Monday 14 May 2012

SPDG v2

Created an improved version of the SPDG

functionality added

  • added returning of SqlDataReader
  • added support for stored procedure output parameters
  • added support for stored procedure "metadata"
  • corrected datamappings to .net
  • backward compatibility with version 1

The "settings" for the app can also be done within the stored procedures via "metadata" to indicate functions to be exposed. To make use of this functionality, add the following code anywhere within the stored procedures; the app will make use of regular expressions to detect the "metadata"

/*[SPDG]Skip,ExecuteDataSet,ExecuteDataReader,ExecuteXML,ExecuteNonQuery,ExecuteScalar*/
 OR
 /*[SPDG]ExecuteNonQuery*/
 OR
 /*[SPDG]Skip*/ - to be exclude in class generation 

Only include the functionality you would like to expose for the particular stored procedure. if no "metadata" is included, the app will leave the options for you to fill in.

I've also included support for accessing output parameters from stored procedures. The output will be stored in the public properties of the stored procedure classes.

accessing of the return value from the stored procedure output can be retrieved using the stored procedure class properties

sp_getbinary sp = new sp_getbinary(new byte[50]);
sp.ExecuteNonQuery();
foreach (byte b in sp.dataout)
{
    lResult.Text += b.ToString();
}
lResult.Text += "\n";
sp_getntext nt = new sp_getntext(new string(' ', 4000));
nt.ExecuteNonQuery();
lResult.Text += nt.dataout;

you can download the full source code from Code Project

Thursday 10 May 2012

SPDG - Stored Procedure Data Gateway

This is a follow-up on my previous post with regard to the stored procedure gateway. i've created a utility that anyone working on c#.net and MSSQL can use to simplify the creation of the data layer.

head to code project for the full article

The stored procedure data gateway is a utility that generates classes for each stored procedure within an MSSQL database. Each stored procedure
can be configured to expose only supported functionality (ie. ExecuteDataSet, ExecuteXML, ExecuteNonQuery or ExecuteScalar).

The utility also generates a .csproj that encapsulates the data layer in a single assembly, which can then be included into your existing project
for data access.

I wanted something that could be easily implemented with as little coding on the individual stored procedure classes as possible, with
the base class containing most if not all of the data access logic. since the bulk of the work will be on the individual classes and coding
the logic for each stored procedure. here's a sample of the class that has been generated.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SPDataGateway
{
    public class sp_getfavourites: spbase<sp_getfavourites.eFields>, IExecuteDataSet, IExecuteXML
    {
        public enum eFields { userid }
        public sp_getfavourites ( Int64 userid )
        {
            this.userid = userid;

        }
        public Int64 userid { get; set; }
        public System.Data.DataSet ExecuteDataSet()
        {
            return base.ExecuteDataSet(eFields.userid);
        }
        public string ExecuteXML()
        {
            return base.ExecuteXML(eFields.userid);
        }
        protected override string StoredProcedureName
        {
            get { return "sp_getfavourites"; }
        }
    }
}

Each individual class only encapsulates the function exposed, the stored procedure name and the parameters required; the bulk
of the logic is contained in the base class.

The utility is a single form application that contains these controls:

  1. Toolbar
    • New - Clears the form
    • Open - opens an XML file that contains your project settings.
    • Save - saves your settings for the project in XML format (saved in .spg)
    • Synchronize - synchornizes the current list with any new stored procedures from the database.
    • Write Classes - performs an IO writing of the stored procedure classes and supporting classes.
  2. Form
    • Connection String - connection string to connect to your database
    • Namespace - namespace and assembly name for the cs project being created.
  3. Left Pane - Contains the full list of stored procedures and the options for each procedure.
  4. Right Pane - contains 3 tabs that holds the following info
    • Stored Procedure Parameters - List of parameters of the current selected procedure.
    • Stored Procedure - the stored procedure content retrieve from the database.
    • C# SP Class - the sample of the class begin generated.

To start off a new project, click on new and key in the connection string and desired namespace for the project; when you are done
click on synchronize and the app will retrieve all stored procedures into the list on the left pane.

You can then proceed to configure each stored procedure, to tell the application if the stored procedure returns a dataset, xml or
scalar value or if there are no return values.

Scrolling through the list will update the right pane with details of the selected stored procedure.

When done, remember to save your work; the application will prompt to create a .spg file which contains an XML document with all
settings. Correspondingly, to retrieve your previous work, click on open and select the saved .spg file.

The utility will create these directories and files:

  • \ - project root directory will hold only the .csproj file
  • \helpers\ - contains the SQLHelper.cs class from here
  • \interfaces\ - contains all the interfaces for the project
  • \sps\ - contains the stored procedure classes and base classes

Sunday 22 April 2012

Integrating Facebook register social plugin on websites

Here's a basic step by step guide on implementing the Facebook registration social plugin to your website. Following the steps below will quickly get your site registering users from Facebook.

to find out more on the registration plugin please read the Facebook registration plugin documentation

Step 1


the first step that you would need to take is to register your app on Facebook.
  1. navigate to Facebook developer
  2. create a new app
copy your [app id] and [app secret] as both would be required later

Step 2


you will need a couple of scripts to get things up and running.

firstly, we would need to load the javascript SDK as we would be using FBML tags. you can choose to create a .js to store this script and reference in or simply paste it in the block in your pages. remember to insert your [app id] you copied in step 1 and replace the links with your own domain.

window.fbAsyncInit = function () {
    FB.init({
        appId: '[your app id]', // App ID
        channelUrl: 'http://www.blahblahblah.com/channel.html', // Channel File
        status: true, // check login status
        cookie: true, // enable cookies to allow the server to access the session
        oauth: true, // enable OAuth 2.0
        xfbml: true  // parse XFBML
    });

    // Additional initialization code here
    FB.getLoginStatus(function (response) {
        if (response.status == 'connected') {
            if (fblogin == false) {
                var uid = response.authResponse.userID;
                var accessToken = response.authResponse.accessToken;
                window.location.href = 'http://www.blahblahblah.com/login.ashx?at=' + accessToken;
            }
        } else {
            // do something
        }
    });
};

// Load the SDK Asynchronously
(function (d) {
    var js, id = 'facebook-jssdk'; if (d.getElementById(id)) { return; }
    js = d.createElement('script'); js.id = id; js.async = true;
    js.src = "//connect.facebook.net/en_US/all.js";
    d.getElementsByTagName('head')[0].appendChild(js);
} (document));


we use the FB.getLoginStatus function to retrieve the login status on each page, this can be used to hide the login box/section and to show user info.
it perform a check and login when a user login or reopens the browser. The fblogin variable is created in page_load on the masterpage, which checks if we have the Session variables needed.

    protected void Page_Load(object sender, EventArgs e)
    {
        string script = "";
        if (Session["fbid"] != null)
        {
            script = "var fblogin = true;";
        }
        else
        {
            script = "var fblogin = false;";
        }
        
        ScriptManager.RegisterClientScriptBlock(this, typeof(Page), "fblogincheck", script,true );
    }


Step 3


Next, we would need to create a registration page (register.aspx), this would hold the registration plugin below.
  • fields : holds the list of fields required by your application (pls read the Facebook registration plugin documentation if you need custom fields)
  • redirect-uri : holds the uri that Facebook will redirect to once the user has authorized your app. the signed_request will be posted to the url.



Step 4


We would also need to create a page/handler to process the information passed from the authorization dialog/registration page.

to simplify implementation, i've used the Facebook C# SDK, you should have Facebook.dll and Newtonsoft.Json.dll in the bin folder once you've referenced this.

I've used a generic handler (.ashx) to handle the login/registration. this handler handles both the post from the Facebook authorization dialog and also the login redirection; thus i've retrieved the access token using an if-else check to see what has been passed to the handler.

the extra interface implemented is required if you want to persist any data to the session state.

public class login : IHttpHandler, IRequiresSessionState {
    
    public void ProcessRequest (HttpContext cx) {
        cx.Response.ContentType = "text/html";
        string at = "";
        FacebookClient fb = new FacebookClient();

        if (cx.Request["signed_request"] != null)
        {
            dynamic signedRequest = fb.ParseSignedRequest("[app secret]", cx.Request["signed_request"].ToString());
            at = signedRequest.oauth_token;
        }
        else if (cx.Request["at"] != null)
        {
            at = cx.Request.QueryString["at"];
            cx.Session["AccessToken"] = at;
        }

        if (at != "")
        {
            fb = new FacebookClient(at);
            dynamic result = fb.Get("me", new { fields = "name,id,gender,birthday,email" });

            string name = result.name;
            Int64 id = Convert.ToInt64(result.id);

            cx.Session["fbid"] = id;
            cx.Session["fbname"] = name;

            // perform the user registration/check here
        }
        else
        {
            //do something if no access token is found
        }
        cx.Response.Redirect("/index.aspx");
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}

this is a very very simplified implementation of the registration plugin, it gives only the basic name and id which you can use to register a user to your website. should you need further information from Facebook or custom fields, you can add them to the codes above and request the necessary permissions on the Facebook developer app.

to get the birthday and email fields, you would need to add [email] and [user_birthday] permissions ... go to auth dialog on the app settings and add them under authenticated referrals -> user & friend permissions.

Friday 13 April 2012

Stored Procedure Gateway


here's my attempt at a stored procedure gateway to facilitate/simplify multi developer scenarios and standardizing the coding as much as possible.

The gateway is developed in C# and uses generics, reflection, interfaces and an abstract base class. following is the list of requirements that i wanted to fulfil
  • place most if not all of the core logic into the base class
  • allow fast and straightforward implementation for each and every subsequent stored procedure
  • expose only supported methods on each stored procedure class
I'll start off with the base class which holds most of the logic.

spbase (base class)

the base class is defined abstract with a <tfields> generic type parameter, it also implements the IDisposable interface so we can clean up after use.
public abstract class spbase<tfields> : IDisposable
3 properties are defined. StoredProcedureName is defined protected to give access only to the child class.
private SqlParameter[] sqlparams { get; set; }
private SqlConnection SQLConnection { get; set; }
protected abstract string StoredProcedureName { get; }
The constructor does a check on the generic type parameter to ensure the developer has defined the child class generic type parameter as an enum; and initializes the SQLConnection.
public spbase()
{
    if (!typeof(tfields).IsEnum)
    {
        throw new ApplicationException("Invalid class definition!");
    }
    try
    {
        this.SQLConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["conString"].ToString());
    }
    catch (Exception e)
    {
        this.Dispose();
        throw e;
    }
}
The following code describes the methods of the base class
The setParameters method takes in the parameters required by the stored procedure; the keyword params is used so as to allow for a variable number of parameters to be passed to the method, as each stored procedure will have a variable number of parameter. The method uses reflection to access the properties defined in the child class. NOTE: (params tfields[] fields) will be explained further in the article.
private SqlParameter[] setParameters(params tfields[] fields)
{
    if (fields.Length <= 0) return null;

    SqlParameter[] sqlparams = new SqlParameter[fields.Length];
    for (int i = 0; i < fields.Length; i++)
    {
        PropertyInfo pi = this.GetType().GetProperty(fields[i].ToString());
        sqlparams[i] = new SqlParameter(fields[i].ToString(), pi.GetGetMethod().Invoke(this, null));
    }
    return sqlparams;
}
checkFields gives the option of overriding and defining the logic for checking the fields.
public virtual bool checkFields(params tfields[] fieldstocheck) { return true; }
The following 4 Execute methods uses the MS SqlHelper class, parameters are set using the setParamters function by passing in fields. Each are marked protected so as to expose methods to only the child class.
protected virtual string ExecuteXML(params tfields[] fields)
{
    return ExecuteDataSet(fields).GetXml();
}
protected virtual DataSet ExecuteDataSet(params tfields[] fields)
{
    sqlparams = this.setParameters(fields);
    return SqlHelper.ExecuteDataset(this.SQLConnection, CommandType.StoredProcedure, this.StoredProcedureName, sqlparams);
}
protected virtual void ExecuteNonQuery(params tfields[] fields)
{
    sqlparams = this.setParameters(fields);
    SqlHelper.ExecuteNonQuery(this.SQLConnection, CommandType.StoredProcedure, this.StoredProcedureName, sqlparams);
}
protected virtual object ExecuteScalar(params tfields[] fields) 
{
    sqlparams = this.setParameters(fields);
    return SqlHelper.ExecuteScalar(this.SQLConnection, CommandType.StoredProcedure, this.StoredProcedureName, sqlparams);
}
Implementation of the IDisposable interface
public void Dispose()
{
    this.SQLConnection.Close();
    this.SQLConnection = null;
    this.SQLConnection.Dispose();
}
Interfaces

4 interfaces corresponding to the 4 Execute methods are required. the interfaces simply define the methods to be made available for each stored procedure class.
interface IExecuteDataSet
{
    System.Data.DataSet ExecuteDataSet();
}
interface IExecuteNonQuery
{
    void ExecuteNonQuery();
}
interface IExecuteXML
{
    string ExecuteXML();
}
interface IExecuteScalar
{
    object ExecuteScalar();
}
Stored Procedure Class

Now to put everything together ... Start off by defining the stored procedure class, i always prefix mine with "sp_" so the class will follow suit.
public class sp_addnewuser: spbase<>
The class inherits from spbase which requires a generic type parameter, we will need to define that like so:
public class sp_addnewuser: spbase<sp_addnewuser.eFields>
{
    public enum eFields { userid = 0, username, useremail }

    public int userid { get; set; }
    public string username { get; set; }
    public string useremail { get; set; }

    protected override string StoredProcedureName
    {
        get { return "sp_addnewuser"; }
    }
}
We pass in the sp_addnewuser.eFields which is the enum defined in the child class so that our base class knows the enum and can use the values to perform it's tasks. This is the same enum that we will use as parameters in (params tfields[] fields). the eFields enum will contain all the stored procedure parameters (named exactly as in the stored procedure); for procedures with no parameters, simply define an empty eFields.
public enum eFields {}
On top of the enums, we would require corresponding properties (NOTE: must be exactly as the values in the enum). We would also be required to implement the abstract method StoredProcedureName, which we have done so as above. Next we would need to implement the interfaces to expose the execute methods for this stored procedure.
public class sp_addnewuser: spbase<sp_addnewuser.eFields>, IExecuteNonQuery
{
    public enum eFields { userid = 0, username, useremail }

    public int userid { get; set; }
    public string username { get; set; }
    public string useremail { get; set; }

    public void ExecuteNonQuery
    {
        base.ExecuteNonQuery(eFields.userid, eFields.username, eFields.useremail);
    }
    'this is the actual stored procedure name
    protected override string StoredProcedureName
    {
        get { return "sp_addnewuser"; }
    }
}
The base class base.ExecuteNonQuery takes in the parameters eFields.userid, eFields.username, eFields.useremail. this allows the base class to form the SqlParameters required for the execution of the stored procedure. All subsequent stored procedure classes will be defined in a similar way. here's another example of the implementation
class sp_getcountry: spbase<sp_getcountry.eFields>, IExecuteDataSet, IExecuteXML
{
        
    public enum eFields
    {
        countrycode = 0
    }

    public string countrycode { get; set; }

    public string ExecuteXML()
    {
        return base.ExecuteDataSet(eFields.countrycode).GetXml();
    }

    public System.Data.DataSet ExecuteDataSet()
    {
        return base.ExecuteDataSet(eFields.countrycode);
    }

    protected override string StoredProcedureName
    {
        get { return "sp_getcountry"; }
    }
}
The sp_getcountry class implements the IExecuteDataSet and IExecuteXML interfaces, which will expose the Execute methods supported by this stored procedure.

You may want to add a constructor to initialize all the properties (NOTE: remember to call base() on the constructor).