How to load WF workflows dynamically

This is post is about loading and running Workflow foundation (WF) XAML files. It is a powerful technique which can be used to change Workflows on the fly, without re-compiling the application. All this functionalities can be achieved via single line of code.

WorkflowInvoker.Invoke(ActivityXamlServices.Load("Activity1.xaml"));

Happy Programming :)

Generate your database entities using T4 templates

Long back I wrote some post about code generation using T4 templates. This post is about generating database entities using T4 templates. This code is pretty straight forward, you are reading the app.config to get the connection string, connecting to db server using Sql Server SMO objects, enumerating tables and columns.

Here is the code, which will read the App.Config file and get the connection string. (I am using a connection string with name, Default).

string appConfig = this.Host.ResolvePath("App.config");
if(!File.Exists(appConfig))
{
	Error("App.config not exists");
}

ExeConfigurationFileMap configFile = new ExeConfigurationFileMap();
configFile.ExeConfigFilename = appConfig;
var configuration = ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
var connectionString = configuration.ConnectionStrings.ConnectionStrings["Default"].ConnectionString;

Here is the code which will connects to the database, enumerate tables and columns and generates classes and properties.

SqlConnection sqlConnection = new SqlConnection(connectionString);
ServerConnection serverConnection = new ServerConnection(sqlConnection);
Server server = new Server(serverConnection);
var tables = server.Databases[server.ConnectionContext.DatabaseName].Tables;
#>
namespace <#= server.ConnectionContext.DatabaseName #>.Entities
{
<#
foreach(Table table in tables)
{
#>
public sealed partial class <#= CleanName(table.Name) #>
{
<#
foreach(Column column in table.Columns)
{
#>
	public <#= ToClrType(column.DataType, column.Nullable) #> <#= CleanName(column.Name) #> { get; set; }
<#
}
#>
}
<#
}
#>
}

And here is the two functions which will fix any issue with table name and column names. And returns C# type by using a SQL Server type.

private string FixTableName(string tableName)
{
	var result = tableName.Replace(" ","_");
	return System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(result);
}

private string ToClrType(DataType dataType, bool isNullable)
{
	string returnType = string.Empty;
	switch (dataType.SqlDataType)
    {
        case SqlDataType.BigInt:
            returnType = string.Format("{0}{1}","long", isNullable ? "?":"");
			break;
        case SqlDataType.Binary:
        case SqlDataType.Image:
        case SqlDataType.Timestamp:
        case SqlDataType.VarBinary:
            returnType = "byte[]";
			break;
        case SqlDataType.Bit:
			returnType = string.Format("{0}{1}","bool", isNullable ? "?":"");
			break;
        case SqlDataType.Char:
        case SqlDataType.NChar:
        case SqlDataType.NText:
        case SqlDataType.NVarChar:
        case SqlDataType.Text:
        case SqlDataType.VarChar:
        case SqlDataType.Xml:
            returnType = string.Format("{0}{1}","string", "");
			break;
        case SqlDataType.DateTime:
        case SqlDataType.SmallDateTime:
        case SqlDataType.Date:
        case SqlDataType.Time:
        case SqlDataType.DateTime2:
			returnType = string.Format("{0}{1}","System.DateTime", isNullable ? "?":"");
			break;
        case SqlDataType.Decimal:
        case SqlDataType.Money:
        case SqlDataType.SmallMoney:
			returnType = string.Format("{0}{1}","decimal", isNullable ? "?":"");
			break;
        case SqlDataType.Float:
			returnType = string.Format("{0}{1}","double", isNullable ? "?":"");
			break;
        case SqlDataType.Int:
			returnType = string.Format("{0}{1}","int", isNullable ? "?":"");
			break;
        case SqlDataType.Real:
			returnType = string.Format("{0}{1}","float", isNullable ? "?":"");
			break;
        case SqlDataType.UniqueIdentifier:
			returnType = string.Format("{0}{1}","Guid", isNullable ? "?":"");
			break;
        case SqlDataType.SmallInt:
            returnType = string.Format("{0}{1}","short", isNullable ? "?":"");
			break;
        case SqlDataType.TinyInt:
            returnType = string.Format("{0}{1}","byte", isNullable ? "?":"");
			break;
        case SqlDataType.Variant:
            returnType = string.Format("{0}{1}","object", "");
			break;
        case SqlDataType.DateTimeOffset:
            returnType = string.Format("{0}{1}","DateTimeOffset", isNullable ? "?":"");
			break;
		}

		return returnType;
}

Happy Coding :)

You can find the Gist here

How to access SkyDrive from Windows Forms – Part 2

This post is about uploading files from your computer to Sky Drive using Live REST API. For uploading files, sky drive API supports two HTTP methods, PUT and POST. For simplicity in this post PUT method is used. If you want to use POST, please check How to upload file using HttpWebRequest class post. Only difference is the URL should be in same format.

string url = string.Format(@"https://apis.live.net/v5.0/me/skydrive/files/{0}?access_token={1}", 
    Path.GetFileName(fileName), access_token);
using (var client = new WebClient())
{
    client.UploadDataAsync(new Uri(url), "PUT", FileToByteArray(fileName));
}

FileToByteArray() function converts a file to byte array. And it is done. You can find the full source code here.

Happy Programming :)

How to access SkyDrive from Windows Forms – Part 1

Introduction and how it works

SkyDrive is a file hosting service that allows users to upload and sync files to a cloud storage and then access them from a Web browser or their local device. It is part of the Windows Live range of online services and allows users to keep the files private, share them with contacts, or make the files public. Publicly shared files do not require a Microsoft account to access. The service offers 7 GB of free storage for new users. The Live Connect REST API enables apps that work with Live Connect to programmatically access their data stored on Microsoft SkyDrive.

To use Live Connect, you need to create your application. You can create your application from Live Connect Developer Center. After signing in with your live ID, click on the My Apps link. And click on the create application link, which will redirect to Connect your application to Windows Live page, where you can provide Application Name and Language.

Create Live Connect Application

Click on the I accept button will create the application and redirect to the application page.

Manage Live Connect application

As you are using this in Windows Form based application, Select the Mobile Client app: setting as Yes, and leave the Redirect domain textbox as blank. And save it.

Live Connect implements the OAuth 2.0 protocol to authenticate users. Live Connect supports the three authorization flows, Implicit grant flow, Authorization code grant flow and Sign-in control flow. You can find more details about this in OAuth 2.0 (Live Connect). In this post I am using first one, Implicit grant flow. This can be used by both web-based and desktop apps. In this flow, the client makes an authorization request to https://login.live.com/oauth20_authorize.srf with request_type=token.

Implementation

As we are using Implicit grant flow, the implementation is pretty straight forward. Create the Authentication URL, redirect user to the page using Web Browser control, in this page users required to provide live credentials and should allow the application to access the user resources (in this case sky drive, while creating the authentication url, you need to provide the scope). Once the user logged in successfully and allowed your application to access the sky drive or resources, the user will be redirected to the redirect_uri parameter of the request url, as you are developing a Windows Form based application, you can provide https://login.live.com/oauth20_desktop.srf as the redirect_uri parameter.

private const string scope = "wl.skydrive_update"; //SCOPE OF THE APPLICATION
private const string client_id = "[REPLACE WITH YOUR CLIENTID]";
private const string signInUrl = 
    @"https://login.live.com/oauth20_authorize.srf?client_id={0}&redirect_uri=

https://login.live.com/oauth20_desktop.srf&response_type=token&scope={1}";

//In the Form constructor, navigate user to the authentication page
wbSkyDriveAuth.Navigate(string.Format(signInUrl, client_id, scope));

Above code will display a sign in dialog to the users.

Sign in to Live Services

Once user successfully signed in, users will be redirected to the application permissions page, in this page, the application name, icon and which all permissions it requires will be displayed.

Application Permissions

Once user approves the application to access the resources, user will be redirect to the redirect_uri parameter, with access_token query string. You can look for the access_token parameter in the query string and extract the value from this on the DocumentCompleted event of the Web Browser control. In case of Windows Phone or WPF, the event is LoadCompleted, rest of the code works without any issue.

private void wbSkyDriveAuth_DocumentCompleted
    (object sender, WebBrowserDocumentCompletedEventArgs e)
{
    if (e.Url.AbsoluteUri.Contains("#access_token="))
    {
        var x = e.Url.AbsoluteUri.Split(new[] { "#access_token" }, StringSplitOptions.None);
        _authCode = x[1].Split(new[] { '&' })[0];
        DialogResult = DialogResult.OK;
        Close();
    }
}

And using this access token, you can upload / download files from Sky Drive. Here is another code snippet which will helps to display user’s SkyDrive directory.

WebClient client = new WebClient();
var result = client.OpenRead(
    new Uri("https://apis.live.net/v5.0/me/skydrive?access_token=" + access_token));
var sr = new StreamReader(result);
Console.WriteLine(sr.ReadToEnd());

This will write something like this, in the output window. All the responses from Live Services, is in JSON format.

SkyDrive information in JSON format

Next post is about uploading a file to sky drive from Windows Form application. You can find the sample code for this post in here

Happy Programming. :)