Archive

Archive for the ‘Best Practices of ASP.Net’ Category

Handling DBNull.Value

October 20, 2014 2 comments

Every asp.net developer use DbNull.Value when writing code to communicate with database. But it could sometimes be quite painful when you want to write with a null-coalescing or ?: operator. The same would be when getting something from database and type checking.

For example in this code snippet I wrote a function which stores a comment in database. As userWebsite is an optional parameter so it could be null and if database expects null then you need to send DBNull.Value. To make it adjustable in ?: operator you just have to cast into an object. like;
Value = userWebsite != null ? userWebsite : (object)DBNull.Value.
I tested this code in fw 4.0 only, so I’m not sure about older versions.

internal int SaveComment(string name, string email, string comment, string? userWebsite)
        {
            SqlCommand _command = new SqlCommand
            {
                Connection = new SqlConnection { ConnectionString = "connection string" },
                CommandType = CommandType.StoredProcedure,
                CommandText = "csp_comment_save",
            };
            _command.Parameters.AddRange(new SqlParameter[] { new SqlParameter { ParameterName = "name", Value = name, SqlDbType = SqlDbType.VarChar, Size = 100 },
            new SqlParameter { ParameterName = "email", Value = email, SqlDbType = SqlDbType.VarChar, Size = 50 },
            new SqlParameter { ParameterName = "comment", Value = comment, SqlDbType = SqlDbType.VarChar, Size = 255 },
            new SqlParameter { ParameterName = "website", Value = userWebsite != null ? userWebsite : (object)DBNull.Value, SqlDbType = SqlDbType.VarChar, Size = 20 }});
            _command.Connection.Open();
            int result=_command.ExecuteNonQuery();
            _command.Connection.Close();
            return result;
        }
Advertisements

WCF RESTful service hosting on IIS6 and consuming by jQuery

July 18, 2014 Leave a comment

Couple of days ago I needed to deploy a WCF RESTfull service on IIS6. Before then I never deployed RESTfull service on IIS6 so it came up with quite configurations for me. While I was deploying this web service on IIS6, I as usual goggled for some configuration related help, although I found, but most of the stuff were scattered. I mean I didn’t find all in a single post or a blog. So I thought why couldn’t do it.

In this post I developed a WCF RESTfull web service from scratch to hosting on web server and consuming by jQuery ajax. Here is the service contract. You’ll find UriTemplate with both with parameters and without parameter.

 /// <PostedOn>deepasp.wordpress.com</PostedOn>
    /// <PostedBy>Muhammad Hussain</PostedBy>
    [ServiceContract(Name = "DeepASPService", Namespace = "deepasp.wordpress.com")]    
    interface IDeepASPService
    {
        /// <summary>
        /// Returns all articles from the blog.
        /// </summary>        
        /// <returns></returns>
        [OperationContract]
        [WebGet(UriTemplate = "/GetArticles?blogName={blogName}", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]        
        List<Article> GetAllArticles(string blogName);

        [OperationContract]
        [WebGet(UriTemplate = "/GetTagArticles?tagName={tagName}", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
        List<Article> GetArticlesByTagName(string tagName);

        [OperationContract]
        [WebGet(UriTemplate = "/GetArticle?Id={Id}", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
        Article GetArticleById(string Id);

        [OperationContract]
        [WebGet(UriTemplate = "/SaveArticle?authenticationToken={authenticationToken}&amp;title={title}&amp;body={body}&amp;submittedBy={submittedBy}", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
        bool SaveArticle(string authenticationToken, string title, string body, string submittedBy);
    }

Here is the Service implementing above contract. Most of the operations are only defined and not fully implemented as it didn’t need for this post. GetArticles operation returns a generic list in json format.

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class DeepASPService : IDeepASPService
    {
        public List<Article> GetAllArticles(string blogName)
        {
            return new List<Article>()
            {
                new Article { Id = Guid.NewGuid(), Name=blogName, Title = "WCF RESTfull web service.", Body = "Html body.", Comments=new List<Comment>()
                {
                    new Comment { Id = Guid.NewGuid(), CommentedOn = DateTime.Now, DisplayName = "deepasp.wordpress.com", Email="no-emailId@deepasp.wordpress.com", Replies = null }
                }},
                new Article { Id = Guid.NewGuid(), Name=blogName,Title = "WCF RESTfull web service deploying on IIS 6.", Body = "Html body.", Comments=new List<Comment>()
                    {
                        new Comment { Id = Guid.NewGuid(), CommentedOn = DateTime.Now, DisplayName = "deepasp.wordpress.com", Email="no-emailId@deepasp.wordpress.com", Replies = new List<Comment> ()
                        {
                            new Comment { Id = Guid.NewGuid(), CommentedOn = DateTime.Now, DisplayName = "deepasp.wordpress.com", Email="no-emailId@deepasp.wordpress.com", Replies =null } 
                        }
                    }
                }},
            };
        }

        public List<Article> GetArticlesByTagName(string tagName)
        {
            throw new NotImplementedException();
        }

        public Article GetArticleById(string Id)
        {
            throw new NotImplementedException();
        }

        public bool SaveArticle(string authenticationToken, string title, string body, string submittedBy)
        {
            if (AuthenticateRequest(authenticationToken))
            {
                //save article 
            }
            return true;
        }

        private bool AuthenticateRequest(string authenticationToken)
        {
            //authentication code
            return true;
        }
    }

In this sample application there are only two data contracts but you can have as many data contracts as you need.
DataContracts:

    [Serializable]
    [DataContract]
    public class Article
    {
        [DataMember]
        public Guid Id { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public string Title { get; set; }

        [DataMember]
        public string Body { get; set; }

        [DataMember]
        public List<Comment> Comments { get; set; }        
    }
    [Serializable]
    [DataContract]
    public class Comment
    {
        [DataMember]
        public Guid Id { get; set; }

        [DataMember]
        public string DisplayName { get; set; }

        [DataMember]
        public string Body { get; set; }

        [DataMember]
        public DateTime CommentedOn { get; set; }

        [DataMember]
        public string Email { get; set; }

        [DataMember]
        public List<Comment> Replies { get; set; }
    }

Configurations:
Service.svc

<%@ ServiceHost Language="C#" Debug="true" Service="Namespace.ServiceName" CodeBehind="ServiceName.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>

web.config:

<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <services>
      <service name="Namespace.ServiceName" behaviorConfiguration="ServiceBehavior">
        <endpoint binding="webHttpBinding" contract="Namespace.ServiceInterface"
                  behaviorConfiguration="webHttp"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior" >
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="True"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webHttp">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

Now we will host this service on IIS. So here is the step by step procedure;

1-Right click on website go to New

2-Click Create virtual directory(in this sample code I created a virutal directory in an existing website)

3- A wizard screen will come up like;

CreatingVD

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4-Click Next

5-In Alias textbox give any name for your service e.g. TestRESTfullService

6-Next and browse the path where your service is e.g. wwwroot\RESTfullWCFService

7-Next

8-Next

9-FINISH

Now although you have successfully deployed your service on IIS but hereafter configurations are required to run it properly.

1-Right click on the new virtual directory you created(e.g. TestRESTfullService)

2-Go to properties

3-By default this virtual directory will be shown as a website(globe logo will appear before it) so you need to convert this into an application.

4-Click on Create application button as showing at #1 in the below picture. After creating application your service icon will change from globe to gear.

createApplication

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

figure 2

5-Change execute permissions from None to Scripts only like the process 2 in the above picture

6- Click on Configuration button and you’ll see this screen;

ConfigurationStep1

 

 

 

 

 

 

 

 

 

7-Click on Insert and you’ll see a small screen like this;

ConfigurationStep4

 

 

 

 

8-Click on Browse and select aspnet_isapi.dll from C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll. If you don’t find v4.0.30319 folder and it means you don’t have dotnet framework 4 full version. So you’ll have to download it from microsoft website and install it. After installation complete you’ll find this so then select it.

9- DO NOT FORGET to uncheck “Verify that file exists” checkbox from the above screen.

10- Now click on Directory Security tab from figure 2.

11- In this Authentication Methods screen you will uncheck “Integrated windows authentication” checkbox.

12- Click OK.

13-Now go to ASP.Net tab from figure 2 and select ASP.Net version : 4.0.30313. (Sometimes a message will appear when version is changed so just press OK).

14- Now restart your IIS. It will lose all sessions of websites hosted on this server so be cautious, its better to do at night time.

14-That’s all you needed.You’ve done it !

Your WCF RESTfull service must be running

Now its time to consume your service. Here we will consume using jQuery ajax like;

function GetAllArticles() {
            var url = "/TestRESTfullService/ServiceName.svc/GetArticles?blogName=deepasp"
            $(function() {
                $.ajax({
                    type: "GET"
                    url: url,
                    async: true,
                    dataType: "json"
                    success: function(articles) {
                        if (articles != null) {
                            document.getElementById("response").innerHTML = ConvertObjecToHtml(articles);
                        }
                        else{
                            document.getElementById("response").innerHTML ="No articles published yet on this blog."
                        }
                    },
                    error: function(e) {
                        alert("Error occured while processing service request" + e.responseText);
                    }
                });
            });
        }

Here download the source code;

Session Variables Management

June 12, 2014 Leave a comment

Session variables are used in our web applications quite often. Some of the variables are maintained for the whole session. So we can use them in different places to perform application’s logic. But while getting some values errors happen just because of a small silly spelling mistake and application blows up. We can somehow overcome most of the common session variables spelling mistake problems by using static classes. Because in this way you don’t need to spell each time you access.

In this post I created a static class in Web/UI layer and created properties for all those common session variables used by our application. So in this way you can set or get your session variables just using this class. It also serves you to organize your session variables in your project.
As it is only a class so I captured it in an image, but if you need source code it can be provided.

 /// <summary>
    /// Managing Session Variables
    /// </summary>
    internal static class BlogSessionVariables
    {
        /// <summary>
        /// Gets sets UserIdentification variable.
        /// </summary>
        public static string UserIdentifier
        {
            get { return (HttpContext.Current.Session["UserIdentification"] != null ? Convert.ToString(HttpContext.Current.Session["UserIdentification"]) : string.Empty); }
            set { HttpContext.Current.Session["UserIdentification"] = value; }
        }

        /// <summary>
        /// Gets sets articles variable.
        /// </summary>
        public static List<dynamic> Articles
        {
            get { return (HttpContext.Current.Session["Articles"] != null ? (List<dynamic>)HttpContext.Current.Session["Articles"] : null); }
            set { HttpContext.Current.Session["Articles"] = value; }
        }
    }

Click the image to enlarge so you can view the whole class and test functions.
session variable management

Instantiate Anonymous Generic List in C#

May 7, 2014 Leave a comment

Sometimes we need anonymous objects in our day to day programming. I used anonymous types in my LINQ queries but I never instantiated an anonymous generic list, I mean I never needed to do it. But now I needed and found an easy way to do it. So if you need it you can enjoy 🙂

         /// <summary>
        /// Returns geo-location of cities.        
        /// </summary>
        /// <returns></returns>
        internal List<dynamic> GetCitiesGeoLocation()
        {
            List<dynamic> cities = new List<dynamic>(){
                new { Name="Lahore", Latitude ="31.5497N", Longitude="74.3436E" },
                new { Name="London", Latitude ="51.5072N", Longitude="0.1275W" },
                new { Name ="Kansas City", Latitude ="39.0997N", Longitude ="94.5783W"}
            };

            return cities;
        }

Could not complete the operation due to error 80020101 in IE11

November 27, 2013 Leave a comment

My asp.net application was working on all browsers before IE11 came in. But when IE11 launched and users started to use it,I got lot of complaints about the UI mess and postbacks . The most irritating thing was neither AJAX UpdatePanel was working nor any postbacks on the page.  So I googled it for almost two days trying different tricks/tips but didn’t work, but then I found this hotfix on microsoft website; http://support.microsoft.com/kb/2836939/en-us.
Most important thing is that after downloading this file you need to install on the server where asp.net website/application is deployed/hosted. Because this error is not an error of your project/application, but its an issue of dotnet framework 4.0 and 2.0.

Cross Browser Compatible AJAX Toolkit Auto-Complete Extender

May 14, 2013 5 comments

Asp.net developers use AJAX Toolkit’s AutoCompleteExtender to get a Google like search behavior. It is a very easy to use control.
You can easily set all its properties using asp.net markup screen.

It works with every browser but sometimes its suggestion list doesn’t properly aligned with the associated control.
It needs little work around for cross browser compatibility.

So, in this post I am going to show you how can make it more cross browser compatible by using its OnClientShown event.

For more detail about the properties of the control , you can get msdn;

Markup look;
Control Markup

Javascript function to make it cross browser compatible;
SuggestionListPositionSet

Service Method to get suggestions;
ServiceMethod

Tested it on IE8, IE8+,Fire-Fox, Google Chrome, Safari and IPad.
You can download the sample solution from here;

DataSet Vs DataReader

July 10, 2012 2 comments

Best Practices developing applications Part-1

There are many reasons why we follow best practices. My own thoughts have changed over the course of my career. Early in my career as a junior developer I strictly followed the patterns and practices of my seniors and leads, and I assumed that their advice would be better than my own.

But with the passage of time my perceptions started to change because of research . As we have to research when our application consumes lot of time in executing and also when its scalability becomes a question. Before doing so I always used DataSet to get the data from the database. Whether it is for large application or too small, but then I found something was doing wrong.

DataSet is a collection of in memory tables and datareader provides the ability to expose the data from database.

Both are very widely used in asp.net applications to get/fetch the data from the database . But for a scalable ,fast and reliable application one has to know the best practices in developing application.

DataSet

We should use when the application is;

  • Windows application
  • Not too large data
  • Returning multiple tables
  • If, to be serialized
  • Disconnected architecture
  • To return from a WCF  service
  • To send across layers
  • Caching the data
  • Do not need to open or close connection

Code snippet using dataset;

public DataSet GetRecord(Guid id, string procedureName)
{
DataSet resultSet = new DataSet();
SqlConnection connection = new SqlConnection(System.Configuration.
ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
SqlCommand command = new SqlCommand(procedureName, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters["pID"].Value = id.ToString();
IDataAdapter adapter = new SqlDataAdapter(command);
try
{
adapter.Fill(resultSet);
}
catch (Exception ex)
{
throw new PerformanceException(ex.Message, ex.InnerException);
}
return resultSet;
}

DataReader
DataReader is a stream which is readonly and forward only. It fetches the record
from databse and stores in the network buffer and gives whenever requests.
DataReader releasese the records as query executes and do not wait for
the entire query to execute. Therefore it is very fast as compare to the
dataset. It releases only when read method is called.

Its usages;

  • Web application
  • Large data
  • Returning multiple tables
  • For Fast data access
  • Needs explicitly closed
  • Output parameter value will only available after close
  • returns only a row after read

code sample for DataReader

 public SqlDataReader GetRecord(Guid id, string procedureName)
        {

            SqlDataReader resultReader = null;
            SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
            SqlCommand command = new SqlCommand(procedureName, connection);
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters["pID"].Value = id.ToString();
            try
            {
                connection.Open();
                resultReader = command.ExecuteReader(CommandBehavior.CloseConnection);
            }
            catch (Exception ex)
            {
                if (resultReader != null || connection.State == ConnectionState.Open)
                {
                    resultReader.Close();
                    connection.Close();
                }
                throw new PerformanceException(ex.Message, ex.InnerException);
            }

            return resultReader;
        }