Practical implementation: Bulk Edit GridView

Being an ASP.NET developer I think this is one of the most common of the requirements that we encounter in our day-to-day projects i.e., bulk editable grid. The gridview provided my Microsoft out-of-the-box will only allow editing one row at a time which in some cases is enough but there could be some scenarios where the complete grid needs to be editable. We have an implementation in ASP.NET Real world controls – BulkEditGridView but it seemed to me as way more complicated for regular usage in projects. Its licensed under Microsoft Public License which in Scott Hanselman’s words is “…is a VERY relaxed license that basically says ‘have fun, and don’t call if there’s trouble.’“ so we can use it but in case of any specific issues it requires us to go through the complicated code to figure out things. For sure its excellent and works perfectly well in most of the cases but I was thinking of having a much simpler implementation which is sufficient in most of the cases. One challenge here was detecting only the rows that were changed because its unnecessary as well as waste of time for processing unchanged rows.

Now for the implementation, its going to be direct usage of GridView with ItemTemplate and primary key fields as labels with css-style as hidden. Also, we would be having another hidden field which will detect the row that was edited. It’s important that we have our primary keys as labels (although hidden) because asp.net renders labels as <span> and hence that data won’t be present in the POST message back to server. This will save us from edits with tools like Fiddler.I have used the Northwind database Categories table for the sake of this blog post.

Beginning with aspx file we would be having a grid view with itemtemplate as follows for the Categories table

 

<asp:GridView ID="grdEditableGrid" runat="server" AutoGenerateColumns="false" OnRowDataBound="grdEditableGrid_RowDataBound">
            <Columns>
                <asp:TemplateField HeaderText="CategoryID" ItemStyle-CssClass="hiddencol" HeaderStyle-CssClass="hiddencol" >
                    <ItemTemplate>
                        <asp:Label runat="server" ID="lblCategoryID" Text='<%# DataBinder.Eval(Container.DataItem, "CategoryID") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="CategoryName">
                    <ItemTemplate>
                        <asp:TextBox runat="server" ID="txtCategoryName" Text='<%# DataBinder.Eval(Container.DataItem, "CategoryName") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Description">
                    <ItemTemplate>
                        <asp:TextBox runat="server" ID="txtDescription" Text='<%# DataBinder.Eval(Container.DataItem, "Description") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Edit Status" ItemStyle-CssClass=hiddencol HeaderStyle-CssClass=hiddencol>
                    <ItemTemplate>
                        <asp:HiddenField runat="server" ID="hdnEditStatus" Value='' EnableViewState="true" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
</asp:GridView>

We will also have the following CSS class

 <style type="text/css">
    .hiddencol
    {
        display: none;
    }
</style>

We also have the following javascript function which, as we will see, will play a key role in identifying the edited rows.

<script type="text/javascript">
        function updateEditStatus(clientID) {
            var hiddenEditControl = document.getElementById(clientID);
            if (hiddenEditControl != null) {
                hiddenEditControl.value = "true";
            }
        }
</script>

Now going to the code behind we will have the same boiler-plate code to load data into the gridview but as seen in the aspx file we made the primary key column as label and set to css class which makes it hidden. Also, we have added another column Edit Status with as hidden field control named hdnEditStatus which will hold the edit status of each row. The code. Apart from the regular code that we write to populate the gridview control, for the purpose of editable gridview we need to do some more work in RowDataBound event. In this event we are going to add attributes for onkeyup client-side event for the textbox controls. We may add attributes related to other controls like dropdown list for client-side which will be used for detecting any change in the control’s data. These events will be calling the javascript function updateEditStatus so that the particular row on which action has been taken will have the hidden field marked as true so that on the server side we can consider them and process only those rows. This method can be used on any editable control that will be put on the gridview as long as it has client-side event to capture that the data in that control has changed.

protected void grdEditableGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
      TextBox categoryName = e.Row.FindControl("txtCategoryName") as TextBox;
      if (categoryName != null)
      {
          categoryName.Attributes.Add("onkeyup", "updateEditStatus(\"" + e.Row.FindControl("hdnEditStatus").ClientID + "\");");
      }           
      TextBox description = e.Row.FindControl("txtDescription") as TextBox;
      if (description != null)
      {
          description.Attributes.Add("onkeyup", "updateEditStatus(\"" + e.Row.FindControl("hdnEditStatus").ClientID + "\");");
      }
}

Now upon button click we can easily capture the rows that were changed and a generic method getDirtyRows has been written so that it can be called easily multiple times to get the changed rows ids or may be the complete set of details. In the below implementation it returns all the CategoryIDs that were changed. This can be customized as per our requirement.

private DataTable getDirtyRows()
{
    DataTable dtDirtyRows = new DataTable();            

    dtDirtyRows.Columns.Add("CategoryID");

    foreach (GridViewRow item in grdEditableGrid.Rows)
    {
        HiddenField editStatus = item.FindControl("hdnEditStatus") as HiddenField;
        if (editStatus != null)
        {
            if (editStatus.Value == "true")
            {
                var lblCategoryID = item.FindControl("lblCategoryID") as Label;
                if (lblCategoryID != null)
                {
                    DataRow dr = dtDirtyRows.Rows.Add();
                    dr["CategoryID"] = lblCategoryID.Text;
                }
            }
        }
    }

    return dtDirtyRows;
}

The complete source code for this is located at github

That’s all folks!!

Hope you people will find this useful.

Thanks,
Sai Pavan Viswanath Upadhyayula


FFR(From Framework Reference) : Nullable Types

Over the weekend I happened to download the .net framework 4 source code as its one of those source codes written by some of the smartest people in the world. I was going through some of the classes which I usually use in my day-to-day coding and found few interesting facts. In an attempt to share my findings with the community I am starting this series named From-Framework-Reference (FFR). This basically gives insight into few of randomly (or may be most used by me) picked up classes and their implementation at high level in the framework and how does it impact our daily usage of these classes in our projects. This blog we are going to look at Nullable<T> class, its implementation and some practical tips of using this class in the projects. Another reason being, sometimes its better to read code than reading documentation.

Located in System, in the file Nullable.cs there are two objects one being static Nullable & the other one being a generic struct Nullable<T>. First we are going to look at Nullable static class. It has 3 useful methods Compare<T>, Equals<T>, GetUnderlyingType<T>

Compare<T> : I learnt couple of things here. First, the way to use only generic methods without the class being generic where the Type could be any struct. The second one being the framework underlying uses the default comparer by using Comparer generic class as

Comparer<T>.Default.Compare(n1.value, n2.value)

Things get tricky when we implement a custom struct and try to make it nullable.

Equals<T> : Works on similar lines as above and uses underlying EqualityComparer<T> and get the Default implementation and compares the values and is implemented in a way explained in MSDN documentation.

GetUnderlyingType<T> : As MSDN documentation suggests, when null is passed to this method a ArgumentNullException is raised. Return parameter is assigned to value of null such that if the next conditions satisfy null is returned for this method. Now a check on the type IsGenericType & and not IsGenericTypeDefinition is done making sure that this is a generic type i.e., it is Nullable<T> now get the GetGenericTypeDefinition from the Type. now the genericType obtained just now is checked for ReferenceEquals with typeof Nullable<> make sure that it’s a Nullable<T> implemenation. If these conditions satisfy GetGenericArguments method is called which will give all the generic parameters in order. Since Nullable<T> has only one we have to get it with indexer 0 and return the result.

Nullable<T> struct implementation:

Going through struct was pretty interesting for the fact that I have expected to be implemented in a different way. As the class is comparatively bigger than Nullable struct (though much much smaller than other classes in .net) I am going to go through the highlights/learning that I had through this class implementation.

First and foremost observation was  its implemented as struct (though we know this from MSDN documentation) it makes sense because the generic parameter can only be a struct. The next one being implicit operator implementation is present and to my surprise whenever we assign a value a new struct implemenation is returned. I think its because it’s a struct so not much memory pressure.

return new Nullable<T>(value);

Another interesting thing for me was the explicit operator implementation where the code is

public static explicit operator T(Nullable<T> value) { 
            return value.Value; 
}

My thoughts after seeing this code was it would raise an exception when we try to run the following code because when value.Value will be called since the variable ‘i’ does not have value it will raise a InvalidOperationException (just like when we call i.Value) but as we know practical implementation of this code does not raise any exception.

int? i = null;
int? i2 = (int?)i;

However, the following implementation is raising the InvalidOperationException as expected. I have asked this question in StackOverflow and would be updating once I get the answer.

It could be that some of the details are already present on MSDN but it was fun & learning in understanding the code written by smart people.

That’s all folks!!

Hope you people will find this useful.

Thanks,
Sai Pavan Viswanath Upadhyayula



All the .net framework code shown above is copyrighted to Microsoft™ Corporation

Securing the cookies

Web application security – the buzz word since quite some time. Small steps towards security, simple things taken care would help us in the bigger picture of securing our website. In this blog, we are going to discuss about securing the cookies, the little magicians, which make quite a few things possible on web like identifying the user, how long it has been since he first logged on and so on. Now, every good thing comes with a negative shade. Though they are very much handy it is very easy for anyone to view the cookies or rather steal them.

Yes, we can encrypt them so that it ensures their safety. Before going to that step few simple things when taken care will ensure highly safe cookies without the overhead of encryption. Let’s first think about how the cookies are transmitted and accessed. As we already know cookies are key/value pairs stored in the form of files on the user’s hard drive (not necessarily always though). Since they are stored on client location the security cannot be guaranteed. For obvious reasons we cannot guarantee security of the cookies if the attacker has physical access to computer. Now we are going to discuss couple of methods to make cookies safer, while being accessed programmatically or while being transmitted over the network

Task 1: Mark the cookies “HttpOnly”

Cookies as we know can be easily accessed through the scripting languages like JavaScript. It is as simple as calling document.cookie and we get all the cookies associated with that website. Since we can’t do much about the situation where attacker has physical access, we cannot be complacent and allow access to the cookies in such an easy way. The good news is that we have a very easy way to secure our cookies from being accessed through scripting languages by marking them as HttpOnly while we are creating the cookies. Doing this for each and every cookie that we are creating in a programmatic way is time consuming and error prone. Fortunately ASP.NET provides us with an easy way to do this in the web.config file as shown below

<httpCookies httpOnlyCookies="true"/>

With the above configuration ASP.NET makes sure that all the cookies (either user created or ASP.NET created) are marked as HttpOnly. Now comes the question what is HttpOnly. As the name suggests these cookies can be accessed only via Http protocol which means that any access via the scripting languages is not possible. During each page request the cookies are sent back and forth on the Http protocol and no other way of accessing the cookies is permitted. Ok, its good that we stopped script access to the cookies, now comes the question what if someone is eavesdropping on my communication with the web server. This setting cannot provide any kind of security in this scenario. Hence now its time to move on to the next task where we are going to address this issue.

Task 2: Mark the cookies as “Secure”

Now that we have secured our cookies from the evil scripting languages and made sure that they are transmitted only on the Http channel we will lookat how to avoid eavesdropping. When data is sent over the internet, it is done so in plain text so the persons who can put a wire on your cable or who share the same router at your ISP can very easily track what you are doing. This issue was there since long and hence the technology HTTPS which is HTTP Secure. To put it simply a 128-bit encrypted channel is established between the web browser and the web server. All the data on this channel is encrypted using the public key token provided by the server and upon receiving the request the web server will decrypt the content. What is best way other than sending your cookies on the same channel. To make sure that your cookies are transmitted “only” on the secure channel you would mark the cookie as “Secure”. This is done again while setting the cookie on the client’s machine instructing the web browser to send the cookie only on the secure Http channel. Again ASP.NET has made our life easy by defining an attribute to mark all the cookies as secure.

<httpCookies httpOnlyCookies="true" requireSSL="true"/>

A word of caution here. If you try to test your website on a non secure channel each request is considered as a new session. So all the variables and other session data are reset for every request. For each request the SessionId cookie is set on the user’s machine. Hence this attribute has to be used with little care.

That’s all folks!!

Hope you people will find this useful.

Thanks,
Sai Pavan Viswanath Upadhyayula


Practical implementation of fix for XSS vulnerability

In this post, I am going to discuss about the practical way of fixing the XSS vulnerability in ASP.NET applications. An introduction about XSS vulnerability can be found here. So, why I chose to write this blog post. I happened to see quite a few blog posts and sites which discuss about fixing the XSS vulnerability by constraining the input and encoding the output. But, I felt that there is a gap between practical implementation of the suggestion and what is written in the web sites.

Now lets discuss briefly about how we would be going ahead and fixing this issue. As this link suggests the simple approach for this security vulnerability is constrain the input and encode the output. Its simple when on an article but during implementation we will face some issues. I will put forward one such issue. Lets go ahead with the suggestion of constraining the input. Following the basic rule of implementing Regex/Custom validator with ClientScript enabled and having the ServerValidate event implemented so that when the page is posted back we can double check on whether the input is proper or not. Along with this we are also suggested to implement the ASP.NET built-in capability of identifying and filtering malicious input. The main issue occurs here.

Everything is fine till we constrain the input on the client-side using JavaScript functions. But as the popular suggestion goes we cannot trust the input based only on our validations on client-side. So now when we enable ValidateRequest attribute on the Page directive even before our server side validation of the validators kicks in ASP.NET will identify the malicious input. When it identifies malicious input it actually redirects to an error page which looks something like this.

ValidateRequest

Definitely it is possible to gracefully handle this by handling the exception of type HttpRequestValidationException and then redirecting the user to appropriate custom error page. But we have to remember here that most of the users are legitimate and also not giving a chance to the end user to correct his mistake or worst not even telling the user where the mistake is present is not acceptable. Thus we need more fine grained control over how we are going to leverage ASP.NET built-in capability to handle malicious input while allowing our server side validations to run and check for error before ASP.NET validation kicks in.

Before discussing the strategy on implementing solution for above problem we will first have to understand how setting the attribute ValidateRequest will actually work. If you are aware of the Page life cycle, one of the very early events that is fired is ProcessRequest of the PageHandlerFactory. PageHandlerFactory is the default HttpHandler for the ASP.NET files. In this ProcessRequest  the method Request.ValidateInput() is called. Here is an excellent blog on the inner working of ValidateInput method. This method actually sets flags which will suggest whether the following inputs coming from the client side are actually proper viz., Form data, Cookies, QueryString. Please remember that calling that method does not raise an HttpRequestValidationException, we have access the collection which actually has malicious input for the exception to be raised.

Thus by setting ValidateRequest as false in Page directive and then calling this method in Page load we would gain control over the ASP.NET validation. Now we can call the Page.Validate() to trigger server side validation and if page is invalid simply return to the end-user suggesting the problem with their input. In a scenario where our validation fails as a next line of defense we would access the collections of forms, query string and cookies so that since ValidateInput has already set the flags accessing any one of the above which are having an issue will raise an exception. Thus, we can ensure that Server side validation is done while not compromising on ASP.NET built-in validation. Here is the sample code for the same.

protected void Page_Load(object sender, EventArgs e)
        {
            try {
                if (Page.IsPostBack)
                {
                    Request.ValidateInput();

                    Page.Validate();
                    if (!Page.IsValid)
                    {
                        return;
                    }

                    NameValueCollection formsCollection = Request.Form;
                    NameValueCollection queryStringCollection = Request.QueryString;
                    HttpCookieCollection cookiesCollection = Request.Cookies;
                }
            }
            catch (HttpRequestValidationException)
            {
                Response.Redirect("MaliciousInputError.html");
            }
        }

Also, I have seen developers who just started their career in .net worrying about the return statement in the Page_Load event. I want to clarify here that with the return statement we only come out from page load event, rest of the page lifecycle will be intact.

Hope you people will find this useful.

Thanks,

Sai Pavan Viswanath Upadhyayula


DateTime vs. StopWatch

Today I was trying to measure performance of an extension method that I have written on a DataSet. Basically, the extension method loops through all the DataTables. On each  DataTable it iterates through all the rows (including the column names) and encodes all the strings using the HttpUtility.HtmlEncode method. This is to make sure that we are protecting our site from XSS attack (more about prevention of XSS attacks in ASP.NET are here). I had to do this without effecting the current performance of the website.

Now, I had to somehow measure and I was using Debug.WriteLine method to log the details. First off I started with DateTime.Now, storing it in a variable and then after the processing was done subtracting it from the current DateTime (DateTime.Now) and taking the milliseconds elapsed in the resulting TimeSpan surprised me. I was sure that there was time consumption for that task but the output window was showing zero milliseconds. After couple of tries I resorted to StopWatch class. The usual Start and Stop methods before and after the task were now actually showing me the correct details. It was accurate to the Tick.

So my today’s learning, for accuracy and performance measurements depend only on StopWatch class :-) . Might have learned it late but as the saying goes “Better late than never”. Hope it helps some one.

Thanks,

Sai Pavan Viswanath Upadhyayula

Aiming high!!

Hello World!!

Here is my first blog, rather I should say its one of the many of my registered blogs where I took a new year resolution to be active on. I am planning to post all my learning in the Software field on an immediate basis on this blog. Hope people will feel this blog useful.

To introduce myself, I am a .Net Developer working for an MNC and I have an experience of 3.5 years on .Net. My only aim for starting this blog is to document my learning in way that is useful for me as well as the developer community. I also have simple wishes which I would discuss when the time is right. Hoping that this new year fulfills my wishes.

Thanks,

Sai Pavan Viswanath Upadhyayula