European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET 4.5 Hosting - Amsterdam :: How to Disable Bundling and Minification in ASP.NET 4.5/MVC 4

clock February 12, 2013 05:51 by author Scott

Lots of people are excited about the new bundling and minification feature in the next version of ASP.NET and MVC. One major drawback I see a lot of people clamoring about is the fact that you cannot conditionally disable bundling or minification when you are in debug mode. Out of the box (and to be clear, I’m referring to the version that ships with MVC 4 beta) it’s impossible to debug your CSS and Javascript.

I expect this will change in the release version, but for now you are forced to create your own custom bundles (something you’d end up doing anyway) and conditionally check if you’re in debug mode to short-circuit the bundling/minification.

Disabling minification while in debug mode

It’s as simple as an #if DEBUG line and creating a transformer that does nothing. For example:

01           protected void Application_Start()
02           {
03               IBundleTransform jsTransformer;
04           #if DEBUG
05               jsTransformer = new NoTransform("text/javascript");
06           #else
07               jstransformer = new JsMinify();
08           #endif
09          
10               var bundle = new Bundle("~/Scripts/js", jsTransformer);
11          
12               bundle.AddFile("~/Scripts/script1.js");
13               bundle.AddFile("~/scripts/script2.js");
14          
15               BundleTable.Bundles.Add(bundle);
16           }

Now when you reference this javascript bundle like <script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script> in a view it will render a single bundled and minified script when in release mode, but as a single bundled, non-minified file while in debug mode.

Disabling bundling while in debug mode

The above approach improves this situation, but I don’t think it goes far enough. If I’m going to have multiple source files, I want to debug with the same multiple source files, at least initially. It would get too confusing writing code in a several files and then debugging it in a single monolithic file.

As an experiment to see if it was possible, I ended up building a better bundler that does just what I want: bundles and minifies in release mode, but doesn’t bundle or minify when the build is set to debug.

The entire class is below, explanation to follow:

01           public static class BetterBundler
02           {
03               private static bool _debug;
04               const string CssTemplate = "<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />";
05          
06               public static void Init()
07               {
08           #if DEBUG
09                   _debug = true;
10           #endif
11                   var bundle = new Bundle("~/content/css", new CssMinify());
12          
13                   bundle.AddFile("~/Content/test.css");
14                   bundle.AddFile("~/Content/site.css");
15                   
16                   BundleTable.Bundles.Add(bundle);
17               }
18          
19               public static MvcHtmlString ResolveBundleUrl(string bundleUrl)
20               {
21                   return _debug ? BundledFiles(BundleTable.Bundles.ResolveBundleUrl(bundleUrl)) : UnbundledFiles(bundleUrl);
22               }
23               
24               private static MvcHtmlString BundledFiles(string bundleVirtualPath)
25               {
26                   return new MvcHtmlString(string.Format(CssTemplate, bundleVirtualPath));
27               }
28          
29               private static MvcHtmlString UnbundledFiles(string bundleUrl)
30               {
31                   var bundle = BundleTable.Bundles.GetBundleFor(bundleUrl);
32          
33                   StringBuilder sb = new StringBuilder();
34                   var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
35          
36                   foreach (var file in bundle.EnumerateFiles(new BundleContext(new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, bundleUrl)))
37                   {
38                       sb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(ToVirtualPath(file.FullName)));
39                   }
40          
41                   return new MvcHtmlString(sb.ToString());
42               }
43          
44               private static string ToVirtualPath(string physicalPath)
45               {
46                   var relativePath = physicalPath.Replace(HttpContext.Current.Request.ServerVariables["APPL_PHYSICAL_PATH"], "");
47                   return relativePath.Replace("\\", "/").Insert(0, "~/");
48               }
49          
50               public static MvcHtmlString CssBundle(this HtmlHelper helper, string bundleUrl)
51               {
52                   return ResolveBundleUrl(bundleUrl);
53               }
54           }

To summarize, I’m using the same technique to determine debug mode, and of course this could be extended to conditionally bundle or not based on any boolean. The interesting code is in the UnbundledFiles(string bundleUrl) method.

Currently, there is no concept of named bundles – bundles are specified simply by the virtual path of the resultant bundle. This means all our calling code in the view has to give is the virtual path of the bundle. We have to start from that and uncover all the physical files deeper within the BundleTable.

var bundle = BundleTable.Bundles.GetBundleFor(bundleUrl);

This line retrieves the bundle that we created from the BundleTable.

bundle.EnumerateFiles(new BundleContext(new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, bundleUrl))

This gets all of the physical files from the bundle.

The rest is just boilerplate code to turn those raw physical files back into relative virtual paths and into the proper html tags.

Finally, you’ll note that I have an HtmlHelper method in there, CssBundle(this HtmlHelper helper, string bundleUrl). To render a bundle link in a view, this must be used. Since the result of a bundle could be one or multiple files, I decided the simplest approach would be to allow the BetterBundler to render the full html tag itself. This could easily be changed or enhanced.

1              In the view:
2             
3              @Html.CssBundle("~/content/css")

The Result

In release mode:

<link href="/content/css?v=7GiB-1k9Pr1JbbYY72bT3T2EOpxXf0rGPdEOXVKl5oQ1" rel="stylesheet" type="text/css" />

In debug mode:

<link href="/content/test.css" rel="stylesheet" type="text/css" />
<link href="/content/site.css" rel="stylesheet" type="text/css" />

 



European ASP.NET 4.5 Hosting - Amsterdam :: Web Sockets and How to Develop HTML5 Web Sockets in ASP.NET 4.5

clock December 20, 2012 05:02 by author Scott

HTML5 WebSockets allow you to perform two-way (duplex) communication between the client browser and the server. ASP.NET 4.5 and IIS 8 provide support for WebSocket protocol so that you can program WebSockets in your ASP.NET web forms and ASP.NET MVC applications. This article discusses what WebSockets are and how to develop web applications that take advantage of HTML5 WebSockets.

Overview of HTML5 Web Sockets

Typically a communication over the web is comprised of two distinct parties participating in the communication, viz. the client and the web server. An ordinary web page uses a request-response model of communication wherein the browser sends a request to the server and the server then sends back a response. Each request and response uses a new connection and that connection is closed once the response is returned by the server. As you might have guessed, such a communication is poor in terms of performance since a new connection is established between the same client and the server every time. Additionally, such a communication can't be two way, i.e. client talking to server and server talking to the client simultaneously.

In the case of two-way or duplex communication both the parties participating in the communication can communicate at the same time. A common application of the duplex communication is chat systems such as MSN or Yahoo Messenger and Google Talk. In any chat system, two or more members can chat with each other at the same time. As far as HTML5 is concerned, the technique to achieve two way communications is Web Sockets.

Unlike the request-response model, WebSockets keep the underlying communication channel open throughout the course of communication. A WebSocket based communication typically involves three steps:

- Establishing a connection between the client and the server or Hand Shake.
- Asking the Web Socket server to listen to the incoming communication
- Sending and receiving data

Web applications use HTTP protocol for their functioning and HTTP protocol essentially makes use of the request-response model. The plain HTTP protocol isn't well suited for performing two-way communications. The WebSockets therefore, need to "upgrade" the plain HTTP protocol to WebSocket protocol. This "upgrade" takes place while establishing the connection between the client and the server. In order to upgrade the communication from plain HTTP to WebSocket, you need a web server that is capable of doing this upgrade.

Enabling WebSocket Protocol in Windows 8

As far IIS is concerned, IIS 8.0 that ships with Windows 8 is capable of accepting Web Socket communications. If you are developing a web application that makes use of HTML5 Web Sockets, you may need to install WebSocket support in IIS 8.0. The following figure shows the "Turn Windows features on or off" option from the control panel. It can be used to install WebSocket protocol.



Notice how the "WebSocket Protocol" feature is checked under "World Wide Web Services". If the IIS installation doesn't have WebSocket protocol enabled your ASP.NET applications won't be able to receive and respond to the WebSocket requests on the server.

A WebSocket based application consists of two parts, viz. WebSocket server side code and WebSocket client side code. The WebSocket server side code sits on the web server and "listens" to the incoming communication from clients. When some communication is received from the client it processes the communication and typically sends some communication back to the client. If there is no communication from the client the WebSocket server can either keep waiting for the communication or can terminate the communication channel. The WebSocket client side code makes use of the WebSocket object of HTML5 for the purpose of sending and receiving data to and from the WebSocket server side code.

The WebSocket client side code follows the same coding pattern regardless of your web server software. As far as ASP.NET is concerned, IIS 8 and certain .NET framework classes together allow you to develop WebSocket server side functionality. To understand how the client side and server side code goes hand in hand let's develop a simple application that performs a two-way communication. The web form that acts as a WebSocket client is shown below:



Using the above web form you can send a text message from the client to the server. The server then sends the same message back to the client (this is purely for the sake of simplicity and testing purposes. You can send any other data from the server. Clicking on the Stop button stops the server and no further communication can take place between the client and the server.

Coding the Client Side

Open the default web form and add the following jQuery code to a <script> block:

var socket;
$(document).ready(function () {
    socket = new WebSocket("ws://localhost:1046/WebSocketGenericHandler.ashx");
    socket.addEventListener("open", function (evt) {
      $("#divHistory").append('<h3>Connection Opened with the Echo server.</h3> ');},
    false);  
    socket.addEventListener("message", function (evt) {
      $("#divHistory").append('<h3^gt;' + evt.data + '</h3> ');   },
    false);  
    socket.addEventListener("error", function (evt) {
      $("#divHistory").append('<h3>Unexpected Error.</h3> ');},
    false);
    ...
});


The code shown above declares a global variable named socket to hold a reference to a WebSocket object. A WebSocket instance is then created by passing the URL of the WebSocketHandler.ashx. The WebSocketHandler.ashx contains the WebSocket server side code that "listens" to the client requests. You will develop WebSocketHandler.ashx later in this article. Notice how the URL uses ws:// protocol instead of http://. Next, event handlers for the three events, viz. open, message, and error, are wired using the addEventListener() method. The open event is raised when the readyState property (discussed next) changes to 1 (OPEN) and indicates that the connection is ready to send and receive data. The message event is raised when a message is received from the WebSocket server. The error event is raised when an error occurs during the communication with the Web Socket server.

Inside the message event handler the data sent by the server is retrieved using the evt.data property. The returned data is then appended to a <div> element. The other event handlers simply output the specified messages in the <div> element. The data from the client is sent to the server when the Send button is clicked. The click event handler of the Send button looks like this:

$("#btnSend").click(function () {
    if (socket.readyState == WebSocket.OPEN) {
        socket.send($("#txtMsg").val());
    }
    else {
        $("#divHistory").append('<h3>The underlying connection is closed.</h3> ');
  }
});


The click event handler of the Send button checks the readyState property of the WebSocket object. If the readyState is OPEN, it calls the send() method on the WebSocket instance. This read only property returns the current state of the connection. Possible values are 0 - CONNECTING, 1 - OPEN, 2 - CLOSING, 3 - CLOSED. The send() method sends data to the WebSocket server side code over an established connection. The text entered in the textbox is passed as a parameter to the send() method.

You can close the underlying connection by calling the close() method of the WebSocket object as follows:

$("#btnStop").click(function () {
  socket.close();
});

Coding the Server Side

The WebSocketHandler.ashx contains the server side code that listens and responds to the client requests. This code is shown below:

public class WebSocketHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        if (context.IsWebSocketRequest)
        {
            context.AcceptWebSocketRequest(DoTalking);
        }
    }
    ...
}


The above code shows an ASP.NET generic handler - WebSocketHandler - that triggers the WebSocket server. The ProcessRequest() method of the generic handler first checks whether the incoming request is a WebSocket request. This is done by checking the IsWebSocketRequest property of the HttpContext object. This property works hand-in-hand with the IIS 8.0 WebSocket module and returns true if an incoming request is a WebSocket request. A Web Socket request is different than an ordinary HTTP request in that instead of using http:// protocol it uses ws:// (Web Socket) protocol.

If the IsWebSocketRequest returns true, the AcceptWebSocketRequest() method of the HttpContext is called. This method takes one parameter - user function - that supplies a function that listens and responds to the client requests. In this case the user function contains the logic to listen to the incoming data and send it back to the client. The user function supplied to the AcceptWebSocketRequest() method should be an asynchronous function as shown below:

public async Task DoTalking(AspNetWebSocketContext context)
{
    WebSocket socket = context.WebSocket;
    while (true)
    {
        ArraySegment buffer = new ArraySegment(new byte[1024]);
        WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
        if (socket.State == WebSocketState.Open)
        {
            string userMessage = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
            userMessage = "You sent: " + userMessage + " at " +  DateTime.Now.ToLongTimeString();
            buffer = new ArraySegment(Encoding.UTF8.GetBytes(userMessage));
            await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
        }
        else
        {
            break;
        }
    }
}


The DoTalking() method is marked as "async" indicating that the code inside it is going to run in asynchronous fashion. The DoTalking() method returns a Task object. The Task class acts as a wrapper to the asynchronous code. The DoTalking() method receives a parameter of type AspNetWebSocketContext. The AspNetWebSocketContext class gives you access to the WebSocket through its WebSocket property. The WebSocket class is the server side counterpart of the HTML5 WebSocket object. An endless while loop is then started so that the server can continuously listen to the incoming requests. To receive the incoming data, the ReceiveAsync() method of the WebSocket class is used. The ReceiveAsync() method is invoked along with the await operator. In this case the awaited task is to receive incoming data and store it in an ArraySegment, a byte array. The results of the receive operation are stored in WebSocketReceiveResult object. If the WebSocket is open as indicated by the State property, the received data is sent back to the client using the SendAsync() method. If the State property has any value other than Open, the while loop is exited thus terminating the server.

Summary

HTML5 WebSockets allow you to perform two-way (duplex) communication. To use HTML5 WebSockets in an ASP.NET application you need to enable the WebSocket protocol in IIS 8.0. You can then use IsWebSocketRequest property and AcceptWebSocketRequest() method to start the client-server communication. Using WebSockets, you can develop web applications such as Chat systems that require the ability to send and receive data simultaneously between the client and the server.

 



European ASP.NET 4.5 Hosting - Amsterdam :: Using Caller Info Attributes in .NET 4.5

clock December 12, 2012 07:56 by author Scott

Introduction

When developing complex .NET applications sometimes you need to find out the details about the caller of a method. .NET Framework 4.5 introduces what is known as Caller Info Attributes, a set of attributes that give you the details about a method caller. Caller info attributes can come in handy for tracing, debugging and diagnostic tools or utilities. This article examines what Caller Info Attributes are and how to use them in a .NET application.


Overview of Caller Info Attributes


Caller Info Attributes are attributes provided by the .NET Framework (System.Runtime.CompilerServices) that give details about the caller of a method. The caller info attributes are applied to a method with the help of optional parameters. These parameters don't take part in the method signature, as far as calling the method is concerned. They simply pass caller information to the code contained inside the method. Caller info attributes are available to C# as well as Visual Basic and are listed below:

Caller Info Attribute

Description

CallerMemberName

This attribute gives you the name of the caller as a string. For methods, the respective method names are returned whereas for constructors and finalizers strings ".ctor" and "Finalizer" are returned.

CallerFilePath

This attribute gives you the path and file name of the source file that contains the caller.

CallerLineNumber

This attribute gives you the line number in the source file at which the method is called.


A common use of these attributes will involve logging the information returned by these attributes to some log file or trace.


Using Caller Info Attributes


Now that you know what Caller Info Attributes are, let's create a simple application that shows how they can be used. Consider the Windows Forms application shown below:


The above application consists of two Visual Studio projects - a Windows Forms project that contains a form as shown above and a Class Library project that contains a class called Employee. As you might have guessed the Windows Form accepts EmployeeID, FirstName and LastName and calls AddEmployee() method of the Class Library. Though the application doesn't do any database INSERTs for the sake of illustrating Caller Info Attributes this setup is sufficient.

The Employee class that resides in the Class Library project is shown below:


1. 
public class Employee
2. 
{
3. 
    public Employee([CallerMemberName]string sourceMemberName = "",
4. 
                    [CallerFilePath]string sourceFilePath = "",
5. 
                    [CallerLineNumber]int sourceLineNo = 0)
6. 
    {
7. 
        Debug.WriteLine("Member Name : " + sourceMemberName);
8. 
        Debug.WriteLine("File Name : " + sourceFilePath);
9. 
        Debug.WriteLine("Line No. : " + sourceLineNo);
10.
    }
11. 

12.
    private int intEmployeeID;
13.
    public int EmployeeID
14.
    {
15.
        get
16.
        {
17.
            return intEmployeeID;
18.
        }
19.
        set
20.
        {
21.
            intEmployeeID = value;
22.
        }
23.
    }
24. 

25.
    private string strFirstName;
26.
    public string FirstName
27.
    {
28.
        get
29.
        {
30.
            return strFirstName;
31.
        }
32.
        set
33.
        {
34.
            strFirstName = value;
35.
        }
36.
    }
37. 

38.
    private string strLastName;
39.
    public string LastName
40.
    {
41.
        get
42.
        {
43.
            return strLastName;
44.
        }
45.
        set
46.
        {
47.
            strLastName = value;
48.
        }
49.
    }
50. 

51.
    public string AddEmployee([CallerMemberName]string sourceMemberName="",
52.
                              [CallerFilePath]string sourceFilePath="",
53.
                              [CallerLineNumber]int sourceLineNo=0)
54.
    {
55.
        Debug.WriteLine("Member Name : " + sourceMemberName);
56.
        Debug.WriteLine("File Name : " + sourceFilePath);
57.
        Debug.WriteLine("Line No. : " + sourceLineNo);
58.
        //do database INSERT here
59.
        return "Employee added successfully!";
60.
    }
61.
    

The Employee class is quite simple. It contains a constructor, a method named AddEmployee() and three properties, viz. EmployeeID, FirstName and LastName. The caller info attributes are used in the constructor and AddEmployee() method. Notice how the caller info attributes are used. To use any of the caller info attributes you need to declare optional parameters and then decorate them with the appropriate attributes. In the above example the code declares three optional parameters, viz. sourceMemberName, sourceFilePath and sourceLineNo. Note that sourceLineNo is an integer parameter since the [CallerLineNumber] attribute gives a numeric result. The optional parameters are assigned some default values. These values are returned in case there is no caller information. Inside the constructor and AddMethod() the code simply outputs the parameter values to the Output window using Debug.WriteLine() statements.

The Employee class thus created is used by the Windows Forms application as follows:


1. 
private void button1_Click(object sender, EventArgs e)
2. 
{
3. 
    Employee emp = new Employee();
4. 
    emp.EmployeeID = int.Parse(textBox1.Text);
5. 
    emp.FirstName = textBox2.Text;
6. 
    emp.LastName = textBox3.Text;
7. 
    MessageBox.Show(emp.AddEmployee());
8. 
}

The Click event handler of the Add Employee button simply creates a new instance of the Employee class, assigns property values and calls the AddEmployee() method.

If you run the Windows Forms application and see the Output window you should see this:



The Output window shows the caller information

As you can see the Output window shows the caller information as expected.


Using [CallerMemberName] with INotifyPropertyChanged Interface


Though the primary use of caller info attributes is in debugging and tracing scenarios, you can use the [CallerMemberName] attribute to avoid using hard-coding member names. One such scenario is when your class implements the INotifyPropertyChanged interface. This interface is typically implemented by data bound controls and components and is used to notify the user interface that a property value has changed. This way the UI can refresh itself or do some processing. To understand the problem posed by hard-coding property names see the modified Employee class below:


1. 
public class Employee:INotifyPropertyChanged
2. 
{
3. 
    public event PropertyChangedEventHandler PropertyChanged;
4.  

5. 
    private int intEmployeeID;
6. 
    public int EmployeeID
7. 
    {
8. 
        get
9. 
        {
10.
            return intEmployeeID;
11.
        }
12.
        set
13.
        {
14.
            intEmployeeID = value;
15.
            if (PropertyChanged != null)
16.
            {
17.
               PropertyChangedEventArgs evt = new PropertyChangedEventArgs("EmployeeID");
18.
               this.PropertyChanged(this, evt);
19.
            }
20.
        }
21.
    }
22. 

23.
    private string strFirstName;
24.
    public string FirstName
25.
    {
26.
        get
27.
        {
28.
            return strFirstName;
29.
        }
30.
        set
31.
        {
32.
            strFirstName = value;
33.
            if (PropertyChanged != null)
34.
            {
35.
               PropertyChangedEventArgs evt = new PropertyChangedEventArgs("FirstName");
36.
               this.PropertyChanged(this, evt);
37.
            }
38.
        }
39.
    }
40. 

41.
    private string strLastName;
42.
    public string LastName
43.
    {
44.
        get
45.
        {
46.
            return strLastName;
47.
        }
48.
        set
49.
        {
50.
            strLastName = value;
51.
           if (PropertyChanged != null)
52.
            {
53.
               PropertyChangedEventArgs evt = new PropertyChangedEventArgs("LastName");
54.
               this.PropertyChanged(this, evt);
55.
            }
56.
        }
57.
    }
58. 

59.
    public string AddEmployee([CallerMemberName]string sourceMemberName="",
60.
                              [CallerFilePath]string sourceFilePath="",
61.
                              [CallerLineNumber]int sourceLineNo=0)
62.
    {
63.
       ...
64.
    }
65.
}

The Employee class now implements INotifyPropertyChanged interface. Whenever a property value is assigned it raises PropertyChanged event. The caller (Windows Forms in this case) can handle the PropertyChanged event and be notified whenever a property changes. Now the problem is that inside the property set routines the property names are hard-coded. If you ever change the property names you need to ensure that all the hard-coded property names are also changed accordingly. This can be cumbersome for complex class libraries. Using the [CallerMemberName] attribute you can avoid this hard-coding. Let's see how.

To use the [CallerMemberName] attribute to avoid hard-coding the property names you need to do a bit more work. You need to create a generic helper method that internally assigns the property values. The following code shows how this can be done:


1. 
protected bool SetPropertyValue<T>(ref T varName, T propValue, [CallerMemberName] string propName = null)
2. 
{
3. 
    varName = propValue;
4. 
    if (PropertyChanged != null)
5. 
    {
6. 
        PropertyChangedEventArgs evt = new PropertyChangedEventArgs(propName);
7. 
        this.PropertyChanged(this, evt);
8. 
        Debug.WriteLine("Member Name : " + propName);
9. 
    }
10.
    return true;
11.
}

The SetPropertyValue() method uses only the [CallerMemberName] attribute. It takes three parameters. The first reference parameter is the variable that holds a property value (strFirstName for example). The second parameter is the new property value being assigned to the property. Finally, the third optional parameter supplies the caller member name. Inside the SetPropertyValue() method you assign the property value to the variable, raises the PropertyChanged event and calls Debug.WriteLine() as before.

Now, you need to call the SetPropertyValue() method inside the property set routines as shown below:


1. 
private string strFirstName;
2. 
public string FirstName
3. 
{
4. 
    get
5. 
    {
6. 
        return strFirstName;
7. 
    }
8. 
    set
9. 
    {
10.
        SetPropertyValue<string>(ref strFirstName, value);
11.
    }
12.
}

Now when you assign any property value, the set routine will call the SetPropertyValue() method and pass its name to the SetPropertyValue() method. Inside the SetPropertyValue() method you use this name (propName parameter) without hard-coding the actual property name.

Summary


.NET Framework 4.5 introduces Caller Info Attributes that can be used to obtain information about the caller of a method. Three attributes, viz. [CallerMemberName], [CallerFilePath] and [CallerLineNumber] supply caller name, its source file and the line number at which the call was made. You can use caller info attributes for tracing, debugging, logging or diagnostic purposes.



European ASP.NET 4.5 Hosting - Amsterdam :: Using ASP.NET 4.5 to Upload Multiple Files

clock November 23, 2012 05:20 by author Scott

In versions of ASP.NET before 4.5 there was no direct way to enable a user to upload multiple files at once. The FileUpload control only supported a single file at the time. Common solutions to uploading multiple files were to use a server-side control such as those from Telerik or DevExpress or to use a client-side solution using a jQuery plugin for example. In the latter case, you would access Request.Files to get at the uploaded files, rather than retrieving them form a FileUpload control directly. Fortunately, in ASP.NET 4.5 uploading multiple files is now really easy.

The FileUpload Control with HTML5 Support

The FileUpload control has been enhanced in ASP.NET to support the HTML5 multiple attribute on an input with its type set to file. The server control has been expanded with an AllowMultiple attribute that renders the necessary HTML5 attribute. In addition, the control now has properties such as HasFiles and PostedFiles that enable you to work with a collection of uploaded files, rather than with just a single file as was the case with previous versions of the control.

All you need to do to enable multiple file uploads is set the AllowMultiple property of the FileUpload control to true:

<asp:FileUpload ID="FileUpload1" runat="server" AllowMultiple="true" />

In the browser, this renders the following HTML:

<input type="file" multiple="multiple" name="FileUpload1" id="FileUpload1" />

Notice how the multiple="multiple" attribute tells the browser to enable support for multiple files. Each browser that supports this feature uses a slight different interface. For example, in Chrome it looks like this:

while in Opera it looks like this:

All major browsers (Firefox, Chrome, Opera and Safari) except Internet Explorer 9 support this feature. IE 10 will support uploading multiple files as well, so hopefully this limitation is soon a thing of the past. While Safari seems to officially support this feature, I couldn't make the example work with multiple files. This could be a bug in Safari.

Working with the uploaded files at the server is similar to how you used to work with the control, except that you now work with a collection of files, rather than with a single instance. The following code snippet demonstrates how to save the uploaded files to disk and assign their names to a simple Label control, reporting back to the user which files were uploaded:

protected void Upload_Click(object sender, EventArgs e)
{
  if (FileUpload1.HasFiles)
  {
    string rootPath = Server.MapPath("~/App_Data/");
    foreach (HttpPostedFile file in FileUpload1.PostedFiles)
    {
      file.SaveAs(Path.Combine(rootPath, file.FileName));
      Label1.Text += String.Format("{0}<br />", file.FileName);
    }
  }
}

With this code, each uploaded file is saved in the App_Data folder in the root of the web site. Notice that this is just a simple example, and you would still need to write code you normally would to prevent existing files from being overwritten, and to block specific files types from being uploaded.

 



Europe ASP.NET 4.5 Hosting - Amsterdam :: Using Model Binding in ASP.NET Data Controls

clock September 6, 2012 09:12 by author Scott

Introduction

ASP.NET Web Forms became popular due to the wide range of data bound controls such as GridView, DetailsView and ListView. The earlier versions of ASP.NET, however, were a bit rigid about how data was bound to these controls. Most of the time developers had to use one or the other data source control (SQL Data Source, Object Data Source, Entity Data Source etc.) to bind data from the underlying data store with the data bound controls. ASP.NET 4.5 provides a flexible alternative to data bind these controls - model binding. Using the new model binding features you can use methods instead of data source controls to perform CRUD operations. This article explains how the new model binding features can be used. You will also learn to use strongly typed data controls.

Data Binding in ASP.NET Server Controls

In the earlier versions of ASP.NET you used data bound controls and data source controls hand in hand to display and edit data. First, you needed to configure a data source control, such as Object Data Source or Entity Data Source and then set the DataSourceID property of a data bound control to the respective data source control. The data bound control would have one or more fields of some inbuilt type (BoundField for example) or template fields. If the control was using template fields you used Eval() data binding expression for one way data binding and Bind() data binding expression for two way data binding.

The following sample markup shows a GridView control bound with an Entity Data Source.

<asp:EntityDataSource ID="EntityDataSource1" runat="server"
    ConnectionString="name=NorthwindEntities"
    DefaultContainerName="NorthwindEntities" EnableFlattening="False"
    EntitySetName="Customers"
    Select="it.[CustomerID], it.[CompanyName], it.[ContactName], it.[Country]">
</asp:EntityDataSource>
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
    DataKeyNames="CustomerID" DataSourceID="EntityDataSource1">
    <Columns>
        <asp:BoundField DataField="CustomerID" HeaderText="CustomerID" ReadOnly="True"
            SortExpression="CustomerID" />
        <asp:BoundField DataField="CompanyName" HeaderText="CompanyName"
            ReadOnly="True" SortExpression="CompanyName" />
        <asp:BoundField DataField="ContactName" HeaderText="ContactName"
            ReadOnly="True" SortExpression="ContactName" />
        <asp:TemplateField HeaderText="Country" SortExpression="Country">
            <EditItemTemplate>
                <asp:Label ID="Label1" runat="server" Text='<%# Eval("Country") %>'></asp:Label>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label1" runat="server" Text='<%# Bind("Country") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>


Notice how the DataSourceID property of the GridView is set to EntityDataSource1. Also, notice the use of Eval() and Bind() to bind the Country column.


Though data source controls work well in simple situations, developers often need complete control on how the data is fetched and how it is saved back to the database. This calls for a more code centered approach than the control driven approach. That is where the new model binding features come into the picture. Using model binding features you can write methods in your code behind class that perform the CRUD operations on the underlying data store. This way you have total control over the process of fetching and editing the data. Have a look at the following markup that uses the new model binding features:

<asp:GridView ID="GridView1" runat="server"
SelectMethod="GetCustomers"
dateMethod="UpdateCustomer"
DeleteMethod="DeleteCustomer"
... >


This time the GridView control doesn't use a data source control. The SelectMethod, UpdateMethod and DeleteMethod properties are set to method names GetCustomers, UpdateCustomers and DeleteCustomers respectively. These methods reside in the code behind. You will develop a complete version of this example in the following sections.

In addition to the code centered data binding, you can also use data within the controls in strongly typed manner. This is especially handy for template fields. Instead of using Eval() and Bind() data binding expressions, you can now use Item and BindItem properties respectively. These properties work along with the ItemType property. The use of these properties will be clear from the following markup.

<asp:GridView ID="GridView1" runat="server"
SelectMethod="GetCustomers"
UpdateMethod="UpdateCustomer"
DeleteMethod="DeleteCustomer"
ItemType="NorthwindModel.Customer"
... >
<Columns>
...
<asp:TemplateField HeaderText="Country" SortExpression="Country">
  <ItemTemplate>
   <asp:Label ID="Label2" runat="server" Text='<%# Item.Country %>'></asp:Label>
  </ItemTemplate
  <EditItemTemplate>
   <asp:TextBox ID="TextBox2" Text='<%# BindItem.Country %>' runat="server"></asp:TextBox>
  </EditItemTemplate>
</asp:TemplateField>
...


Notice the code marked in bold letters. The ItemType property is set to an Entity Framework Data Model type - Customer. Once you do so, you can access properties of Customer class in a strongly typed fashion. Instead of Eval("Country") you now use Item.Country and instead of Bind("Country") you use BindItem.Country. This way there can't be any errors while specifying column names because they are available to you in the intellisense in strongly typed manner.


Creating a Sample Website

Now that you understand the basics of model binding and strongly typed data binding, let's create a web form that illustrates the complete process in detail. You will be using Customers table from the Northwind database in this example. Begin by creating a new ASP.NET Web Site. Then add an Entity Framework Data Model to its App_Code folder and create model class for the Customers table. The following figure shows the Customers model class in the Visual Studio designer




Open the default web form and place a GridView control on it. Configure the GridView to show CustomerID, CompanyName, ContactName and Country columns. Also add Edit and Delete command buttons. The following markup shows the GridView after adding these columns:


<asp:GridView ID="GridView1" runat="server"

SelectMethod="GetCustomers"

UpdateMethod="UpdateCustomer"

DeleteMethod="DeleteCustomer"

ItemType="NorthwindModel.Customer"

AllowSorting="True"

AllowPaging="True"

DataKeyNames="CustomerID" ...>

    <Columns>
        <asp:BoundField DataField="CustomerID" HeaderText="Customer ID" ReadOnly="True"
            SortExpression="CustomerID"></asp:BoundField>
        <asp:TemplateField HeaderText="Company Name" SortExpression="CompanyName">
            <EditItemTemplate>
                <asp:TextBox ID="TextBox2" Text='<%# BindItem.CompanyName %>' runat="server"></asp:TextBox>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label2" runat="server" Text='<%# Item.CompanyName %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="ContactName" HeaderText="Contact Name"
            SortExpression="ContactName"></asp:BoundField>
        <asp:TemplateField HeaderText="Country" SortExpression="Country">
            <EditItemTemplate>
                <asp:TextBox ID="TextBox3" runat="server" Text='<%# BindItem.Country %>'></asp:TextBox>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label3" runat="server" Text='<%# Item.Country %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:CommandField ShowEditButton="True" ButtonType="Button">
        <ControlStyle Width="75px" />
        </asp:CommandField>
        <asp:CommandField ShowDeleteButton="True" ButtonType="Button">
        <ControlStyle Width="75px" />
        </asp:CommandField>
    </Columns>
...

</asp:GridView>


The following figure shows the GridView at runtime:




Notice that the ItemType property of the GridView is set to NorthwindModel.Customer and its SelectMethod, UpdateMethod and DeleteMethod properties are set to GetCustomers, UpdateCustomer and DeleteCustomer respectively. You will be creating these methods in the following sections.


Selecting Data

In order to display data in the GridView you need to write a method that fetches data from the data store and then specify it in the SelectMethod property of GridView. So, switch to the code behind and add a method named GetCustomers() as shown below:


public IQueryable<Customer> GetCustomers()
{
    NorthwindEntities db = new NorthwindEntities();
    var data = from item in db.Customers
                orderby item.CustomerID
                select item;
    return data;
}


The GetCustomers() method returns an IQueryable collection of Customer objects. Inside it fetches all of the records from the Customers table and returns them to the caller. Note that we have enabled paging in our GridView. When you enable paging for a GridView, behind the scenes it fetches only the required number of records as specified by the PageSize property.

Updating and Deleting Data

The methods UpdateCustomer() and DeleteCustomer() do the job of updating and deleting a Customer respectively. The UpdateCustomer() method is shown next:


public void UpdateCustomer(Customer c)

{
    NorthwindEntities db = new NorthwindEntities();
    var data = from item in db.Customers
                where item.CustomerID == c.CustomerID
                select item;

    Customer obj = data.SingleOrDefault();
    obj.CompanyName = c.CompanyName;
    obj.ContactName = c.ContactName;
    obj.Country = c.Country;
    db.SaveChanges();
}


The UpdateCustomer() method accepts a parameter of type Customer. At runtime, when you modify a GridView row and click the Update button, UpdateCustomer() method will be called and the corresponding Customer object is passed as its parameter. Inside, you find out a specific Customer based on its CustomerID, assign the modified values and then save the changes to the database by calling the SaveChanges() method.

The DeleteCustomer() method follows a similar method signature but internally deletes a Customer. The following code shows the DeleteCustomer() method:

public void DeleteCustomer(Customer c)
{
    NorthwindEntities db=new NorthwindEntities();
    var data = from item in db.Customers
                where item.CustomerID == c.CustomerID
                select item;
    Customer obj = data.SingleOrDefault();
    db.DeleteObject(obj);
    db.SaveChanges();
}


The DeleteCustomer() method receives the Customer being deleted as a parameter. Inside it fetches a Customer matching the CustomerID and deletes it using the DeleteObject() method.

Now, run the web form and try editing and deleting a few Customer records.

Adding Validation Support

Though the GridView is able to modify Customer data, there are no validations on the data being saved. One way to enforce the validations is to use a combination of template fields and validation controls. However, there is an easy alternative - Data Annotations.

Data Annotations are special attributes that you apply on the data model properties. They specify validation criteria such as maximum length, minimum length and specific data format (Email address, URL etc.).

To use Data Annotations add a new class in the App_Code folder and name it as CustomerValidations. The CustomerValidations class will store only validation information for the Customer class. You could have added the data annotation attributes directly to the Customer data model class but to avoid accidental overwriting during model recreation it is recommended to isolate them in a separate class.

public class CustomerValidations
{
    [StringLength(5,MinimumLength=3 ,ErrorMessage="CustomerID must between 3-5 characters!")]
    public string CustomerID { get; set; }

    [StringLength(20, ErrorMessage = "Company Name must be upto 20 characters!")]
    public string CompanyName { get; set; }

    [Required]
    public string ContactName { get; set; }

    [Required]
    [StringLength(15,ErrorMessage="Invalid country length!")]
    public string Country { get; set; }
}


The CustomerValidations class makes use of data annotation attributes such as [StringLength] and [Required]. The former attribute ensures that the entered data is within a specified maximum length. The later attribute enforces that the property value must be provided. You can also use many other data annotation attributes depending on your requirement.

As of now the CustomerValidations class is a stand alone class. You need to associate it with the Customer data model class using the [MetadataType] attribute. To do so, open the Entity Framework Data Model file (Model.Designer.cs) and add the following piece of code:

[MetadataType(typeof(CustomerValidations))]
public partial class Customer : EntityObject
{
...
}


The [MetadataType] attribute specifies the type of the class that contains validation information (CustomerValidations in this case).

Now, open the web form and place a ValidationSummary control below the GridView. Set its ShowModelStateErrors property to true. The ShowModelStateErrors property controls whether data model validation errors should be displayed in the ValidationSummary or not.

<asp:ValidationSummary ID="ValidationSummary1" runat="server"
ShowModelStateErrors="true" ... />


In addition to displaying validation errors to the end user, you should also ensure that the changed Customer details are saved in the database only if model validations are successful. To do so, modify the UpdateCustomer() method as shown below:

public void UpdateCustomer(Customer c)

{

    NorthwindEntities db = new NorthwindEntities();
    var data = from item in db.Customers
                where item.CustomerID == c.CustomerID
                select item;
    Customer obj = data.SingleOrDefault();
    obj.CompanyName = c.CompanyName;
    ...
    if (ModelState.IsValid)
    {
        db.SaveChanges();
    }
}


Notice the code marked in bold letters. The UpdateCustomer() method now checks the state of the model using the ModelState.IsValid property. If all the model validations are successful, the IsValid property will return true and only then will changes be saved to the database.


Now, run the web form again and try to enter some invalid data. You should see validation errors similar to the following figure:




Summary


ASP.NET 4.5 supports model binding that allows a more code centric approach for performing CRUD operations on the data. Instead of using Data Source Controls, you can now write methods in the code behind file that select, insert, update and delete data from the underlying data store. The SelectMethod, InsertMethod, UpdateMethod and DeleteMethod properties of data bound controls are used to specify the respective method. You can also make use of Data Annotations for performing validations on the data being entered. Thus the new model binding features provide a more flexible and powerful approach to data binding.



European ASP.NET 4.5 Hosting - Amsterdam :: Working with Asynchronous Operations in ASP.NET 4.5 Web Forms

clock September 4, 2012 06:52 by author Scott

Introduction

Asynchronously running code can improve the overall performance and responsiveness of your web application. In ASP.NET 4.5 web forms applications you can register asynchronous methods with the page framework. The ASP.NET page framework and .NET 4.5 asynchronous programming support then executes the operations in asynchronous fashion. This article shows how this can be done.

Example Scenario

Consider that you have a web application that needs to call two ASP.NET Web API services namely Customer and Product. These services return Customer and Product data from the Northwind database respectively. Now, assume that each of these services take 5 seconds to complete the data retrieval operation. If you use synchronous mode for calling these services then the total time taken will be 10 seconds. Because the execution will happen sequentially - first Customer service will complete and then Product service will complete.

On the other hand if you invoke these services in asynchronous fashion, the service operations won't block the caller thread. The Customer service will be invoked and control will be immediately returned to the caller. The caller thread will then proceed to invoke the Product service. So, two operations will be invoked in parallel. In this case the total time taken for completing both of the operations will be the time taken by the longest of the operations (5 seconds in this case).

Async, Await, Task and RegisterAsyncTask

Before developing web forms applications that execute asynchronous operations you need to understand a few basic terms involved in the process.

A task is an operation that is to be executed in asynchronous fashion. Such an operation is programmatically represented by the Task class from System.Threading.Tasks namespace.

When an asynchronous operation begins, the caller thread can continue its work further. However, the caller thread must wait at some point of time for the asynchronous operation to complete. The await keyword invokes an asynchronous operation and waits for it to complete.

The async modifier is applied to a method that is to be invoked asynchronously. Such an asynchronous method typically returns a Task object and has at least one await call inside it.

Just to understand how async, await and task are used at code level, consider the following piece of code:

public async Task<MyObject> MyMethodAsync()
{
  MyObject data = await service.GetDataAsync();
  //other operations on data go here
  return data;
}

Here, method MyMethodAsync() is marked with async modifier. By convention, asynchronous method names end with "Async". The MyMethodAsync() returns MyObject wrapped inside a Task instance. Inside the method a remote service is invoked using GetDataAsync(). Since MyMethodAsync() needs to return data retrieved from the service, the await keyword is used to wait till the GetDataAsync() method returns. Once GetDataAsync() returns the execution is resumed and further code is executed. The data is finally returned to the caller.

NOTE:
For a detailed understanding of async, await and Task refer to MSDN dicumentation. Here, these terms are discussed only for giving a basic understanding of the respective keywords.

ASP.NET page framework provides a method - RegisterAsyncTask() - that registers an asynchronous task with the page framework. Tasks registered using the RegisterAsyncTask() method are invoked immediately after the PreRender event. The RegisterAsyncTask() method takes a parameter of type PageAsyncTask. The PageAsyncTask object wraps the information about an asynchronous task registered with a page. The following piece of code shows how they are used:

protected void Page_Load(object sender, EventArgs e)
{
   PageAsyncTask task = new PageAsyncTask(MyMethod);
   RegisterAsyncTask(task);
}


Asynchronous Solution


Now that you are familiar with the basic concepts involved in utilizing asynchronous operations in a web forms application, let's create a sample application that puts this knowledge to use.


Begin by creating two projects - an empty web forms application and an ASP.NET MVC4 Web API application.


Add an Entity Framework Data Model for the Customers and Products tables of the Northwind database. Place the EF data model inside the Models folder.




Add an Entity Framework Data Model for the Customers and Products tables


Add two ApiController classes to the Web API project and name them as CustomerController and ProductController.




Add two ApiController classes


Then add Get() methods to both the ApiController classes as shown below:


public class CustomerController : ApiController
{
    public IEnumerable<Customer> Get()
    {
        Northwind db = new Northwind();
        var data = from item in db.Customers
                    select item;
        System.Threading.Thread.Sleep(5000);
        return data;
    }

}
public class ProductController : ApiController
{
    public IEnumerable<Product> Get()
    {
        Northwind db = new Northwind();
        var data = from item in db.Products
                    select item;
        System.Threading.Thread.Sleep(5000);
        return data;
    }

}


The Get() method of the CustomerController class selects all the Customer records from the Customers table whereas the Get() method of the ProductController class selects all the Product records. For the sake of testing, a delay of 5 seconds is introduced in each Get() method. The Get() methods return an IEnumerable collection of Customer and Product objects respectively.


Now, go to the web forms project and open the code behind file of the default web form. Here, you will write a couple of private methods that invoke the Web API developed previously. These methods are shown below:

public async Task<List<Customer>> InvokeCustomerService()
{
    using (HttpClient client = new HttpClient())
    {
        HttpResponseMessage response = await client.GetAsync("http://localhost
        string json= (await response.Content.ReadAsStringAsync());
        List<Customer> data = JsonConvert.DeserializeObject<List<Customer>>(json
        return data;
    }
}

public async Task<List<Product>> InvokeProductService()
{
    using (HttpClient client = new HttpClient())
    {
        HttpResponseMessage response = await client.GetAsync("http://localhost
        string json = (await response.Content.ReadAsStringAsync());
        List<Product> data = JsonConvert.DeserializeObject<List<Product>>(json
        return data;
    }
}

The InvokeCustomerService() method invokes the Customer Web API whereas InvokeProductService() method invokes Product Web API. Both the methods essentially use an HttpClient to get data from the respective Web API. Notice that both the methods have async modifier and return a Task instance that wraps the actual return type (List<Customer> and List<Product> respectively). The GetAsync() method of the HttpClient object is an asynchronous method. Call to the GetAsync() is marked using the await keyword so that further statements are executed only when GetAsync() returns. The GetAsync() method accepts a URL of the respective Web API. Make sure to change the port number as per your development setup. The GetAsync() method returns an HttpResponseMessage object. The actual data is then retrieved using ReadAsStringAsync() method of the Content property. The ReadAsStringAsync() will return data as a JSON string. This JSON data is converted into a .NET generic List using DeserializeObject() method of the JsonConvert class. The JsonConvert class comes from the Json.NET open source componenet. You can download Json.NET here.

The InvokeCustomerService() and InvokeProductService() methods are called inside another private method GetDataFromServicesAsync() as shown below:

private async Task GetDataFromServicesAsync()
{
    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();

    var task1 = InvokeCustomerService();
    var task2 = InvokeProductService();

    await Task.WhenAll(task1, task2);

    List<Customer> data1 = task1.Result;
    List<Product> data2 = task2.Result;

    stopWatch.Stop();
    Label2.Text = string.Format("<h2>Retrieved {0} customers and {1} products
                                 data1.Count, data2.Count, stopWatch.Elapsed.TotalSeconds
}


As shown above, GetDataFromServicesAsync() is also marked as async and returns a Task instance. Inside, a StopWatch class from System.Diagnostics namespace is used to find the time taken by both of the operations to complete. InvokeCustomerService() and InvokeProductService() methods are then called. The returned Task instance is stored in task1 and task2 variables respectively. The WhenAll() method of Task class creates another Task that completes when all the specified tasks are complete. In this case it creates a Task that completes after complition of task1 and task2. Actual data returned by the respective Web API is retrieved using the Result property of the respective Task objects. The time taken to complete the operation is measured by the StopWatch and is displayed in a Label.

The next step is to register GetDataFromServicesAsync() with the page framework. This is done using the RegisterAsyncTask() method as shown below:


protected void Page_Load(object sender, EventArgs e)
{
    RegisterAsyncTask(new PageAsyncTask(GetDataFromServicesAsync));
}


As you can see, Page_Load event handler registers an asynchronous task using RegisterAsyncTask() method. The RegisterAsyncTask() method accepts an instance of PageAsyncTask. The PageAsyncTask instance in turn wraps the GetDataFromServicesAsync() method created earlier.


The final step is to set Async attribute of the @Page directive to true:


<%@
Page Async="true" Language="C#" CodeBehind="WebForm1.aspx.cs" ... %>

The Aync attribute of the @Page directive indicates that this web form will be executed in asynchronous fashion. Web forms that use RegisterAsyncTask() method must set the Async attribute to true, otherwise an exception is raised at runtime.

This completes the application and you can test it by running the web forms application. The following figure shows a sample run of the web form:




A sample run of the web form


Though the code doesn't show the synchronous execution of the Web API operations, for the sake of better understanding the above figure shows time taken for synchronous as well as asynchronous execution. Recollect that both the Get() methods sleep for 5 seconds and hence the synchronous execution takes approximately 10 seconds. However, the asynchronous execution takes approximately 5 seconds. As you can see the asynchronous operation improves the overall performance of the application.


Summary

Using async and await keywords you can create operations that run asynchronously. Such asynchronous tasks can be registered with the page framework using RegisterAsyncTask() method. Registered tasks run immediately after the PreRender event of the web form. Asynchronous operations can improve the overall performance and user responsiveness of a web application.



European ASP.NET 4.5 Hosting - Amsterdam :: Writing asynchronous HTTP Module in ASP.NET 4.5

clock August 13, 2012 09:00 by author Scott

In this article, I will show you new features in ASP.NET 4.5, Asynchronous HTTP Module.

First Just to give a brief Idea, why Asynchronous HTTPModules are important ?


As we all know, web is stateless. A Web page is created from scratch every time whenever it is posted back to the server. In traditional web programming, all the information within the page and control gets wiped off on every postback. Every request in ASP.NET goes through a series of events.


Every request is served by am HTTP handler and it goes a series of HTTPModules (HTTPPipeline) which can be read, update the request. A lot of features of ASP.NET like Authentication, Authorization, Session etc are implemented as HTTP Module in ASP.NET. Let’s have a view on the Request Processing




Now as you can see the request is assigned to a thread T1 from the available threads is thread pool. And the request is passed through several HTTPModules and finally served my HTTPHandler and response is send back with the same thread (T1).


During the entire processing, same thread is engaged in serving the same request and cannot be used by any another request till request processing completes. During the request processing if any HTTPModules depends on some entities like I/O based operations, web services, Databases queries etc then it takes long to complete which makes the thread busy for long which makes asp.net thread will not do anything during that duration and will be useless. In this kind of scenarios the throughput goes down rapidly.


In the above scenario, synchronous HTTPModule can degrade the site performance a lot. So if we can make HTTPModules as asynchronous that can increase the through put a lot. In asynchronous mode, ASP.NET thread get released as soon as the control get passed to another component/module, it does not wait. And the thread becomes available in thread pool and can be used to serve another request. When the component completes its assigned task then it got assigned to new ASP.NET thread which completes the request. The flow can be graphically presented as




In the above picture, An asp.net thread T1 is assigned from threadpool to server the request. When the control got passed to File System to log message, asp.net thread got released and when essage logging got completed, control passed to asp.net and it is assigned to another thread say T2 from thread pool.

In .NET Framework 4.o, there was some major enhancement made for asynchronous programming model. Any asynchronous operation is represents a Task and it comes under the namespace System.Threading.Tasks.Task.

In .NET 4.5, there are some new operator and keyword introduced that makes the life easy for implement Asynchronous feature. One is async keyword and await operator.


These two enables us to write the asynchronous code is similar fashion as we write for synchronous mode.


And these features can be easily used while writing HTTPModules and HTTPHandlers. We’ll be using these enhancements in writing our custom asynchronous HTTPModule.


In my sample as depicted in image, I am creating a module that writes some log messages in a text file for every request made.


So to create a Custom
HTTPModule, Create a class library project. And create a class say named LogModule which implements IHttpModule. For this you need to add a reference of Assembly System.Web.

LogModule
would contains the methods discussed below.

We need to implement two methods Init and Dispose that are part of
IHTTPModule interface.

Here first , I have written an asynchronous method that actually reads the information from the request and writes in the log file asynchronously . For this I have used
WriteAsync of FileStream

private async Task WriteLogmessages(object sender, EventArgs e)
{
    HttpApplication app = (HttpApplication)sender;
        DateTime time = DateTime.Now;

        string line = String.Format(
        "{0,10:d}    {1,11:T}    {2, 32}   {3}\r\n",
        time, time,
        app.Request.UserHostAddress,
        app.Request.Url);
        using (_file = new FileStream(
            HttpContext.Current.Server.MapPath(
              "~/App_Data/RequestLog.txt"),
            FileMode.OpenOrCreate, FileAccess.Write,
            FileShare.Write, 1024, true))
        {
            line = line + "  ," + threaddetails;
            byte[] output = Encoding.ASCII.GetBytes(line);

            _file.Seek(_position, SeekOrigin.Begin);
            _position += output.Length;
            await _file.WriteAsync(output, 0, output.Length);
        }

}

Here you can see the await key word, what it means..


As per msdn “An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.“

await is used with some asynchronous method that returns task and is used suspend the execution of the method until the task completes and control is returned back to the caller to execute further. await should be used with the last expression of any code block.

And Init method would be like

public void Init(HttpApplication context)

{

        // It wraps the Task-based method
        EventHandlerTaskAsyncHelper asyncHelper =
           new EventHandlerTaskAsyncHelper(WriteLogmessages);

        //asyncHelper's BeginEventHandler and EndEventHandler eventhandler that is used
        //as Begin and End methods for Asynchronous HTTP modules
        context.AddOnPostAuthorizeRequestAsync(
        asyncHelper.BeginEventHandler, asyncHelper.EndEventHandler);

}

So apart from above these methods, we need to implement the dispose method.

Now compile your class library and use the reference in your ASP.NET website . Now as you must be knowing that we need to need to add the entry in the config file. So it’ll be as

<system.webServer>

<modules>
<add name="MyCustomHTTPModule" type="MyCustomHTTPModule.LogModule, MyCustomHTTPModule"/>
</modules>
</system.webServer>

Now when you run your application, you will see the logs are created in a text file in App_Data folder as mentioned path in the code.

Hope you all have liked this new feature.

 

 



European ASP.NET 4.5 Hosting - Amsterdam :: Custom Caching Provider in ASP.NET 4.0/4.5

clock August 6, 2012 06:54 by author Scott

In this article I am trying to explain Custom Caching Provider in ASP.NET 4.0 or 4.5. I have created a sample in Visual Studio 2011.

Purpose

Caching enables you to store data in memory for rapid access. When the data is accessed again, applications can get the data from the cache instead of retrieving it from the original source. This can improve performance and scalability. In addition, caching makes data available when the data source is temporarily unavailable.


Code:

Step 1
: Create two new projects; one is Web Application and the other is Class Library.

Step 2
: Now open the Class Library project and add a reference for System.Web assembly.

Step 3
: Now inherit your class from OutputCacheProvider Class.

Step 4
: Now override all Add, Get, Set and Remove Methods.

Here is sample Code.

public class FileCacheProvider : OutputCacheProvider

    {
        private string _filecachePath;

        public string FilecachePath
        {
            get
            {
                if (!string.IsNullOrEmpty(_filecachePath))
                    return _filecachePath;
                _filecachePath = System.Configuration.ConfigurationManager.AppSettings["OutputCachePath"];

                var context = HttpContext.Current;

                if (context != null)
                {
                    _filecachePath = context.Server.MapPath(_filecachePath);
                    if (!_filecachePath.EndsWith("\\"))
                        _filecachePath += "\\";
                }

                return _filecachePath;
            }
        }
        public override object Add(string key, object entry, DateTime utcExpiry)
        {
            Debug.WriteLine("Cache.Add(" + key + ", " + entry + ", " + utcExpiry + ")");

            var path = GetPathFromKey(key);

            if (File.Exists(path))
                return entry;

            using (var file = File.OpenWrite(path))
            {
                var item = new CacheItem { Expires = utcExpiry, Item = entry };
                var formatter = new BinaryFormatter();
                formatter.Serialize(file, item);
            }

            return entry;
        }
        public override object Get(string key)
        {
            Debug.WriteLine("Cache.Get(" + key + ")");
 
            var path = GetPathFromKey(key);

            if (!File.Exists(path))
                return null;

            CacheItem item = null;

            using (var file = File.OpenRead(path))
            {
                var formatter = new BinaryFormatter();
                item = (CacheItem)formatter.Deserialize(file);
            }

            if (item == null || item.Expires <= DateTime.Now.ToUniversalTime())
            {
                Remove(key);
                return null;
            }

             return item.Item;
        }
        public override void Remove(string key)
        {
            Debug.WriteLine("Cache.Remove(" + key + ")");

            var path = GetPathFromKey(key);

            if (File.Exists(path))
                File.Delete(path);
        }

        public override void Set(string key, object entry, DateTime utcExpiry)
        {
            Debug.WriteLine("Cache.Set(" + key + ", " + entry + ", " + utcExpiry + ")");

            var item = new CacheItem { Expires = utcExpiry, Item = entry };
            var path = GetPathFromKey(key);

            using (var file = File.OpenWrite(path))
            {
                var formatter = new BinaryFormatter();
                formatter.Serialize(file, item);
            }
        }
        private string GetPathFromKey(string key)
        {
            return FilecachePath + MD5(key) + ".txt";
        }

        private string MD5(string s)
        {
            var provider = new MD5CryptoServiceProvider();
            var bytes = Encoding.UTF8.GetBytes(s);
            var builder = new StringBuilder();

            bytes = provider.ComputeHash(bytes);

            foreach (var b in bytes)
                builder.Append(b.ToString("x2").ToLower());

            return builder.ToString();
        }
    }

Step 5
: Now add the class library project reference to your web application and add the following attribute to your web.config file:

  <caching>
      <outputCache defaultProvider="FileCacheProvider">
        <providers>
         <add name="FileCacheProvider" type="CustomCacheProviderLib4_5.FileCacheProvider"/>
        </providers>
      </outputCache>
    </caching>

Step 6: Now add an OutputCache Directive to your page (Default.aspx).

<%@ OutputCache VaryByParam="ID" Duration="300" %>

Step 7: Now run your web application and see that your page is loading from the Cache:



Step 8
: Here is the output window:



European ASP.NET 4.5 Hosting - Amsterdam :: Websockets with ASP.net 4.5 and Visual Studio 11

clock July 25, 2012 08:31 by author Scott

Web applications are becoming increasingly sophisticated and it is common to need to communicate with various services.

There are a number of options to accomplish this task with probably the most popular being to continually poll a server with XHR requests. Other alternatives exist that delay disconnections. These can be tricky to implement and don’t scale well (sometimes worse than polling as they keep a connection open) so aren’t used as much.


HTTP isn’t really an ideal protocol for performing frequent requests as:


- It’s not optimized for speed

- It utilizes a lot of bandwidth for every request with various headers etc sent with every request
- To keep an application up to date many requests must be sent
- Provides limited cross domain support (relying on workarounds such as JSONP http://remysharp.com/2007/10/08/what-is-jsonp/)
- Firewalls & proxys sometimes buffer streaming/long polling solutions increasing latency
- Long polling & streaming solutions are not very scalable

WebSockets are a new technology that attempts to resolve some of these limitations by:


- Sending the minimum amount of data necessary

- Making more efficient usage of bandwidth
- Providing cross domain support
- Still operating over HTTP so it can transverse firewalls and proxies
- Works with some load balancers (TCP l4)
- Provides support for binary data (note some JavaScript implementations don’t currently support this)

When would web sockets be a suitable protocol for your application?


You might want to consider using web sockets in the following scenarios:


- Games

- Real time data
- Chat applications
- News tickers

There is a nice set of demos at: http://www.html5rocks.com/en/tutorials/websockets/basics/ and an interesting article that compares a Web Sockets and polling solution in terms of latency & throughput at http://websocket.org/quantum.html.


Websockets pitfalls


Websockets is a relatively new protocol that has already undergone a number of versions as various issues are addressed. This is important as support across browsers varies.


At the time of writing Websockets (in some form) can be used by the following browsers (check caniuse.com for the most up to date info):


- IE10

- Chrome 13+
- Firefox 7
- Safari 5+
- Opera 11+

Earlier implementations of websockets had some security issues so your connections may work but are not secure (Firefox disabled support in Firefox 4 & 5 for this reason).


The other issue that you may encounter is that some older proxy servers don’t support the http upgrade system that websockets uses to connect so some clients may be unable to connect.


.net 4.5 Web Socket Support

.net 4.5 introduces a number of APIs for working with web sockets. If you find you need more control than the ASP.net API’s offers then look into WCF as that has also been updated.


Before we begin there are a couple of requirements for using ASP.net web sockets API:

-
Application must be hosted on IIS 8 (available only with some version of Windows 8 – please note currently IIS Express currently does not work)
-
Web Sockets protocol feature installed (IIS option)
-
.net 4.5
-
A compatible browser on the client (IE10 or Chrome will 18 work fine at time of writing)
-
It would help if your Chinese birth animal was the horse

Currently Microsoft have no plans to release Websockets support for earlier versions of IIS so if you plan to run it on Windows Server 2008 then you are going to have to look at other options such as http://superwebsocket.codeplex.com/.

You could also look at the SignalR library from Microsoft which is designed for developing async applications and provides WebSockets (and fallback) support: https://github.com/SignalR/SignalR/wiki/WebSockets.

Hello Web Sockets Example!

Ok I am going to assume that you are already working with some version of Windows 8 that has IIS & ASP.net 4.5 installed. The other thing we are going to need to do is make sure IIS has the Web Sockets Protocol feature installed (this is in the add/remove programs bit):

First create a new empty ASP.net project called WebSockets

Add the Nuget package Microsoft.Websockets

Pull down the latest jQuery library and put it in a scripts directory (I am using 1.7.2) – note jQuery isn’t necessary it just saves a bit of tedious event and manipulation code.

Now add a file called index.htm and enter the following code:

<!doctype html>

<head>

<script src="Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>

<script type="text/javascript">

$(document).ready(function () {

var name = prompt('what is your name?:');

var url = 'ws://' + window.location.hostname + window.location.pathname.replace('index.htm', 'ws.ashx') + '?name=' + name;

alert('Connecting to: ' + url);

ws = new WebSocket(url);

ws.onopen = function () {

$('#messages').prepend('Connected <br/>');

$('#cmdSend').click(function () {

ws.send($('#txtMessage').val());

$('#txtMessage').val('');

});

};

ws.onmessage = function (e) {

$('#chatMessages').prepend(e.data + '<br/>');

};

$('#cmdLeave').click(function () {

ws.close();

});

ws.onclose = function () {

$('#chatMessages').prepend('Closed <br/>');

};

ws.onerror = function (e) {

$('#chatMessages').prepend('Oops something went wront <br/>');

};

});

</script>

</head>

<body>

<input id="txtMessage" />

<input id="cmdSend" type="button" value="Send" />

<input id="cmdLeave" type="button" value="Leave" />

<br />

<div id="chatMessages" />

</body>

</html>

We need to create an http handler so add a new generic handler to the project called ws.ashx and enter the following code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using Microsoft.Web.WebSockets;

namespace WebSockets

{

public class WSHttpHandler : IHttpHandler

{

public void ProcessRequest(HttpContext context)

{

if (context.IsWebSocketRequest)

context.AcceptWebSocketRequest(new TestWebSocketHandler());

}

public bool IsReusable

{

get

{

return false;

}

}

}

}

Finally we need to create something to handle the websocket connection (TestWebSocketHandler that is created in the AcceptWebSocketRequest method).

Create a new class called TestWebSocketHandler and enter the following code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading;

using System.Web;

using Microsoft.Web.WebSockets;

namespace WebSockets

{

public class TestWebSocketHandler : WebSocketHandler

{

private static WebSocketCollection clients = new WebSocketCollection();

private string name;

public override void OnOpen()

{

this.name = this.WebSocketContext.QueryString["name"];

clients.Add(this);

clients.Broadcast(name + " has connected.");

}

public override void OnMessage(string message)

{

clients.Broadcast(string.Format("{0} said: {1}", name, message));

}

public override void OnClose()

{

clients.Remove(this);

clients.Broadcast(string.Format("{0} has gone away.", name));

}

}

}


That’s all you need so now compile the project and run it in a compatible browser (IE10 or the latest Chrome will do fine) making sure you are hosting your project from IIS (project properties if you are not).


Once you have run it up you will be prompted to provide a name, then an alert box will indicate the end point of your application (ws://localhost/.. – note the secure https version is wss://).


Now open up a different browser and you should find you can via websockets!



European ASP.NET 4.5 Hosting - Amsterdam :: Request Validation with ASP.NET 4.5

clock July 16, 2012 07:16 by author Scott

Security is always the one of the greatest concerns of Applications and when it comes to web applications, they are more prone to security breach. All the web technologies provides many features that are used to write secured web applications.

Here In this post, I am going to discuss Request Validation feature, mainly focusing ASP.NET 4.5 version.


Request validation introduced since ASP.NET 1.1 is available. By default it is enabled and it prevents to accept un-encoded HTML/XML etc from Client to server. It validates all the data that is passed from client to server. It can be any form like


- Cookies

- Form Collection
- Querystring
- Server variables

This helps to avoid script injection attacks. So it is always recommended to validate all the data that is passed from client to server because it can be malicious code and can be harmful the application.


Although, if we are sure that this situation would not arise, it can be disabled at application level or page level so no request will get validated. But this is not the case every time. On some occasions, we may need to allow users to enter some html, xml etc.. data . In this case, we need to partially validate the request.


There are several scenarios where we need to turn off the request validation just because of some specific data we don’t need to get validated. It leads us to write less secure code because we are the whole request goes to unvalidated. There are scenarios like in blog sites where we normally allow the user to write html , xml etc as input


Till ASP.NET 4.0, we have option to disable the request validation in the entire application or can be done page by page. But till now we did not have option to partially validate the page. ASP.NET 4.5 enables us to validate some specific part of the request.


ASP.NET 4.5 provides us two features.


1. Selectively un-validate the request

2. Deferred or lazy validation

How to allow partially unvalidated request in asp.net 4.5

I have created a sample application and have two textboxes – txtValidate and txtunValidate, with a submit button.

Let’s have a use case that I want to validate txtValidate but not txtunValidate. You must remember that this was not possible with earlier version of ASP.NET.I’ll also discuss it in detail later. To use this feature , you must set requestValidationMode as 4.5 in web.config like

<httpruntime requestvalidationmode="4.5" />

Apart from this, ASP.NET 4.5 added one more property ValidateRequestMode with input controls. And it can have the following values


- Enabled: Request validation is enabled for the control. Bydefault it is enabled

- Disabled: Input values for this control would not be validated
- Inherit: Property value will be inherited from parent

So let’s proceed with sample, and as I don’t want to validate txtunValidate so I need to set ValidateRequestMode attribute as disabled like




Now Let’s run the code.



And as you can see I’ve put some script tag in txtunValidate and it worked fine. But let us remove the
requestValidationMode from web.config and try to submit the same input again.



and see it gave the
HttpRequestValidationException exception and got the above screen. Now lets again put the attribute requestValidationMode in web.config and try to put some script in txtValidate and submit. It’ll show you the same exception again as expected. So here you can see, ASP.NET 4.5 enables us to selectively validate the request.

Deferred or lazy validation

This is also introduced in asp.net 4.5 and I’ll say that above feature is just a corollary of this feature.


To provide these features, Microsoft has done some major changes in the way Request Validation feature got implemented in earlier version of ASP.NET. As we know, to process a request, ASP.NET creates an instance of HTTPContext which holds the instance of HTTPRequest and HTTPResponse with other required data. All the input data that is passed from client to server, it is posted in form collection, querystring etc.. ASP.NET validates every data that is passed from client to server.

Actually in ASP.NET 4.5, whenever the data is accessed from the request it gets validated. Like when we access the form collection to some input as Request.Form[uniqueId] the validation triggers. To provide selective validation, Microsoft has introduced a new collection property named as Unvalidated in the HTTPRequest class. This contains all the data that is passed from client to server like cookies, form collection, querystring etc as



Now the same data is available at two places. In
UnValidated collection and normal in HTTPRequest. When we set the ValidateRequestMode is disabled, the data is accessed from UnValidated collection else normal request. UnValidated collection don’t trigger any validation while other one triggers. I’ll show you a demo later.

In earlier version of ASP.NET 1.1/2.0/3.5, Request validation is done at earlier level of page processing. There were also some good amount of changes took place in ASP.NET 4.0, which provides us the feature to validate the non-ASP.NET resources as well which was not available earlier.


Under the hood


I have the same application and I have removed the
requestValidationMode attribute from web.config and putting some html tags as I did above example and pressed submit. So I got the HttpRequestValidationException as



Now let’s put the
requestValidationMode as 4.5 and try the same as above. I have removed the disable attribute. Again I got the same exception as below



But if we examine the circled part of the stacktrace, we can easily Identify that in 4.5, the validation exception got thrown from TextBox’s
LoadPostData method.

Please check study case below


Case Study 1

As we all know the ASP.NET Page LifeCycle as




As you can see, here
LoadPostData is a part of PageLife Cycle and comes after LoadViewState. All of the Input control’s data don’t get wiped off during postback even if viewstate is not enabled for that control.

So this is the
LoadPostData method that is responsible to get the data from Form collection and assign it to the control. As I said, Now asp.net 4.5, validates the input only when you access the data from form collection. That’s why if you look the stacktrace then it is visible that the exception is thrown from LoadPostData method only and page life cycle is the last stage of ASP.NET Request Processing.

Now lets try to have an clarification using a demo. As I mentioned, in ASP.NET 4.5, the validation triggers only when the data is accessed and the data is accessed at
LoadPostData for input controls. So lets create a custom textbox. For this I’ll override LoadPostData method and will do nothing in that. It means that the data would not be accessed for the customTextBox at LoadPostData. So even if the ValidationMode is enabled for the CustomtextBox, it wont be fired. Lets see this

I have created a
CustomtestBox and overridden the LoadPostData method as

public class CustomTextBox : System.Web.UI.WebControls.TextBox
 {
     protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
     {
          return false;
     }
 }


You can see, I have just returned false in the
LoadPostData method. Now I have used my CustomTextBox at my aspx page as



Now set the
requestValidationMode as 4.5 in web.config and enter some script tag and submit.

You would not get any error even
RequestValidation is enabled. This proves the validation fires only when data is accessed from the form collection.

Case Study 2

Here I’ll also try to prove the same as above. I have already shown above that How the new
UnValidated property of Context holds all the data including form collection, querystring, cookies etc. So whenever the data is accessed from the UnValidated collection, the validation is not fired. But when it is accessed from the normal form collection, validation gets fired.

So here I am going to use again the earlier sample. In that example I had two textboxes and a submit button. Here the change is that at server side, instead of accessing the data form txtValidate.Text, I’ll be accessing the data from FormCollection. So I’ll set the the ValidateRequestMode as disabled for both the textbox and will try to get the data one will be form normal Form Collection and another is from Unvalidated’s form collection as

protected void Button1_Click(object sender, EventArgs e)
 {
     string textValidated = this.Context.Request.Unvalidated.Form[txtValidate.UniqueID];
     string textUnValidated = this.Context.Request.Form[txtunValidate.UniqueID];
 }


Now lets enter some html tags in both the textboxes and submit the page using debugger as




Oh!! see even we have disabled the validation, even in that situation when data is accessed from normal Form collection the validation is fired.


This again proves the validation is fired only when the data is acessed and when the
ValidateRequestMode is set as disabled it is accessed from the UnValidated property



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in