Tuesday, 28 June 2011

Visual Studio/SQL Server - Script schema and data in Visual Studio 2008 and onwards


http://blogs.msdn.com/b/webdevtools/archive/2007/10/15/sql-database-publishing-wizard-is-now-in-visual-studio-orcas.aspx

Friday, 24 June 2011

C#/XSLT - Adding custom xml namespaces / extension objects


Today I had a bit of a ball ache trying to capture errors that were failing within my XSLT. Whenever I called the document() function with an invalid file path, the document will fail to transform and nothing will be displayed.

Initially I looked at trying to capture the error using when/otherwise by passing the result of the document() function into a test attribute. This simply does not work, even if you convert the result to a boolean. So after wading through crappy advice, I thought as I'm using C# to do my transformations, I will simply add a custom namespace.

The following example explains how to check if a file exists using a custom namespace in C#.


1. Add a custom xmlns reference to your XSL file. The format is as follows: xmlns:<tag name>="<namespace>"

Example:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:file="urn:schemas-file">


This will allow me to prefix functions within my urn:schemas-file namespace with the prefix: file



2. Now the XSL has access to this custom library of functions (which we haven't yet coded yet)... we need to actually call one of our functions within the XSL.

Example:
<!-- Sample variable holding a location to a file -->
<xsl:variable name="filePath" select="../root/xml/testdocument.xml" />
 
<!-- Check to see if the file exists -->
<xsl:choose>
<xsl:when test="file:fileExists($filePath)">
    File exists... process the file here and output some stuff!
</xsl:when>
<xsl:otherwise>
    File does not exist. perform fallback operation!
</xsl:otherwise>
</xsl:choose>




3. Now the XSL knows out our functions and were consuming one of them, we just need to write the namespace itself and apply to to the transformation! Create a class in C# and add some functionality that you wish to make available to your XSL file.

Example:
// <copyright file="XSLFileHelper.cs" company="Ginko Solutions">
// Copyright (c) 2011 All Right Reserved
// </copyright>
// <author>Sean Greasley</author>
// <email>sean.greasley@fusedigital.com</email>
// <summary>Provides file functionality to support XSL processing</summary>
namespace RegulationExplorerWebHTML.Helpers
{
    using System;
    using System.IO;
    using System.Web;
 
    /// <summary>
    /// Provides file functionality to support XSL processing
    /// </summary>
    public class XSLFileHelper
    {
        public bool fileExists(string file)
        {
            // Get path
            string path = HttpContext.Current.Server.MapPath(file);
 
            // Exists<?>
            return File.Exists(path);
        }
    }
}




4. The final step is to apply this class to the transformation process! To do this, will use the AddExtensionObject method of the XsltArgumentList class.

Note: Please see my previous post about how to do an XML/XSL transformation in C# with parameters and settings.

Example:
XsltArgumentList xslArgs = new XsltArgumentList();
xslArgs.AddExtensionObject("urn:schemas-file", new XSLFileHelper());




5. and thats it!

Thursday, 23 June 2011

Serializing LINQ-to-SQL classes example with deep cloning


Serializing Linq-To-Sql classes isn't as straight forward as you might imagine. You may have got as far as attempting to serialize a class and found an error stating Linq.EntityRef cannot be serialized. This post explains to to serialize Linq-To-Sql entities using a cloning example.


For this example, I will be taking a deep clone of a Linq-To-Sql object and all of its associated properties. To do this, I will use serialization and utilise the ICloneable interface.

This example assumes you already have a Linq-To-Sql classes file (.dbml) with some tables/class information within the designer...

1. Open the Linq-To-Sql designer (.dbml) and view the main properties. Change the 'Serialzation Mode' to Unidirectional. This decorates our Linq-To-Sql entities with serialization capabilities.

2. Create a partial class for the Linq-To-Sql class you wish to clone. This allows you to extend the functionality of a Linq-To-Sql class as all classes are partial.

3. Add the [Serializable] attribute to the header of the class. This marks the class as serializable.

4. Implement the ICloneable inteferface. We can now override the Clone() method. When this method is called, we need to apply the serialization process to the object we wish to clone.

5. When serializing a Linq-To-Sql class, we cannot use the BinaryFormatter. Linq-To-Sql classes simply do not support this. Instead, we can utilise the NetDataContractSerializer. This will suit out requirements for the serialization of Linq-To-Sql entities.

6. and your done!



Serialzation code snippet
/// <summary>
/// Linq-To-Sql partial class, extends the 'Event' entity/class.
/// Note: Also changed Serialzation mode in designer to Unidirectional
/// </summary>
[Serializable]
public partial class Event : ICloneable
{
    /// <summary>
    /// Overrides the Clone method within the IClonable interface
    /// to performing object cloning
    /// </summary>
    /// <returns>A clone of the incoming object</returns>
    public object Clone()
    {
        return CloningFunctions.CloneObject(this);
    }
}
 
 
/// <summary>
/// Provides functions aiding object cloning
/// </summary>
public class CloningFunctions
{
    /// <summary>
    /// Clones an  object using the NetDataContractSerializer
    /// </summary>
    /// <param name="obj">Incoming object to clone</param>
    /// <returns>A clone of the incoming object</returns>
    public static object CloneObject(object obj)
    {
        using (MemoryStream memStream = new MemoryStream())
        {
            NetDataContractSerializer formatter = new NetDataContractSerializer(new StreamingContext(StreamingContextStates.Clone));
            formatter.Serialize(memStream, obj);
            memStream.Seek(0, SeekOrigin.Begin);
            return formatter.Deserialize(memStream);
        }
    }
}

Wednesday, 22 June 2011

Access computer behind router over the internet


Here's a few notes which I find useful for accessing my system over the internet from an external location.

Is the remote system behind a router?
If so, use the router's IP address. Either go to whatismyip.com, or get the router's IP Address from the router control panel (typically 192.168.1.1). This will be the IP address you will use to access the system.

Enabling remote access
Enable remote access to the system. For windows, its usually at "Right Click My Computer > Properties > Remote/Remote Settings". Here you can also configure who is allowed to access the system.

Systems behind a router
Setup port forwarding to the system in question. Find your local IP address (usually 192.168.x.x) and forward the necessary ports to this system. I.e. for HTTP, use port 80. So when you visit the router's IP address over HTTP (http://externalRouterIP), it will forward the request to your machine. Another useful one is 3389 for remote desktop.
Optional: It may be useful to set a static IP for your system. This ensures that your internal IP address stays the same. If your router software does not support this, you can figure your own in Network Settings under the Control Panel in Windows.

Tuesday, 21 June 2011

SVN: Setting up SubVersion server on Windows


Here is a great article on how to setup SVN server on a windows machine.

http://www.codinghorror.com/blog/2008/04/setting-up-subversion-on-windows.html

Monday, 20 June 2011

SEO - Search Engine Optimization


Here's a good post on hoe to use an SEO tool to crawl your website for SEO improvements.
The tool installs itself into most web servers and is free to download!

Description
The IIS Search Engine Optimization (SEO) Toolkit helps Web developers, hosting providers, and Web server administrators to improve their Web site’s relevance in search results by recommending how to make the site content more search engine-friendly. The IIS SEO Toolkit includes the Site Analysis module, the Robots Exclusion module, and the Sitemaps and Site Indexes module, which let you perform detailed analysis and offer recommendations and editing tools for managing your Robots and Sitemaps files.

Article and Download
http://weblogs.asp.net/scottgu/archive/2009/06/03/iis-search-engine-optimization-toolkit.aspx

Wednesday, 15 June 2011

C# - Simple TripleDES Encryption with or without hashing


This class below enables simple encryption and decryption of text strings. It uses the TripleDES algorithms and you can chose weather to use MD5 hash against the key.
Simply change the value of the encryptionKey to whatever you want the key to be.


C# Source code
// <copyright file="EncryptionHelper.cs" company="GinkoSolutions.com">
// Copyright (c) 2011 All Right Reserved
// </copyright>
// <author>Sean Greasley</author>
// <email>sean@ginkosolutions.com</email>
// <summary>Enables simple TripleDES encryption with or without hashing</summary>
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Security.Cryptography;
 
/// <summary>
/// Enables simple TripleDES encryption with or without hashing
/// </summary>
public class EncryptionHelper
{
    /// <summary>
    /// Encryption key. Used to encrypt and decrypt.
    /// </summary>
    private static readonly string encryptionKey = "YOURSECRETKEY";
 
    public EncryptionHelper() {}
 
    /// <summary>
    /// Encrypt text string
    /// </summary>
    /// <param name="toEncrypt">The string of data to encrypt</param>
    /// <param name="useHashing">Weather hashing is used or not</param>
    /// <returns>An encrypted string</returns>
    public static string Encrypt(string toEncrypt, bool useHashing)
    {
        byte[] keyArray;
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
 
        // If hashing use get hashcode regards to your key
        if (useHashing)
        {
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(encryptionKey));
            hashmd5.Clear();
        }
        else
            keyArray = UTF8Encoding.UTF8.GetBytes(encryptionKey);
 
        // Set the secret key for the tripleDES algorithm
        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        tdes.Key = keyArray;
        tdes.Mode = CipherMode.ECB;
        tdes.Padding = PaddingMode.PKCS7;
 
        // Transform the specified region of bytes array to resultArray
        ICryptoTransform cTransform = tdes.CreateEncryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        tdes.Clear();
 
        // Return the encrypted data into unreadable string format
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }
 
    /// <summary>
    /// Decrypts a text string
    /// </summary>
    /// <param name="cipherString">The encrypted string</param>
    /// <param name="useHashing">Weather hashing is used or not</param>
    /// <returns>Decrypted text string</returns>
    public static string Decrypt(string cipherString, bool useHashing)
    {
        byte[] keyArray;
        byte[] toEncryptArray = Convert.FromBase64String(cipherString.Replace(' ', '+'));
 
        if (useHashing)
        {
            // If hashing was used get the hash code with regards to your key
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(encryptionKey));
            hashmd5.Clear();
        }
        else
        {
            // If hashing was not implemented get the byte code of the key
            keyArray = UTF8Encoding.UTF8.GetBytes(encryptionKey);
        }
 
        // Set the secret key for the tripleDES algorithm
        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        tdes.Key = keyArray;
        tdes.Mode = CipherMode.ECB;
        tdes.Padding = PaddingMode.PKCS7;
 
        ICryptoTransform cTransform = tdes.CreateDecryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        tdes.Clear();
 
        // Return the Clear decrypted TEXT
        return UTF8Encoding.UTF8.GetString(resultArray);
    }
}

Facebook Connect - Post to wall feed


After using Facebook Connect for a while, you can soon find out how shoddy the documentation is. There seem to be about 5000 half-written API's, most out of date and even the Facebook API documentation is barely holding itself together.

Anyway, here's a small JS snippet on how to post to a user's wall. The user must first allow the application pushing rights, or an error will occur.

I have already written a great blog entry on getting started with Facebook Connect, check it out here!


Pre-requisites
- Check out the above link if you have no idea how to get started!
- Allow pushing rights (publish_stream)
- Ensure your already dealing with an authentication session (I have added the code to ensure you already have a valid session in the code below)


Javascript Code
FB.getLoginStatus(function (response) {
    if (response.session) {
 
        var params = {};
        params['message'] = 'This is the main message';
        params['name'] = 'This is the name of the link';
        params['description'] = 'This is the link description';
        params['link'] = 'http://www.URLToNavigateTo.com';
        params['picture'] = 'http://www.FULLpathtoimage.com/image.png'; // 90x90 px
        params['caption'] = 'Small caption appearing under the link';
 
 
        FB.api('/me/feed', 'post', params, function (response) {
            if (!response || response.error) {
                // Error occured posting to the fb wall
            }
        });
 
    } else {
        // User isn't authenticated with facebook
    }
});



This will produce the following result...

Tuesday, 14 June 2011

ASP.NET C# 4.0 - Facebook Connect Example


Facebook connect example

This is a full example written in ASP.NET 4.0 and Javascript. It uses the Facebook Connect client-side library to authenticate and register uses into a database. This minimalist example explains how to easily integrate Facebook Connect into existing or new web applications.

Technologies used:
- ASP.NET/C#
- Javascript/JQuery
- AJAX
- SQL Server Compact
- Entity Framework
- LINQ

Setup Instructions
1. Add the Developer application to your facebook account and create a new facebook application.

Make sure you run the server on port "8080"... Facebook won't argue with this.
(Note: If you use any other port, other than the standard web traffic ports [80/8080],
then Facebook will throw a blank proxy dialog at you, with no kind of helpful error messages!
The URL will contain something like "xd_proxy"...so make sure it's set at 8080!

The settings you can use are as follows...
[Web Site] > [Site URL] > http://localhost:8080/
[Web Site] > [Site Domain] > localhost
[Facebook Integration] > [Canvas URL] > http://localhost:8080/
[Facebook Integration] > [Tab URL] > http://localhost:8080/
[Advanced] > [Sandbox Mode] > Enable [Note: Must only use developer accounts to test with! or you will get errors]


2. Enter application details into Web.config.

3. Enjoy!


Download
Download Source Files Here

Friday, 10 June 2011

CSS: Aligning form fields on a page


In the following example, I have used ASP.NET controls as I have lifted this from a project I have been working on.
If you are not familiar with ASP.NET, when the browser renders these server controls, the controls are rendered down to simple HTML tags:

label (asp:Label)
input (asp:TextBox)
span (asp:RequiredFieldValidator))



HTML/ASP.NET Code
<fieldset class="regForm">
<div class="field">
    <asp:Label ID="lblFirstName" AssociatedControlID="txtFirstName" runat="server" Text="Firstname" />
    <asp:TextBox ID="txtFirstName" runat="server" />
    <asp:RequiredFieldValidator ID="rfvFirstName" runat="server" ControlToValidate="txtFirstName" SetFocusOnError="True" ValidationGroup="vgRegister" ErrorMessage="*" />
</div>
<div class="field">
    <asp:Label ID="lblSurname" AssociatedControlID="txtSurname" runat="server" Text="Surname" />
    <asp:TextBox ID="txtSurname" runat="server" />
    <asp:RequiredFieldValidator ID="rfvSurname" runat="server" ControlToValidate="txtSurname" SetFocusOnError="True" ValidationGroup="vgRegister" ErrorMessage="*" />
</div>
<div class="field">
    <asp:Label ID="lblEmail" AssociatedControlID="txtEmailAddress" runat="server" Text="Email" />
    <asp:TextBox ID="txtEmailAddress" runat="server" />
    <asp:RequiredFieldValidator ID="rfvEmail" runat="server" ControlToValidate="txtEmailAddress" SetFocusOnError="True" ValidationGroup="vgRegister" ErrorMessage="*" />
</div>
</fieldset>



CSS Code
fieldset.regForm div {
    clear: both;
    padding-top:0.2em;
}
fieldset.regForm label {
    display:inline;
    padding-top:0.2em;
    text-align:right;
    margin-right:0.5em;
    float:left;
    width:25%;
}