RSS

Tag Archives: ASP.NET

MVC 4 Code Enhancements

Here are 2 minor nice enhancements for MVC 4.

Conditional Attribute Enhancements
This enhancement is something I really like. If you are accustomed to write server-side code embedded with HTML, you probably ran into ugly spaghetti code like this:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    @{
        string css = "myDiv";
    }
    <div class='@{ if (css != null) {<text>@css</text>} }'></div>
</body>
</html>

In MVC 4, one enhancement allows you to save quite a lot of spaghetti confusing code, by interpreting the Code Nugget for you, like so:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    @{
        string css = "myDiv";
    }
    <div class='@css'></div>
</body>
</html>

Even more, you can really shorten things by inserting lengthy strings and render less HTML:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    @{
        string css = "class=myDiv";
    }
    <div @css></div>
</body>
</html>

Note that if you would have used apostrophes, they would have been HTML encoded. So this:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    @{
        string css = "class='myDiv'";
    }
    <div @css></div>
</body>
</html>

is rendered like this:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
 <div class=&#39;myDiv&#39;></div>
</body>
</html>

If you would like to avoid encoding, just use Html.Raw( ) as usual:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    @{
        var css = @Html.Raw("class='myDiv'");
    }
    <div @css></div>
</body>
</html>

Note that Html.Raw returns an IHtmlString, and this works just as well. It seems like the Code Nugget simply performs a ToString( ) with HTML encoding on the given variable. This can be tested easily. Consider this code:

using System.Web.Mvc;

namespace MVCEnhancements.Controllers
{
    public class MyModel
    {
        public override string ToString()
        {
            return "t'is my code";
        }
    }
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View(new MyModel());
        }
    }
}

and the corresponding cshtml (note the @Model in line 9):

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    @{
        var css = @Html.Raw("class='myDiv'");
    }
    <div @css>@Model</div>
</body>
</html>

This renders the following:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div class=&#39;myDiv&#39;>t&#39;is my code</div>
</body>
</html>

As you can well see, ToString( ) was called and it was also Html Encoded.

URL Resolution Enhancements
Instead of using Url.Content with a tilde,

<!DOCTYPE html>
<html>
<head>
    <script src='@Url.Content("~/Scripts/jquery-1.6.2.js")'></script>
</head>
<body>
    <div>
    </div>
</body>
</html>

You can just use the tilde like so:

<!DOCTYPE html>
<html>
<head>
    <script src='~/Scripts/jquery-1.6.2.js'></script>
</head>
<body>
    <div>
    </div>
</body>
</html>
 
2 Comments

Posted by on 20/05/2012 in Software Development

 

Tags: , ,

Long Poll Sally – ASP.NET MVC AsyncController

Just like the rest of us, I use polling occasionally. When I learned of WebSockets, I came across my reading about a term I wasn’t acquainted with: Long Polling (or “Comet“). It can be viewed schematically here. To put it simply, while polling can be explained as a series or recurring requests to the server for updates, Long Polling is more or less the same, only technically, the client opens a request to the server, but the server doesn’t return an immediate response and keeps the connection open. When the server has a response, it will use that open connection to notify the client. The client then has to perform another request to reopen a connection for the next update.

At first, when I realized what Long Polling is, I didn’t like the idea much. I mean, if you end up reopening a request to the server like regular polling, why bother? This comes in handy only for less-frequent notifications from the server side, otherwise its just like Polling. Besides, with the new WebSockets in place – who needs it? But then I did some more reading and decided that it might come in handy after all. The main problem I see for using WebSockets is IE9. The major browsers (Chrome, Firefox and the soon to be released IE10) support WebSockets. Cool. But IE9 does not support it. “Fine” you say, have your users upgrade their browsers to IE10. Ahhhh, but MS has decided to limit IE10 to Windows 7 or above. MS is taking several steps to force us to upgrade to their latest releases: No IE10 for Vista, just like WebSockets isn’t planned for IIS7. Funny enough, Google’s Chrome supports XP and Firefox is also compatible with older Windows (in fact, a short visit to Wikipedia reveals that: “Windows XP SP2, XP SP3 and above is now the minimum requirement for Firefox 13.0 and above”…) I find it quite amazing, that MS’ latest browsers cannot be installed on their own operating systems, while their biggest competitors can. It’s as if Microsoft believes that users will upgrade to their latest operating systems just to get their better browser, when they have major competition which is compatible with legacy Windows. Gregg Keizer rightfully points to an anonymous comment on IE’s blog: “IE9 is the new IE6.” Microsoft is working so hard on renewing IE and kicking out IE6, but it performs such a strategic mistake by leaving IE8 and IE9 for a long long time.

Anyway, that’s a major issue as far as I’m concerned. IE6 to IE9 will probably remain with us for quite sometime, as many users still use Windows XP or Vista. All of these users will not enjoy WebSockets support, and we developers will have to continue to develop alternatives to MS’ browser policy of not allowing their own users to upgrade. I guess that this more or less explains why Polling and Long Polling are still relevant: we simply can’t rely on WebSockets alone in the upcoming years.

“Hello World”

Following several blog posts, especially this one by Clay Lenhart, I ended up with the following “Hello World”-like example. Here is the client. It’s fairly simple and self explanatory:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Simple</title>
</head>
<body>
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"></script>
    <script type="text/javascript">
        $(function () {
            openConnection();
        });

        function openConnection() {
            $.post("@Url.Action("Simple", "MyAsync")", function (results) {
                if (results.Data) {
                    $('#log').text(results.Data);
                }

                openConnection();
            });
        }
    </script>
    <div id='log'>
    </div>
</body>
</html>

Here is the server side (explanation below):

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace LongPolling.Controllers
{
    public class MyAsyncController : AsyncController
    {
        public void SimpleAsync()
        {
            AsyncManager.OutstandingOperations.Increment();

            Task.Factory.StartNew(() =>
            {
                Thread.Sleep(TimeSpan.FromSeconds(10));
                AsyncManager.Parameters["contents"] = DateTime.Now.TimeOfDay.ToString();
                AsyncManager.OutstandingOperations.Decrement();
            });
        }

        public JsonResult SimpleCompleted(string contents)
        {
            return Json(new { Data = contents });
        }
    }
}

The server code works similarly to the Web Services Async pattern: There is a ‘Begin’ (SimpleAsync), and an ‘End’ (SimpleCompleted). Here is what we see here:

  • Line 8: A would-be async controller must derive from AsyncController. This is what gives us the AsyncManager property through which we accomplish async behavior in MVC.
  • Line 10 is where the async begins. Note, that while the client called the “Simple” Action, our method is called SimpleAsync. In Line 22 you will find it’s counterpart callback method which will be called upon completion (“complete” callback).
  • Lines 12 & 18 are completing operations: In line 12 you announce how many “outstanding operations” you have, which is simply a counter you set at the start of the async operation. When the async operation ends you decrement this counter. When the counter reaches zero, the “completed” callback is called and the response returns to the client. This resembles a C++ reference counter for a smart pointer.
  • Lines 14-19 simulate an async task call. This is where you call time consuming logic, or where you register to receive notifications for two-way communication, simulating WebSockets behavior.
  • Line 17 is how you may pass arguments to the “completed” callback (Line 22).

Here’s a screenshot from IE9 running as IE8:

  1. Response from the server.
  2. Interval of the 10 second requests.
  3. Current pending request.
  4. Browser running in IE8 mode – after all, this is what this effort is all about.

There you have it – quite a simple mechanism to perform async MVC operation, which can evolve into a WebSocket-like operation (see below).

Multiple “outstanding operations”

The OutstandingOperations property which returns an OperationCounter class which is a sort of a reference counter for “pending async operations”. This means that if you have multiple async operations scheduled per a single async request, you may set the counter to the number of those operations, and have each operation decrement the counter when it completes. When the counter reaches zero, the “completed” callback will be returned. Here’s an example:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace LongPolling.Controllers
{
    public class MyAsyncController : AsyncController
    {
        public void MultipleAsync()
        {
            AsyncManager.OutstandingOperations.Increment(3);

            Task.Factory.StartNew(() =>
            {
                Thread.Sleep(1000);
                AsyncManager.Parameters["param1"] = DateTime.Now.ToString();
                AsyncManager.OutstandingOperations.Decrement();
            });

            Task.Factory.StartNew(() =>
            {
                Thread.Sleep(2000);
                AsyncManager.Parameters["param2"] = DateTime.Now.ToString();
                AsyncManager.OutstandingOperations.Decrement();
            });

            Task.Factory.StartNew(() =>
            {
                Thread.Sleep(3000);
                AsyncManager.Parameters["param3"] = DateTime.Now.ToString();
                AsyncManager.OutstandingOperations.Decrement();
            });
        }

        public JsonResult MultipleCompleted(string param1, string param2, string param3)
        {
            return Json(new { Data = string.Format("{0} {1} {2}", param1, param2, param3) });
        }
    }
}
  • Line 12 states that there are three async pending operations to be completed before returning a response.
  • Three new threads simulate those async operations. Each completes in a Decrement being called, to signal an async operation completion (lines 18,25,32). Each also provides a different argument with the result of the pending operation, which will be passed on to the “completed” callback.
  • Line 36: the “completed” callback receives the results of the pending operations and returns a response.

WebSocket-like implementation

UPDATE: Before you dig into this code, you might be interested in SignalR. Turns out that this is a broadcasting solution from guys at MS. It supposed to auto-detect and use WebSockets, Long Polling or whichever technology is available on the client. I have not tried this yet, but it looks very promising. You can see Scott Guthrie talk about this here (1:09:38).

Now it comes down to the “main event”: Implementing a WebSocket like implementation. Instead of opening a WebSocket from the browser to the server for two-way communication, the idea is to open a request which the server will maintain asynchronously but not so much for the purpose of supporting a lengthy operation, as much as to maintain the connection for a future response from some business logic component. Here’s an example for accomplishing this. First, the publisher (i.e. class which publishes business logic events to subscribers):

using System;
using System.Timers;

namespace LongPolling.Controllers
{
    public static class MyPublisher
    {
        public class MyEventArgs : EventArgs
        {
            public string Contents { get; set; }
        }

        public static event EventHandler<MyEventArgs> Notify;

        private static Timer timer;
        static MyPublisher()
        {
            timer = new Timer();
            timer.Interval = 10000;
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timer.AutoReset = false;
            timer.Start();
        }

        static void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                timer.Stop();

                if (Notify != null)
                {
                    Notify(null, new MyEventArgs { Contents = DateTime.Now.ToString() });
                }
            }
            finally
            {
                timer.Start();
            }
        }
    }
}

Not much here to tell. The MyPublisher class simulates receiving notifications from the business logic using a simple timer, that every 10 seconds publishes to subscribers the current DateTime. Next comes the AsyncController:

using System;
using System.Web.Mvc;

namespace LongPolling.Controllers
{
    public class MyAsyncController : AsyncController
    {
        public void LogicAsync()
        {
            AsyncManager.OutstandingOperations.Increment();

            MyPublisher.Notify += MyPublisher_Notify;
        }

        private void MyPublisher_Notify(object sender, MyPublisher.MyEventArgs e)
        {
            MyPublisher.Notify -= MyPublisher_Notify;
            AsyncManager.Parameters["contents"] = e.Contents;
            AsyncManager.OutstandingOperations.Decrement();
        }

        public JsonResult LogicCompleted(string contents)
        {
            return Json(new { Data = contents });
        }
    }
}
  • Line 12: Register to receive an event from the business logic class (“MyPublisher”). MyPublisher will raise an event each time it attempts to notify whatever message to registered clients.
  • Line 15 is the event handler which is raised by MyPublisher. Here we set the argument to be passed to the “completed” callback and decrement the Outstanding Operations reference counter.
  • Line 17 is probably the most important here as it’s the easiest part to forget: we have to release the event handler from MyPublisher, or MyPublisher will keep a reference to our AsyncController instance and it will never be Garbage Collected. In other words: a managed code memory leak. This is just like in Winforms: a form registers with a business class to receive events in order to display a progress bar or some other UI feedback. When you are done you call a Close( ) on that form. You mistakenly believe that because you called Close and don’t see the form anymore – it is disposed of and eligible for Garbage Collection: not remotely. The business class maintains a reference to the form instance and it is not removed at all. After a while, you begin to witness your memory growing more and more although you’re certain that you have cleaned up everything, and you end-up “windebugging” with SOS to detect that leak. In the screenshot below you can see how the event’s invocation list gets populated with just several requests from the same client browser. The event handlers are never released, which cause the MyAsyncController instances generated per request to remain in memory. By issuing a ‘-=’ we unregister correctly from the event, and the invocation list is kept clean.

Regardless of the potential memory leak described above, the major difference in this implementation from the previous sample is conceptual, and not necessarily technological: In the previous sample, the async method was used to start an async operation, which actually opened new threads. When the threads complete, each decrements the reference counter thus signaling the end of the lengthy async operation. The entire process was started as a browser initiative and simply freed ASP.NET’s threads for the time of the lengthy operation. However, in the current example, the browser opened a request for no particular operation but in order to wait for a callback from the server. The server on an entirely different logical class (“MyPublisher”) will decide when and what to return to the client. A server may return different operations, such as “display notification” about a new email, or “redirect to another page” and so forth.

Timeout

Moving on to implementing a WebSocket like behavior, one issue that was bothering is the Timout. It’s one thing to use an async server operation which is due in a reasonable time; it’s another thing when you attempt to implement a WebSocket-like behavior that may time-out due to less-frequent updates. For example, if you would like to implement a chat, updates might be frequent, but if you implement a mechanism which is most of the time idle, and just prompts notifications every now and then to the end user, we could be discussing here relatively long interval updates. Consider Gmail. When you are positioned on an email correspondence, if suddenly you receive an email related to that correspondence – a notification appears informing you that there’s a new message and you may click on “show” or “hide” to proceed. This is a good example for when a website may be open for a lengthy time without any operation, but a server may “push” a message when relevant. Therefore I tried to test whether a Timeout occurs on the client or the server, by a simple Thread.Sleep() to lengthy time intervals on the server side. It seems that an AsyncController (MVC 4) defaults to 45 seconds. After that, the client is expected to receive the following timeout exception:

“System.TimeoutException: The operation has timed out.”

I have no idea why, but settings the Timeout property seems to be completely ignored. For example, setting the Timeout to “infinite” (Timeout.Infinite) or to a simple 60000 ms (and extending the server’s Sleep to a much lengthier operation), returned a Timeout exception after 45 seconds. Luckily, I read here that you could set a NoAsyncTimeoutAttribute on the async method to state that there should not be a timeout, and in fact – this actually works (viewing the Timeout property in a debug watch shows -1, which is the value of Timeout.Infinite, but it actually works.)

Now that I have server Timeout set to infinite, I tested different clients’ behavior. On Chrome and Firefox – the browsers did not timeout even when I set the server to respond after 6 hours. This was a good behavior as far what I expected. However, in IE it timed out. This was quite frustrating, because IE is the target of this Long Polling alternative in the first place. If it times out, it means that now I have to detect how long it takes before the client times out, and that I have to implement a mechanism for having the server return a response no longer than that timeout value or I’m risking losing the connection with the client. Testing this several times shows that IE times out at approx 60 minutes (see pics below).

Now comes the harder part, which is what to do when those 60 minutes time-out. Remember: the idea is to return a response to the client browser before reaching the client time-out, and have the client re-open a new connection. I thought I could use a simple Timer for this. The timer has to be set to a predefined interval (e.g. 30/45/60 minutes etc. – depends on how much risk you wish to take here…), and decrement the Outstanding Operations reference counter if it elapses. This way the server returns a response to the client, which the clients reads as “timeout”, meaning that there’s nothing to do but re-open a request.

Here’s the code:

using System;
using System.Web.Mvc;

namespace LongPolling.Controllers
{
    public class MyAsyncController : AsyncController
    {
        private System.Timers.Timer timer;

        [NoAsyncTimeout]
        public void LogicAsync()
        {
            this.timer = new System.Timers.Timer();
            this.timer.Interval = 4000;
            this.timer.AutoReset = false;
            this.timer.Elapsed += delegate
            {
                timer.Stop();
                MyPublisher.Notify -= new MyPublisher_Notify;
                AsyncManager.Parameters["contents"] = "timeout";
                AsyncManager.OutstandingOperations.Decrement();
            };

            this.timer.Start();

            AsyncManager.OutstandingOperations.Increment();

            MyPublisher.Notify += MyPublisher_Notify;
        }

        private void MyPublisher_Notify(object sender, MyPublisher.MyEventArgs e)
        {
            this.timer.Stop();
            MyPublisher.Notify -= MyPublisher_Notify;
            AsyncManager.Parameters["contents"] = e.Contents;
            AsyncManager.OutstandingOperations.Decrement();
        }

        public JsonResult LogicCompleted(string contents)
        {
            return Json(new { Data = contents });
        }
    }
}
  • Line 8 declares a Timer variable. This timer is started in the ‘Begin’ method (LogicAsync) and is set to 4 seconds (just for this example – it’s supposed to be set to a much lengthier interval but less than 60 minutes).
  • Lines 16-22: When this timer’s Elapsed event is raised, this means that the request is timing out and should be renewed, so we unregister from the publisher (we do not want to process the event handler during re-connection), and decrement the Outstanding Operations reference counter in order to immediately return a response to the browser. The browser is supposed to interpret this response as “do nothing” (NOP) and re-open a request.
  • Line 33: If the timer did not elapse but we did get an event from the Publisher, we immediately stop the timer, and execute the returning response as normal. This ensures that the timer won’t elapse till we finish implementing the response logic.

In the example above, assuming that a MyPublisher is set to return a response every 10 seconds, you are expected to see two “NOP” responses per one correct response of the handler being raised:

await/async

This here is just an extra to this post. I was thinking whether I could use the new async lib from C#. I came up with this:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace LongPolling.Controllers
{
    public class MyAsyncController : AsyncController
    {
        public async Task<JsonResult> MyAction()
        {
            string contents = null;
            await Task.Factory.StartNew(() =>
            {
                Thread.Sleep(TimeSpan.FromMinutes(30));
                contents = DateTime.Now.TimeOfDay.ToString();
            });

            return Json(new { Data = contents });
        }
    }
}

The code above seems to be working well but I’m somewhat uncertain whether it’s the correct implementation or best practice for using await/async in MVC.

UPDATE: In Scott Guthrie’s lecture (1:15:25), you can view async/await support which is similar to the example above.

However, when I tried to rewrite the “MyPublisher pattern” using await/async (excluding the timer part), I ended up with something I wasn’t pleased with:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace LongPolling.Controllers
{
    public class MyAsyncController : AsyncController
    {
        public async Task<JsonResult> MyAction()
        {
            ManualResetEvent ev = new ManualResetEvent(false);
            string contents = null;
            EventHandler<MyPublisher.MyEventArgs> d = null;
            d = delegate(object sender, MyPublisher.MyEventArgs e)
            {
                MyPublisher.Notify -= d;
                contents = e.Contents;
                ev.Set();
            };

            await Task.Factory.StartNew(() =>
            {
                MyPublisher.Notify += d;
                ev.WaitOne();
            });

            return Json(new { Data = contents });
        }
    }
}

Nope, I was clearly unhappy with this code.

Summary

To be honest – I’m not thrilled at all to have to use Long Polling. I didn’t like polling either, but polling was simple – the browser makes requests at (almost) regular intervals, checks for updates. End of story. But with IE10 limited to Windows 7 and above, it seems like Long Polling is a possible solution to achieve a “less frequent polling” but still with “real-time” updates. Having said that, one needs to remember that other solutions are available such as using Flash or Silverlight for achieving two-way communications, and to be honest, I’m uncertain how Google Docs document sharing was implemented. You might also be interested in pubsubhubbub which is based on Atom/RSS feeds (at least watch their really cool “what is PubSubHubbub” video). There are other utils which provide reverse-Ajax and server-pushing such as WebSync, but I haven’t used them myself.

UPDATE: As specified above, SignalR is a .NET based solution from guys at MS which you should also probably look up.

Although the majority of my blog posts relate to stuff that I am learning and documenting as I go along, in this particular case I feel like Long Polling is a technique that I have not experienced sufficiently in order to recommend it. Although this is also true for WebSockets, WebSockets are designed to provide a two-way communication so I was feeling a lot more comfortable recommending them. I see Long Polling not as a technology on its own, but rather as a technique which is designated to provide a solution to a problem using existing technology, which isn’t specifically targeting that same problem. However, I am planning on implementing this soon in order to learn whether it proves itself as reliable and comfortable.

UPDATE: I attempted to implement a Publisher which will be able to filter out the browser that initiates updates to the rest of them using the above technique. My solution had one open Long Polling Ajax request and another Ajax request posted to the server from the same browser representing a user’s update. This was supposed to be nothing too clever: just exclude the current user from the Publisher’s event notification list. I thought of using the Session’s ID to make that distinction, when I noticed that my async requests got stuck almost immediately. At first I thought that this was related to the number of requests I had open from several browsers over a Windows 7 workstation, but slowly and painfully I discovered that this was because I inserted something into the Session in order to make the Session ID sticky. Googling revealed a reason: seems like AsyncController locks the Session in order to make it thread-safe between open requests from the same session. In order to use the Session from an AsyncController you probably have to declare it as read-only using the SessionState attribute. I have not found an “official” explanation for that yet although I’m sure that there is, and the best I found so far was this, this and this blog post. If anyone finds a more documented or official blog from MS guys about this, please comment.

Last credits

Little Richard gets the credit for this blog post’s title.

 
2 Comments

Posted by on 19/03/2012 in Software Development

 

Tags: , , , , , , , ,

How to write a code based ValidationExpression using ExpressionBuilder

Here’s a pain: write an ASP.NET ExpressionBuilder. Here’s another: use a ValidationExpression for a RegularExpressionValidator which isn’t hard-coded, Resource based or App Settings based, but code based. This post will cover both pains, but will open a “world of options” for using custom ASP.NET Expressions.

ASP.NET Expressions

To those unfamiliar with ASP.NET Expressions, here’s a brief: you can set property values in a declarative way using Expressions. For example:

<asp:Label runat="server" Text="<%$Resources: Description %>"/>

Assuming that you have a corresponding resource file, the user will see the value set there for the item that has the Description key. I won’t get into this in this post, but I’m a big fan of using Resources in ASP.NET, so Expressions are something I use often.

ASP.NET comes with 3 out-of-the-box Expression “types”: Resources, Connection Strings and App Settings.

The RegularExpressionValidator Situation (Pain number 2):

I assume that most of us who develop using WebForms and ASP.NET Validators have used the RegularExpressionValidator at some point. Using the ValidationExpression property, we can easily set a Regular Expression to validate our users input for stuff like emails, phone numbers, zip codes etc. Very comfortable:

However, a ValidationExpression has to be either hard coded, or retrieved using an Expression. This means that if you need to use the same regular expression in different locations, you’ll either have to copy-paste it, or use an Expression based solution. Hard-coding and copy-pasting a ValidationExpression could prove to be a bad practice, especially for generic validations such as emails and the like, because you may want to change the tested expression, and in such a case you’ll have to find all those locations you now have to replace. Using Expressions is a better solution because by placing a regular expression in a Resource file or App Settings, you can at least avoid copy-pasting it and you have single location where changes can be made. However, both of these Expression-based solutions are somewhat an ugly workaround, because you’d usually want your regular expression in a Shared/Common dll, so other components may use it, and not only your ASP.NET validators. While AppSettings can still be used across your different assemblies, Resources cannot (well, you can use Reflection but that’s another story). Finally, your expression may reside in a Property and contain logic, so now you have to have a code based solution. For example, let’s assume that you need a regular expression validation which is culture oriented – you probably have to use thread culture code to accomplish that. Unfortunately, you cannot use server side script tags to fetch a static, const or property. For some reason I’m not familiar with, MS has not provided what should have been one of the most basic features in ASP.NET, and that is to use the <%= %> from within declarative syntax:

The above code compiles and runs, but literally renders the server tags themselves instead of resolving them. You can use <%= %> in your JavaScript code, or even inside a regular html block, but you can’t use it in declarative properties! This is beyond me, although I guess that there’s a good explanation to this.

Anyhow, if you do want to use a regular expression placed in a const, static field or a static property as written in the following code, you are now stuck, or you are forced to code-behind this in your page and give up the declarative ValidationExpression.

StaticExpression (Pain number 1):

I decided to overcome this situation using a custom Expression. I have written just a small number of expressions all these years, and each time I found myself wasting precious time on remembering how to do this, googling for sample code etc. There are several good resources on the web for writing custom Expressions. Here’s one and another from MS. To summarize this, I’ll just say that basically there are 4 steps to writing your own a custom expression:

  1. Write a custom Expression class by inheriting from ExpressionBuilder (e.g. StaticExpression class that will accomplish retrieving static, const or Property values).
  2. This class should have a static method which actually performs what you want to do and return the desired string.
  3. This class should also implement the abstract GetCodeExpression( ) method, which simply uses CodeDom objects to call the method you created in step 2. (Note, that you may choose to implement the code directly from this method and skip the static method in step 2, as shown in MS’ sample).
  4. Add the custom Expression to the web.config, so that ASP.NET will now how to resolve the declarative Expressions in your pages.

Here is the StaticExpression class, which supports returning a string from a const or static field/property using simple Reflection (explanation below). I placed this class in the App_Code:

  • Lines 9-18 is the CodeDom method which returns the custom method which actually does all the work (lines 20-71).
  • Lines 26-35 parse and determine whether the expression contains not only the class and field/property, but also an assembly name where to retrieve it from. Note, that you can alternatively change the code so that if no assembly is specified, some default assembly is used (in such a case you’ll have to insert a line of code adjacent to line 34, which states: assemblyName=”<your default assembly name>”.
  • Lines 29-30 assumes that the expression specifies an assembly, and that the assembly is specified prior to the const/property. This resembles working with Global Resources, but this doesn’t have to be the case. You may choose to specify the assembly after the const/property name, resembling how Reflection’s Type.GetType work (line 47 shows this).
  • Lines 38-47 resolves the type of the class to be used. The expression, without the assembly, is parsed so that we’ll have the class (including namespace if specified) separated from the field/property name.
  • Line 50 retrieves the actual class type.
  • Lines 54-58 attempt to detect if the name relates to a static field or const, and retrieve it’s value (the null in Line 57 implies a static field or a const).
  • Lines 59-64 relate to properties (the first null in Line 63 implies a static property and the second null means that there are no arguments to this property).
  • Lines 67-68 will throw an exception if the text could not be retrieved.

The declarative code in your Page:

  1. The Label’s Text demonstrates how to retrieve MyConst const from a Consts class residing in the App_Code (no assembly specified).
  2. The RegularExpressionValidator’s ValidationExpression demonstrates how to retrieve a static Property value from a class residing in a different assembly.

And the web.config, which states that when a “Static” keyword is used for an Expression, resolve it using the StaticExpression class:

Final notes

You may also choose to inherit ResourceExpressionBuilder instead of the abstract ExpressionBuilder. This could be handy if you need a custom Expression that will fallback to resolving a Resource Expression. For example, if your page is running in two different custom modes, X and Y, you could change the resource key stated in the declarative property and only then proceed to retrieving the resource, by calling the base class methods. Your code will require changes, but it’s certainly achievable.

 
Leave a comment

Posted by on 11/11/2011 in Software Development

 

Tags: , , , ,

Removing the IIS 7 Server header in a Classic application pool

There are quite a few blogs that describe how to remove the common headers sent to the browser by ASP.NET and IIS. Here’s an example from the iis.net website:

As you can see, the headers give away which web server and technology is running the website. To be honest, I’m not entirely sure why IIS or ASP.NET should send these headers in the first place, but it never bothered me all these years till now. Apparently, some security specialists consider this a threat, because potential hackers might exploit this knowledge to execute known security hacks. I was puzzled by this claim, because I think that removing these headers will be of little help to prevent such exploits. For example, in ASP.NET it’s enough to see the ‘.aspx’ in the url to know that it’s ASP.NET (and therefore, IIS). You’d have to use Routing to overcome this, which means that either you should have thought of this prior to development, or you have lots of work to do now (strange enough, the security specialists do not necessarily require this change.) Other examples for detecting which technology is used even without having those headers sent over, come from the actual content downloaded from the server, which can be easily viewed using browser development tools. Here are several examples: Microsoft uses a lot of ‘.axd’ files for web resources; the html rendered from ASP.NET usually has a __VIEWSTATE hidden field; web sites which use ASP.NET themes render style sheets from the App_Themes folder.

Having said that, I looked for information on how to remove those headers. It seems like those three headers, X-Powered-By, X-AspNet-Version and Server, are controlled in entirely different locations. As there are quite a few blogs about this topic, I’ll be happy to simply refer to an excellent blog post, which explains how to remove most headers. However, the reason I’m writing this blog is not because I wanted to provide this url, its because it took me some time to remove the Server header from an IIS 7 running an application pool in Classic mode. For Integrated mode, this can be done via code. But this doesn’t seem to work for Classic app pools. So how do we remove the Server tag in such cases?

I preferred a programmatical solution that would not force a change in IIS configuration. Unfortunately, all my coding attempts failed to remove the Server tag in IIS7 Classic mode. In order to accomplish this, I had to download and install a utility from MS, UrlScan. UrlScan version 3.1 supports IIS7 so it provided a working solution. Although it lacks a graphical interface, setup was quite easy:

  1. Start->Run->inetsrv and hit enter.
  2. After installation, there should be a UrlScan folder. Go there.
  3. Edit the urlscan.ini file. If there isn’t one, you can download one from here.
  4. Depending on your need:
    1. Set RemoveServerHeader=1 to remove the Server header completely.
    2. Set AlternateServerName to a string of your choice to change the header sent over.

One side effect I had was that all of a sudden, the browser requests for css files returned a 403 forbidden code. I wasn’t sure why this happened, but it was obviously the result of installing the UrlScan. I found that AllowDotInPath was set to 0 and that this was the cause of it. I changed it quickly to ’1′ and the problem was solved. No other problems have arisen so far.

You can also read the full UrlScan reference here

 
1 Comment

Posted by on 25/08/2011 in Software Development

 

Tags: , , , ,

ASP.NET WebForms Routing

This post is more of a “technical completion” post for using Routing in WebForms, which covers some of the issues I have come across. If you require a quick start on Routing, or technical MVC stuff, please read this post first.

I was happy to learn that it’s quite easy to use MS’ built-in Url Routing solution for ASP.NET WebForms. This is quite easy to accomplish in IIS 7, and requires some tweaking in IIS 6. Read this on how to configure your web.config file to support routing according to your IIS configuration. You may want to check that Url Routing is installed.

One pit fall that I’ve encountered was when I needed to deploy a routing solution on a certain server. There seemed to be a slight configuration difference from my development machine, and routing did not work. What I eventually did was to perform a minor tweak in the configuration file, and added a runAllManagedModulesForAllRequests as described here. Note that there are those who consider this configuration tweak “inappropriate” as far as performance, resources and error prone, but their suggested solutions didn’t seem to solve my issue. I decided to perform a simple check, what ASP.NET MVC’s template is configured like – and runAllManagedModulesForAllRequests=true is exactly that. I reckon that if the guys at MS provide this configuration in ASP.NET MVC, it’s good enough for WebForms too.

Enough with the configuration, where are those pitfalls?

As with ASP.NET MVC, the routes are set in the Global.asax file. Here are some routes that will be used in this post:

get.aspx is the sample page in this post. It contains a single PageMethod and will be our test case:

PageMethods
Unlike Web Services (asmx) WebMethods, there is an issue with Url Routing when it comes to PageMethods. It seems like the client is unable to provide the correct url for the page, and the server seems to fail in figuring out which page and method should be invoked. The error received in the client is “405 Method Not Allowed“, and the response contains a somewhat confusing “The HTTP verb POST used to access path ‘…’ is not allowed.” message, which basically means that the Url isn’t resolved correctly and therefore does not reach the correct PageMethod.

Indeed, the Url the client sends by default to our get.aspx page is: “http://localhost:54885/WebSite2/get/1/Get&#8221;.

  • The first “get” is the route which routes to get.aspx;
  • The “1″ is a simple {id}.
  • The second “Get” is the PageMethod.

Because we received the 405 error message, I used the Route Debugger, and as expected, the Route Debugger showed a “No Match” on that url. Initially I thought that it would be easy to write a RouteHandler and provide a generic solution for PageMethod urls, but after I started coding I noticed that it’s not as easy as it may seem. Possible, but not as easy as the workaround. In order to workaround, all you have to do is to set the path in the client JavaScript to the correct page and you’re done. This is done like so:

Note: You can read here how to call your PageMethods using jQuery.

HttpHandlers – ashx files

It seems like ASP.NET 4 has no support for routing to ashx handler files. When you attempt to route to an ashx you’ll get the following exception:

Type ‘MyHandler’ does not inherit from ‘System.Web.UI.Page’.

Fortunately, this is quite easy to get by, because coding a Route handler which will take care of ashx files is trivial enough. Note, that the solution suggested here is based on a Web site and not a Web application, so the route handler code resides in App_Code.

So, there are three steps to this:

  1. Refactor your ashx code to an App_Code class which inherits from IHttpHandler.
  2. Write a simple Route handler which will create that handler when requested to.
  3. Add the new route handler to the routes defined in Global.asax.

Step 1: Refactor the handler – basically, this is your starting point for your actual “business” implementation (although I encourage calling a Business Layer from here):

Step 2: Create a simple Route handler to return the IHttpHandler:

Step 3: Register the new route in Global.asax:

That’s all there is to it. Now you can use a route for targeting your handler, for example:

http://<server>/handler/123

UPDATE: For routing Web Services (asmx), click here.

Route Data

One last issue is in cases that you perform url rewriting or other processing, and you suddenly notice that your Route Data is gone. This is quite frustrating as you can plainly see that url in the browser’s address bar. Fortunately, the solution is quite simple and also uses a Route Handler. All we have to do, is copy the Route Data in a custom Route handler to HttpContext.Current.Items collection, and we have them for the entire http request. Two steps here:

Step 1: Write a simple custom Route handler which copies the route data:

Step 2: Configure Global.asax accordingly:

To sum up – it’s quite cool to be able to use Routing in WebForms. I just finished a small project where I used Routing and the result is quite awesome. It wasn’t just looking better, but it also allowed me to “white label” the website dynamically. For example, I could do the following: http://server/productA/login and http://server/productB/login, and it really felt like two different websites.

 
2 Comments

Posted by on 22/06/2011 in Software Development

 

Tags: , ,

ASP.NET MVC – RadioButtonList and a Code Nugget issue with Generics

I’ve been reading about a RadioButtonList that used to exist in MVC Futures but was removed from the release. There are different solutions in the forums for this, suggesting various implementations. I decided to combine some of the ideas into an extension method, which creates a radio button list with LABEL FORs. It also checks the selected OPTION, and provides a wrapping div with css class that can be easily used. This looks like this:

  • Lines 24-27 & 38-41 contain a wrapping div, in case a css class for a container was specified.
  • Lines 30-35 is where the important stuff resides: iterate over the items of the dictionary (line 18), and create radio buttons with corresponding LABEL FORs.

Although this was sufficient, I decided to take this one step further and create another extension method especially for enum types. This method creates the dictionary out of an enum, and the label’s text out of a local resource file (using LocalResX which was demonstrated some time ago here). This is how it looks:


Now all I had to do was call the new extension method from the View, or so I thought. This was my code (note that Visual Studio failed to color the generic part and the rest of the arguments):

Much to my surprise, I received the following compilation error:

CS1502: The best overloaded method match for ‘System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)’ has some invalid arguments“.

Say what??

After some experimenting, I replaced the generic <T> with an argument of Type in the extension method, removed the <DayOfWeek> from my View and replaced it with a “typeof(DayOfWeek)” – it solved the problem. But hey, what if I did prefer to use generics? Why did the View fail to compile when I placed the generic on my extension method?

What I had done was to compare the resulting compilation of a successful non-generic implementation (using Reflector), and the failed compilation source code (from the Compilation Error page, simply click on the “Show Complete Compilation Source” to view the source code), and I noticed what had happened here:

What happened was that the View failed to recognize the generic call to the extension method, and assumed that RadioButtonList was a property, or a “HelperResult”, as the compiler error states. Check it out in the screenshot above – Html.RadioButtonList should have been called like a method with parentheses! After that I understood that the fact that Visual Studio did not cope and color the generic call in the View wasn’t a designer coloring bug as I initially thought, but rather what seems to be like a Razor bug.

I still wanted to solve this and use generics instead of passing a “typeof” argument. So what I had to do was recall the Razor Code nuggets vs. Code blocks post from a while back on how to replace the call to Write( ), performed by using a Code nugget (@), with a Code block. I made the changes:

Now I received another compilation error, but it was a whole lot better and simply stated that the result of the RadioButtonList<T> extension method is an MvcHtmlString, whereas Html.Raw expects a string. Well, I’m not sure if MS should have provided an implicit conversion method from string to MvcHtmlString and vice versa, and I wasn’t sure I wanted to do it myself, so I had to choose between calling MvcHtmlString’s ToHtmlString( ) method from the View, or from the extension method and return a string instead. I chose the latter, because I wanted to View’s code to remain cleaner, especially if this method will be reused. So, one more time:

Now the View compiled successfully. Checking the assembly with Reflector showed what I expected:

As you can see, now the code calls the RadioButtonList<T> extension method as expected. The resulting string is sent to Html.Raw and from there to the Write(…) method (which was auto-generated by Razor as a result of using ‘@’).

Although this was worked around, I still expect that Razor will support calling generic methods using a Code nugget and not only via a Code block. It’s certainly possible that I’m missing something here, and sure, the workaround isn’t too bad, but it’s just one of those things which make you feel like it’s a “breach” that wasn’t taken care of, and it also was time consuming. I also wonder why MS dropped the RadioButtonList method that was said to exist back in the previews. I guess that it’s written somewhere on the web…

 
2 Comments

Posted by on 12/06/2011 in Software Development

 

Tags: , , , , , ,

A quick guide to have jQuery call your ASP.NET PageMethods

I based most of my solution and understandings on several posts from Dave Ward. Although Dave’s excellent posts cover everything written here and more, it still took me quite a while to get this going. That is why I decided to sum up my current experience in this single post, which may be considered as a quick guide to having jQuery call WebMethods (PageMethods in particular).

Assuming that we have the following PageMethod, how do we use jQuery to call it?

There are several stages I had to go in order to use jQuery alongside PageMethods:

  1. Use the correct url for the PageMethod.
  2. Ensure that the client and server use json content types.
  3. Pass arguments to the PageMethod as JSON strings (see the ‘JSON, objects, and strings: oh my!‘).
  4. Interpret the result using the ‘d’ key (see the ‘Waiter, there’s a .d in my msg soup!‘).

Here’s the client code I ended up with (explanation below):

Correct url? No surprises here. In order to invoke the correct PageMethod you have to supply a valid url for that method. It’s easy to use ResolveUrl to get this right.

json: As you can see, I used jQuery’s ajaxSetup method in order to assure that all ajax calls are sent using json. Naturally, you don’t have to do this if you do not want JSON, or if not your calls are json-based. But, no doubt that placing the ajaxSetup call in a js file that gets loaded from a master page is very comfortable to ensure that all your jQuery ajax calls are using the same basis.

JSON arguments: This is the part where it get tricky. As Dave Ward explains so well in his post, ASP.NET expects arguments in JSON format, whereas jQuery sends JavaScript objects (which are mistaken for JSON objects) in query string format (that is, if you try to send JavaScript objects). This means that you have to provide jQuery not with a JavaScript object, but rather with a proper JSON string. This will ensure that jQuery wont parametrize your data in key=value format and will provide ASP.NET the desired JSON format. This is important because it means that if you decide to pass your data object as an invalid JSON string, you’ll be frustrated why the thing isn’t working. That’s why when I learned of the JSON native support that now exists in the popular browsers (IE8, FF 3.5 etc.), it became an obvious solution: using JSON.stringify() ensures that the data gets sent in proper JSON format.

Whats with the ‘d’? As explained in Dave’s post, ASP.NET 3.5 and onwards returns a JSON response from the server with a key of ‘d’, for security purposes (preventing XSS attacks). While ASP.NET Ajax framework automatically handles the new ‘d’ formatted result, so that you’ll end up with the intended data without ever knowing that a ‘d’ was there in the first place, you have to handle this manually when using jQuery and WebMethods. jQuery’s combination of ajaxSetup and dataFilter event allows us to handle response from the server prior to actually calling your “onsuccess” callbacks. The proposed solution in the code above assumes that our site is working only with ASP.NET 3.5 WebMethods, and therefore a ‘d’ is always returned. I believe that usually that will be the case, although a more complex solution for checking if a ‘d’ is there already exists. Anyway, the proposed solution simply takes a JSON string returned from from the server, parses it and extracts the actual data from the ‘d’ key. It then transforms the actual data back to a string (which is what jQuery will expect to get when the dataFilter event has ended…).

Following the described steps should get you to use jQuery with ASP.NET’s WebMethods and PageMethods.

After this has consumed precious time to get going, the big question that remains is: was it worth it. You could argue that using jQuery is faster, or that it seems like MS’s client framework is destined to “retire” in favor of jQuery. But honestly, having to go through all this trouble for calling a PageMethod just seems way too much. In short, personally, I’d rather have the good old script proxies which are extremely easy to use over the not-so-trivial jQuery alternative.

Just a reminder though: in MVC using jQuery is quite trivial.

 
2 Comments

Posted by on 20/05/2011 in Software Development

 

Tags: , , , ,

MVC and posting data using Html.BeginForm and Url Routing

We all have pages which represent “fill in” data forms. Quite common is a user’s details form: what’s your first name, what’s your last name, email, date of birth etc. This can be coded in various ways, but I thought that this would be a good way to get to know ASP.NET MVC’s Html.BeginForm( ). While there’s also an Ajax.BeginForm(), I think that the two may differ mainly in the desired behavior after you have completed posting and saving the form data. For example, if you’d like to redirect your user to some other view, or display an entirely new View altogether, you might prefer using Html.BeginForm( ). However, you may want to simply display an informatory “Saved successfully” message, and in that case you’d probably consider using Ajax.BeginForm( ) or simply jQuery’s post.

The thing is that Routing could make this a little tricky (as it was in my case). If a certain Route led to a Controller and resulted in a View with a “fill in” details form, the generated html Form’s Action attribute is going to be that exact route which you originally used. So how on earth are you supposed to save your data, if the same route was used to originally render your details in the first place? Sounds confusing? I also thought so till I figured it out. Lets clarify this issue with a real world example. Suppose your website allows users to view and edit their personal profile. Your route could be like so:

Users would be able to use: http://<server or site name>/profile/myUsername to view and edit their profile. Our server side code residing in the AccountController is the following:

Note that the controller has a LoadProfile action method (which corresponds to the route action shown earlier), and a SaveProfile action method. In order to have the form data posted to SaveProfile, we need to provide some arguments to Html.BeginForm( ):

Basically, this works. The View renders fine, the submit button posts the data to SaveProfile as expected and everything seems great. But, I’m only missing one thing: I don’t have the original username from which the Form originally rendered. In order words, I have no idea at this time to which user the filled in data relates to. This was available from the Route url when the profile was loaded, but it’s unavailable now, when Html.BeginForm( ) uses custom data for posting. I thought that this would be easy to accomplish, because the Html.BeginForm( ) has overloads which accept routing data, but it turned out that when I provided those, other Routes I have in my application got prioritized and this gets ugly, because it means that I’ll have to provide more routes or route constraints in order for this to work. And this was just one form in my app, and it doesn’t make sense that I’ll have to do this for all the forms I’ll develop.

This led me to a different question altogether: Why should I explicitly supply BeginForm( ) with an action or controller in the first place? How come that in MVC’s templates there aren’t such arguments when calling Html.BeginForm( ), and yet when posting data, the correct action is invoked? I noticed that if I provided no arguments to Html.BeginForm( ), the default action was a “profile/{username}” route, just like what I used for loading the user’s profile. I was puzzled over this, because I didn’t understand how MVC was supposed to differentiate between loading a profile and saving a profile, as the Route used for both operations is identical. I looked up MVC’s template and found an example for ChangePassword. Turns out that there are a couple of ChangePassword( ) overloads. The first overload received no arguments (for “loading” the form), but the second overload received a Model with the data (“saving” the form). So how does the route knows which method should be invoked?

The answer lies in an [HttpPost] attribute which is placed over the “saving” action method. The route is quite clever and the action type (either GET or POST) is used to differentiate between actions of the same name. This makes sense, because usually a GET operation is to be used for loading a form, and a POST operation is usually used to posting and saving a form. I went ahead and tried it: I removed the arguments from Html.BeginForm( ), changed LoadProfile and SaveProfile action methods simply to “Profile“, added [HttpPost] to the Profile action method which performs the saving operation, and changed the route accordingly. Here’s how this looks:

If we use two action methods by the same name without [HttpPost] on one of them, the run-time throws a “The current request for action ‘Profile’ on controller type ‘AccountController’ is ambiguous between the following action methods” exception.

Now I could use the RouteData collection for retrieving the user name, as well as other form fields which were sent over as arguments.

 
1 Comment

Posted by on 09/05/2011 in Software Development

 

Tags: , , , , , ,

C# 5 – await and async in ASP.NET

I’ve been doing some reading and experimenting with the new C# 5 Async CTP, available for download from here. I guess that the Async Framework will be a part of .NET 5, although I haven’t found a formal document stating so. There are also some blogs released in the past few months by MS’ people that share information about this new feature. I’ll try to summarize it as I understand it for now, and specifically relate to my findings with regards to ASP.NET.

C# 5 Async Framework seems to focus on easing asynchronous programming. It seems like MS has decided to help us developers write asynchronous code without having to deal with the technical aspect of things, mainly callbacks or thread management, and focus instead on the actual logic we need to implement. The basic idea is that a developer may write code “more or less” in a synchronous fashion, and for the Async Framework to do the rest. In my opinion, this does not mean that a developer won’t have to understand the concept of async programming, nor does it mean that a developer will cease using other “orthodox” methods of async programming.

Having said that, here is an example based on MS Async Whitepapers of how it looks. First, lets review a normal nowadays synchronous method for downloading images and saving them on the local machine, using ASP.NET WebForms Page:


Let’s quickly go over this:

  • Lines 16-19 represent Urls of images for download.
  • Lines 22-25 iterate over the Urls, calling a synchronous method per Url.
  • Lines 30-37 is the method which downloads the given Url synchronously using a simple WebClient (I’ve omitted IDispose handling in this post for simplicity).

The Async CTP allows us to transform this code into asynchronous code by performing minor changes:

For the moment we’ll skip the Page_Load implementation and go directly to the downloading method (lines 27-34). We can see very clearly that the implementation remains almost identical to the original method. However, the Async CTP has some new keywords in C# 5 which are used here, that instruct the compiler to compile our code differently behind the scenes. These are async and await:

  • async: This tells the compiler to compile our method differently, so that it uses Tasks and callbacks to run. Although async is mandatory for using awaits, basically its useless without having any awaits in it. This means that if an asynced method has no await instructions within, the method runs synchronously as usual. Writing async in a method doesn’t cause it to be run on a different thread at all (as you might have expected). All it does is to instruct the compiler to auto-generate hidden classes behind the scenes in order to support awaits.
  • await is what actually tells the compiler to auto-generate code using Tasks in order to run asynchronously. An async method’s code is executed on the same thread it was called upon, until it gets to the first await. Every await (starting with the first one) executes and returns immediately. Once again, this may be confusing with nowadays Wait( ) methods which usually block threads. This isn’t the case here. await does the opposite – it causes the compiler to auto-generate code which runs the code asynchronously, while preserving the context of the method. The rest of the method is compiled as a callback of the async Task. When the Task has completed, the code resumes execution using the synchronization context “right where it left off”. The Async CTP Whitepaper is very clear on this: “At first glance the await keyword looks like it blocks the thread until the task is complete and the data is available, but it doesn’t. Instead it signs up the rest of the method as a callback on the task, and immediately returns. When the awaited task eventually completes, it will invoke that callback and thus resume the execution of the method right where it left off!”

Now that we understand what async and await are, we can understand lines 27-34 better. The highlighted changes are:

  • Line 27 contains two method signature changes: async was added in order to “tell” the compiler that this method is going to use the Async framework; The Task return class is the real deal here, because it’s what allows the calling code to query the status of the async task.
  • Line 30 also contains two changes: await performs an async call to DownloadDataTaskAsync, which returns, that’s right, a Task. In the Whitepaper’s terminology, we “await the task”.
  • Lines 31-33 is compiled as a callback for the Task. This code will not be executed until line 30 completes.

With minor changes to the code, our previously synchronous method has become asynchronous! What’s quite amazing here is that the code still looks as if it is synchronous. This means that in the future, it’s supposed to be much easier to write code asynchronously. Let’s go over the calling code now:

  • Line 14 has a new async which “tells” the compiler we’re using Async framework in this method.
  • Line 22 uses await, which basically what starts the async operation and awaits completion, but what’s more important is that we use a parallel new feature, TaskEx.WhenAll( ), which waits till all the tasks have completed (sort of a Thread.Join for all the Tasks). The TaskEx is the temp CTP class and the WhenAll method is expected to be a part of the Task class upon release.
    • We have to await TaskEx.WhenAll( ) or the Stopwatch will be stopped immediately (line 23). Nevertheless, the Tasks will end as expected during the Page’s life-cycle – this will be explained later on.
  • Lines 23-24 are compiled as callbacks and will not be called till line 22 finishes awaiting the task.

One more thing we need to add here, is that just like in ASP.NET 2, running a code asynchronously requires us to have an Async=”true” in the @Page directive. Failure to do so will result in a: “Asynchronous operations are not allowed in this context. Page starting an asynchronous operation has to have the Async attribute set to true and an asynchronous operation can only be started on a page prior to PreRenderComplete event.“, which hints us not only at the Async=”true” directive, but also that the PreRenderComplete is somehow involved. I’ll discuss this later on.

Let’s have a quick view in Reflector at how this looks (we’ll focus on the Page_Load await):

  1. Notice that the MyForm page contains hidden elements which were auto-generated by the compiler. There’s now a <Page_Load>d__1 class which is used for the asynced Page_Load method (and there’s also a <AsyncDownloadFile>d__6 class for the asynced AsyncDownloadFile method). As you can see, the actual Page_Load method looks entirely different than the original source code.
  2. This statement is basically the what will used to perform the callback when the operation completes.
  3. MoveNext() actually starts execution (see below).

The above code shows us the auto-generated MoveNext() of the <Page_Load>d__1 class:

  1. This is our original code, initializing the Urls to be downloaded, as well as the Stopwatch which times the operation (the code which refers to GetExecutingAssembly was inserted by me in order to be able to easily detect where the compiled assembly is, and to Reflect it – so just ignore it.)
  2. That’s the awaiter.
  3. OnComplete, calls the callback (remember item #2 in the previous Reflector window?), which is the MoveNext() again, till the awaiter’s IsCompleted method returns true.
  4. This is the actual callback code – Stop the Stopwatch and display the elapsed time.

As you can see, our original code was split into 2 parts, one to be executed prior to the await, and the rest as callback code.

Life-cycle

Finally, let’s understand the life-cycle of things. I’ve added some code to log the different operations and thread creations. I also added two life-cycle events (PreRender and PreRenderComplete), because I wanted to learn how the life-cycle handles awaits and asyncs. This is a screenshot of the result:

Short explanation: The “Thread number” column is what’s important. It hints at whenever a new thread was assigned to handle the executing code, which actually means we can better understand the life-cycle of ASP.NET in an async scenario. Here are some highlights:

  • The first thread, which is assigned by ASP.NET to handle the request, is the one stated as “Page_Load thread”. As we can see, this thread executes all the code which runs just prior to the first await. Each await executes and returns immediately, and this can explain why both “before awaits” are on the same thread.
  • Important: OnPreRender wasn’t blocked. So now we know that asynced code which returned from the awaits continues unblocked and does not wait for the Tasks completion in the ASP.NET life-cycle, at least up to PreRender.
  • The first AsyncDownloadFile log message shows us that the callback is running on a different thread, as expected. So we know for sure that the async framework has indeed did what it was supposed to do, which it to split our original code into a block which runs on the calling thread, and a callback which runs on a different ThreadPool thread.
  • Note that the second AsyncDownloadFile log message shows us that a different thread handled the second url callback. That’s also “as expected”, as different Tasks handled each url.
  • As opposed to PreRender, we can see that PreRenderComplete executes after all awaiting Tasks have finished. This will be the behavior even if we remove the await from the TaskEx.WhenAll( ) call. That’s important, because we now understand that ASP.NET is involved in the life-cycle of things and takes care that we won’t finish the Page’s life-cycle before all Tasks are completed. This resembles ASP.NET 2 Async Page pattern (see summary below), and sheds light on the meaning of the detailed Exception specified earlier.

To summarize what we’ve seen so far, using the already existing Task classes, await starts an asynchronous operation and returns immediately. So, the code itself is not blocked at all. The compiler generates code also for the callback, so our code continues only when the Task has completed. In other words, async and await cause the compiler to compile our code into async Tasks and callbacks. ASP.NET integrates well with this environment and “knows” to await all tasks, if you haven’t done it yourself. Needless to say, the asynced version runs in parallel which makes it a lot faster.

If you feel like these async and await keywords are misused, you are welcome to join the arguments which seem to be taking place. As written previously, according to Eric Lippert’s post, developers misinterpret await for a blocking Wait-like operation, whereas it’s exactly the opposite, and tend to believe that writing async in the method signature means that .NET will run it asynchronously. However, as stated in Eric’s blog post, attempts to find better keywords so far have failed.

Summary

I find the suggested framework interesting as it will probably allow a somewhat “default” implementation of async programming, and will allow us developers to achieve async solutions more easily.

I think that many developers who know how to develop async programming to some extent, don’t actually do so. I even “dare” to think that this is a more common situation in server side web programming. Unlike Windows Forms development, where using a BackgroundWorker or some other threading solution is usually required in heavy duty tasks, but somewhat trivial because the forms stay in-memory for as long as we require them to, in server side web programming this is quite different. Most ASP.NET developers rely on IIS and ASP.NET to assign requests to threads, and know that if you initiate a multi-threaded operation yourself in ASP.NET, it is a pain. That’s because when you start a thread, the Page doesn’t stay in-memory or wait for it to finish. In Web Forms, the life-cycle doesn’t wait just because a developer opened a new thread in Page_Load or some other Button_Click event handler. The newly created thread will probably complete after the life-cycle has ended and the response was already sent to the client. More over, if you do implement a threading scenario in ASP.NET and block the page life-cycle using a Thread.Join or some other threading blocking mechanism, the actual ASP.NET main thread processing the request is stuck till the new thread has completed, and is not returned to the ThreadPool. That’s why the people at Microsoft have invented Async Pages in ASP.NET 2. This implementation was built on the idea that somewhere in the Page’s life-cycle (after PreRender), an async operation may start, the thread handling the request will be returned to the ThreadPool, and upon completion of the async thread, the life-cycle is resumed using a different ThreadPool thread (returning to the PreRenderComplete in the life-cycle). While this was some sort of a solution, it was still uncomfortable and forced to developer to be bound to a certain step in the life-cycle in order to achieve async in ASP.NET. So, my guess is that most developers chose not to use this solution as well. In short, while client side async programming evolved thanks to Ajax, server side web programming in ASP.NET lacked the proper infrastructure to evolve. Thanks to the Async framework, it’s possible we’ll see more async web server side development.


 
12 Comments

Posted by on 02/05/2011 in Software Development

 

Tags: , , , ,

ASP.NET MVC Partial View and Ajax “real world” example

If you would like this sample code, right click here and “save as” to download. Then rename to a zip file and open.

In my previous post I have discussed and demonstrated how you can easily use jQuery and a ASP.NET MVC’s Partial View to accomplish an UpdatePanel-like solution. In this post I’d like to demonstrate a “real world” usage of this technique.

I wanted a cool looking Login dialog to popup on request when a user hits a simple “Log On” button, without having to refresh the entire page or redirecting the client to a Login page. In other words, there is no Login page, just a Login dialog. Naturally, I wanted this Log On button to be available across all the pages in the site. This could be easily be implemented using a layout (“Master Page”). But it’s more generic and nice to use a PartialView, to represent that button. More over, the basic code for this already exists in the MVC application template. Simply create a new MVC application and see for yourself. So there’s nothing new so far. However, the code for the login dialog is something new which is required and here I had basically 2 options:

  1. I could render the login dialog as a hidden dialog (“display:none”) in the Partial View (or layout). This is possible, will save a round trip to the server when the user requests to login, but is also quite “ugly” as it is inefficient to render a hidden dialog every time.
  2. I could have an UpdatePanel like implementation. Using a placeholder div, I could request another PartialView from the server on demand. The html rendered will be then “injected” into the placeholder div. I figure that this is way more efficient than the first option and can be considered, well, “nice”.

I decided to go with option 2. It felt more cool and correct, and also provided me with a great opportunity to practice this technique. Here’s the basics:

  1. We’ll create (or rather re-use MVC’s template code) a Partial View to represent a Log On/Log Off button. This will be rendered from the layout onto all pages. This view will also contain a place holder div, which will be injected with the log-in dialog.
  2. We’ll create a Partial View for the login dialog. This is basically a simple div which wraps the username/password textboxes. This will not be rendered anywhere at design time.
  3. We’ll use jQuery’s ‘load’ method to perform an Ajax call to the server, and return the Partial View of the log-in dialog. The dialog’s html will be injected into the place holder described in stage 1.
  4. We’ll create server side code to support the logon/logoff scenarios.

“Strategy”: The login button’s partial view is going to have a wrapping div, which will change according to the whether a user is logged in or not. This will be rendered at first according to the authenticity state, but will change at run-time according to the user’s operations. This will be described in 4 stages below.

Stage 1: Login button (Partial View). I reused MVC’s template code to do this. The entire code is wrapped with a div (‘divLoginButton’), whose contents will dynamically change according to Log on/log off operations performed by the user.

  • Line 1 is the wrapping div.
  • Line 2 is the server side code which decides whether a Log On or Log Off button will be rendered from the server.
  • Lines 4-9 represents a Log Off button. The user is logged in, authenticated, and has not requested to logoff (line 2 makes that decision).
  • Line 7 contains an Ajax call to actually perform the log off, and to replace the div’s entire content with a new state. This really resembles a Web Form’s UpdatePanel’s behavior, only cleaner and more efficient.
  • Lines 13-28 represent a situation that the user is not authenticated and a Log On button is displayed.
  • In line 17 we query whether the login dialog has already rendered from the server. This can happen if the user has clicked the Log On button, the dialog has rendered from the server (line 19), but has not logged in (e.g. clicked the Cancel button of the dialog). In this case, there’s no point in reloading the dialog from the server, so we reset the username/password fields (line 22) and reopen the dialog (line 25).
  • Lines 29-30 is the place holder for the login dialog.

Stage 2: Login dialog (Partial View). I created the new LoginDialog.cshtml PartialView file. This looks like this:

  • Lines 1-13 represent the “dialog”. This is just a basic div with username/password textboxes. This will be displayed as a modal dialog using jQuery UI’s Dialog. Because the dialog is set to autoopen, this will be automatically opened when rendered for the first time.
  • Lines 15-43 contains the JavaScript which will display the window as a dialog. If you’d rather have the JavaScript in a different JS file because you believe that rendering a JavaScript ajax response from the server is a bad thing, it’s also possible.
  • Line 23 indicates a POST ajax call. POST is done for security as I’d rather have the username/password (lines 25/26) not sent in the query string. The Ajax call is for the Login action method in the Home Controller.
  • Line 32 is executed when the result of the Login method is “Success”. This is what does the trick of replacing the “Log On” button with a “Log Off”, similar to the signout process discussed in Stage 1 above. It is possible to return the PartialView directly from the Login action (line 23), but I wanted to render a Success boolean in order to have more control, especially in case the Login fails.

Stage 3: Server side code to support the Log On / Log Off situations.

The comments are probably sufficient, but just in case:

  • Lines 15-18 return the Login Dialog partial view.
  • Lines 21-26 supports a Log Off scenario. Line 23 performs the actual Sign Out. Line 24 instructs the LoginButton partial view that although the user is still authenticated at this point, a Log On button should be rendered and not a Log Off button.
  • Lines 30-33 return a Log On or Log Off button, depending on the authenticity state of the user. Basically this is used after a successful login operation, when we would like to render a Log Off button.
  • Lines 36-42 represents a Login process. Line 38 should be replaced with actual Membership user login validation check. If true, line 40 sets the authentication cookie. Line 41 returns if a successful login was performed. As you can see, in this example the login is always a success.

Stage 4: Render the Login button in the layout (“Master Page”), so it’s visible throughout all the pages.

  • Line 11 represents the Login Button partial view (Log On / Log Off button).
  • Lines 5 and 8 are jQuery UI (required for the modal dialog).

Here’s how it looks. At first, the page is loaded and the Login button is rendered as a Log On button.

Now we click the Log On button. jQuery’s load method performs an Ajax request to the server, and the Login Dialog Partial View is rendered back. Because the JavaScript code which creates the dialog has an autoopen set to true, it automatically opens:

Now we type-in our credentials and click Login. A POST Ajax call to the server performs credential validation and returns a JSON with Success, meaning that the Login went ok and the user has logged in. Now another Ajax call takes place to “refresh” the state of the Login Button to that of a Log Off button. This looks like this:

Finally, when we click the Log Off button, another “refresh” takes place as the server’s LogOff button returns an updated Login Button.

That’s about it. As stated above, you could take the JavaScripts to a different JS file if you feel bad about rendering back JavaScript, or if you think that it’s more efficient either because the network load is reduced or because the JS file will be cached by the browser. It’s also possible to render both a Log On and a Log Off buttons at once and toggle their visibility on the client side, settling just for Ajax calls only to perform the credential validation and to set the cookies. In either case, this isn’t the point of this blog post. The point is to show multiple examples of Partial Views used as Web Forms Update Panels, using jQuery.

 
91 Comments

Posted by on 26/04/2011 in Software Development

 

Tags: , , , , ,

 
Follow

Get every new post delivered to your Inbox.

Join 41 other followers