Sunday, 27 September 2015

Difference between @Helpers and @Functions in MVC



Both @helpers and @functions do share one thing in common - they make code reuse a possibility within Web Pages. They also share another thing in common - they look the same at first glance, which is what might cause a bit of confusion about their roles. However, they are not the same. In essence, a helper is a reusable snippet of Razor sytnax exposed as a method, and is intended for rendering HTML to the browser, whereas a function is static utility method that can be called from anywhere within your Web Pages application. The return type for a helper is always HelperResult, whereas the return type for a function is whatever you want it to be.
A typical example of a helper is to display items in an ordered list. You create a folder called App_Code in the root of your site, if you don't have one already, and add a .cshtml file to it. You can name this file anything you like - but Helpers seems to be appropriate. Within your Helpers.cshtml file, you would add the following code:
@helper OrderedList(IEnumerable<string> items){
    <ol>
        @foreach(var item in items){
            <li>@item</li>
        }
    </ol>
}
As you can see, this code includes HTML tags and Razor code, just like it would if you were rendering an ordered list within a Web Page. When the code is compiled, OrderedList becomes a static method of non-static class called Helpers - the name of the class is taken from the file name. A sample method call could look like this:
@Helpers.OrderedList(new[] { "Blue", "Red", "Green" })
When this is executed, unencoded HTML is output to the browser. You could implement the same functionality using @functions, and here is an example which does just that. Again, you need to add a .cshtml file to App_Code, and give it a name. In this case. Functions.cshtml is as good as any:
@using System.Web.Mvc;
@using System.Text;
@functions {
   
    public static HtmlString OrderedList(IEnumerable<string> items)
    {
        var sb = new StringBuilder();
        var orderedList = new TagBuilder("ol");
        foreach(var item in items){
            var listItem = new TagBuilder("li");
            listItem.SetInnerText(item);
            sb.AppendLine(listItem.ToString(TagRenderMode.Normal));
        }
        orderedList.InnerHtml = sb.ToString();
        return new HtmlString(orderedList.ToString(TagRenderMode.Normal));
    }
}
Again, OrderedList becomes a method of a non-static class named after the file (Functions), and calling it in the page is straightforward:
@Functions.OrderedList(new[] { "Blue", "Red", "Green" })
You've had to reference System.Text to create a StringBuilder object and System.Web.Mvc to use the TagBuilder (although you could have rendered the HTML tags as strings yourself), and make sure you returned an object of type HtmlString to ensure that the whole lot doesn't get HTML encoded when it is rendered to the ouput. Functions cannot contain intermixed HTML. Now you can see the attraction of @helpers.
The appropriate use for @functions is when you want to perform an operation on a variable, rather than output some HTML. For example, you might want to validate an incoming DateTime to ensure that it is some time in the past. You wouldn't accept a form submission where someone's date of birth is some time in the future, after all? This is where @functions can be used:
@functions {   
    public static bool IsBeforeToday(string value){
      DateTime result;
      if (DateTime.TryParse(value.ToString(), out result))
      {
        if (result < DateTime.Now)
        {
          return true;
        }
      }
      return false;
    }
}
This function takes a string as an input, and tests to see if it can be converted to a DateTime successfully. If so, it tests to see if it is before the current date and time. If it passes those tests, it returns true:
@Functions.IsBeforeToday("2010/3/22") @*returns True*@
@Functions.IsBeforeToday("2012/5/6") @*returns False at the time of writing*@
Notice that the return type for both @functions examples have differed - the first is an HtmlString, whereas the second is a bool. The return type for a method compiled from @helpers will always be HelperResult.
One other thing to note - I've emphasised that the class that is compiled as a result of the @functions syntax is non-static. This means that you cannot create extensions methods using @functions.




Asynchronous Controller in ASP.NET MVC



The asynchronous controller enables you to write asynchronous action methods. It allows you to perform long running operation(s) without making the running thread idle. It does not mean it will take lesser time to complete the action. If a request make a service call that require two seconds to complete it, the request will take two seconds whether it is performed synchronously or asynchronously. However, during asynchronous call, the server is not blocked from responding to the other requests.

When to use Asynchronous Controller
Asynchronous action methods are useful when an action must perform several independent long running operations. Suppose we have three operations which takes 500, 600 and 700 milliseconds. With the synchronous call, total response time would be slightly more than 1800 milliseconds. However, if the calls are made asynchronously (in parallel), total response time would be slightly more than 700 milliseconds, because that is the duration of longest task/operation.

How to create Asynchronous Controller
1)    Inherits MVC controller with AsyncController instead of Controller.
2)    Asynchronous action methods are useful when an action must perform several independent long running operations. Suppose we have three operations which takes 500, 600 and 700 milliseconds. With the synchronous call, total response time would be slightly more than 1800 milliseconds. However, if the calls are made asynchronously (in parallel), total response time would be slightly more than 700 milliseconds, because that is the duration of longest task/operation.

Using the code
public class AsynchronuosTestingController : AsyncController
{
    private readonly object _lock = new object();
 
    public void IndexAsync()
    {
        AsyncManager.OutstandingOperations.Increment(2);
        Operation1();
        Operation2();
    }
 
    public ActionResult IndexCompleted(string Operation1, string Operation2)
    {
        ViewData["Operation1"] = Operation1;
        ViewData["Operation2"] = Operation2;
        return View("Index");
    }
 
    void Operation1()
    {
        lock (_lock)
        {
            AsyncManager.Parameters["Operation1"] = "Result1";
        }
        //last line of this method
    
        AsyncManager.OutstandingOperations.Decrement();
    }
 
    void Operation2()
    {
        lock (_lock)
        {
            AsyncManager.Parameters["Operation2"] = "Result2";
        }
        //last line of this method
    
        AsyncManager.OutstandingOperations.Decrement();
    }
}
You can see above in the sample code, we can store the results/values which we want to display on the views in the parameter collections. All the parameter values can be received with the parameters in the actionCompleted (InvokeCompleted) methods.

View Code
@{
         Layout = null;
}
<!DOCTYPE html>
<html>
<head>
         <meta name="viewport" content="width=device-width" />
         <title>Index</title>
</head>
<body>
<div>
         <p>@ViewData["Operation1"] </p>
         <p>@ViewData["Operation2"]</p>
</div>
</body>
</html>
You may be not able to see the difference here but you can check with the long running process to feel the differences.