Hadi Hariri's Blog

Checking for a null Model in ASP.NET MVC

Friday, 30 April 2010 16:26 by hadi

 

It is considered good practice to use strongly-typed models when working with ASP.NET MVC. That is, instead of doing something like

ViewData["CustomerName"] = "John Smith";


you would do

var customer = new Customer() { Name = "John Smith"};

return View(customer);

Using this approach however, has a minor issue. Let’s say someone makes the following request:

http://server.com/customer/details/34

and the corresponding Action that processes this is:

 

public ActionResult Details(int id)
{
    

    var customer = _customerServices.GetCustomerById(id);

    return View(customer);
}

 

if customer with 34 does not exist, you’ll have a problem at runtime if you’ve not made the necessary null checks. This occurs because the View will most likely display the name via the Model property, which is null.

<p>
    Name:
    <%: Model.Name %>
</p>

The most common solution to this problem is to do a null check, either at the controller level, by checking to see if the model is null before passing it to the View, or alternatively in the View, before accessing the model property. If doing the latter, the normal thing would be to extract this into an Html helper to avoid having continuous checks for each property.

Using Action Filters

 

ASP.NET MVC has a series of filters, which are applied before and after certain events take place. An Action filter has four methods that are of particular interest:

  • OnActionExecuting: Takes places before an action is executed
  • OnActionExecuted: Takes place after an action is executed
  • OnResultExecuting: Takes place before a result is executed
  • OnResultExecuted: Takes place after a result is executed

We can leverage these methods to intercept the request/response when an action is executed. For instance we could override OnActionExecuting to perform authorization or override OnActionExecuting to implement some kind of auditing.

In our case, what is interesting however is the OnResultExecuting, which occurs after an Action has executed and before the actual view is rendered. If we could hook into this, we could check to see if the Model passed in is null and if so, do something about it, thus preventing the View from giving a null reference exception while trying to access a null model.

One way to accomplish this is to create a new filter by inheriting from ActionFilterAttribute and overriding the corresponding method:

public class HandleRecordNotFoundAttribute : ActionFilterAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
          var viewResult = filterContext.Result as ViewResult;

          if (viewResult != null && viewResult.ViewData.Model == null)
          {
            filterContext.Result = new ResourceNotFoundResult();
            filterContext.Result.ExecuteResult(filterContext.Controller.ControllerContext);
          }
        }
    }

 

What we’ve done is first get the View that is going to be returned. If it is not null we then check to see if the Model is null. If it is, we return a 404 result, which indicates that the resource requested does not exist. If none of the previous conditions are met, we then just let the response take its course and not interfere. The ResourceNotFoundResult is simply an HttpException wrapper that returns an ActionResult.

public class ResourceNotFoundResult : ActionResult
{
    public string Message { get; private set; }

    public ResourceNotFoundResult()
    {
        Message = "The requested resource was not found";
    }

    public ResourceNotFoundResult(string message)
    {
        Message = message;
    }
    public override void ExecuteResult(ControllerContext context)
    {
        throw new HttpException(404, Message);
    }
}

 

Finally, to use this, all we need to do is just tag the corresponding action with the attribute. This way, instead of continuously having code like this:

public ActionResult Details(int id)
{
    

    var customer = _customerServices.GetCustomerById(id);

    if (customer == null)
    {
        return new ResourceNotFoundResult();
    }
    return View(customer);
}

 

we can have:

[HandleRecordNotFound]
public ActionResult Details(int id)
{
    var customer = _customerServices.GetCustomerById(id);
    
    return View(customer);
}

We could extend this to the controller by first checking the type of the result and not casting it directly to a ViewResult and set the attribute at the Controller level. I’ll leave that to anyone that wants to fork the code. One step further is to modify pipeline to not even require an attribute (but I’ve yet to play with that).

You can get the entire example from here.

Tags:  
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (1) | Comment RSSRSS comment feed

Screencast: ASP.NET Features for ReSharper 5

Monday, 19 April 2010 21:19 by hadi

 

This screen cast shows some of the ASP.NET Features ReSharper offers in version 5. It applies to both ASP.NET MVC and WebForms.

Tags:   ,
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Profiling Apps 1 of N: The MVC ActionLink

Tuesday, 9 March 2010 21:30 by Hadi

 

I’m starting a new series of blogs posts on profiling, where we’ll try and cover common bottlenecks and how to identify them in your applications. However, before delving deeper into the subject, let me make a small but important observation:

Your bottleneck is probably not your for loop

Now, replace that for loop with switch statement, an older version of some outdated algorithm that you feel needs optimizing, or that retched collection of classes that would perform better if you were using an array to loop through them, and you’ll end up with the same observation.

Premature Optimization

When dealing with business applications, it is unusual for major performance problems to be pinpointed down to specific portions of code or a concrete implementation of an algorithm. Usually most of the issues are bottlenecks at the data level, network level or purely down to how a business decision is made.

Whether we use an ORM or use SQL directly, incorrectly formulated queries are one of the most predominant causes of bad performance. Not understanding concepts such as Lazy or Eager loading when using an ORM can be disastrous to the performance of an application, and are usually portrayed as “ORM XYZ sucks at performance”. 

Network bandwidth and latency are other issues; when dealing with web applications for instance, having large pages (i.e. ViewState) or rendering Javascript directly without using script files, are a common problem for performance penalties. Making heavy calls to the server when very little information is required (i.e. UpdatePanel used incorrectly) are again main causes for concern.

In many cases, design decisions we make early can affect the performance of our applications, and it is important to identify these concerns and address them correctly. Using an ORM, profiling it, understanding how Ajax really works and not worrying about working with Javascript, or using an asynchronous architecture when dealing with long running business processes are many ways to avoid bad performance in the long run.

On the other hand, what we shouldn’t do is focus on micro-optimizations, on trying to make the most efficient, yet completely undecipherable algorithm to calculate the probability of winning money when buying lottery tickets, when the underlying problem is a bottleneck caused by a bad query. This kind of approach is often referred to as Premature Optimization, and can be disastrous for a project.

When it does boil down to code

Having said all that, there are times when we need better performance after having eliminated all the obvious causes, and need to discover why something is not performing as well as it should be. Of course, these concerns are greater when the nature of our application demands highly optimized code. In these cases, it is crucial to understand how things work in order to solve the problem. As a old-school boy, before we had managed libraries and drag-n-drop, I’m also a firm believer that it is always important to understand how things work under the covers, even if it is to just improve one self's knowledge.

Therefore, in these series of blog posts about performance, I’m going to focus on the latter, examining the details of code and how some things can perform better than others. So given the disclaimer, let’s get down to business.

In order to do performance tuning, you need to use a tool. Setting stopwatches doesn’t work, because as Christian Gross so rightly pointed out during one of his talks, and I semi-quote: ‘if you’re using a stopwatch, you think you know where the bottleneck is. Most of the time, you’re wrong’.  If you are setting using a manual approach of setting calling Start and Stop, trying to time something, you’re assuming you know that the performance problem is located in a particular point, and many times it is not that point. So you end up having to place these kind of diagnostic codes in various places in your code, and soon it becomes a maintenance nightmare. Fortunately, there are tools that can profile your application in a non-invasive manner. When talking about SQL profiling, there’s NHProfiler for instance. When it comes to code performance profiling, the two most known ones are ANT Profiler and dotTrace. I’m going to be using dotTrace. I used it before joining JetBrains and continue to use it now that I’m at JetBrains. I’ll be using version 4.0 which is currently (at the time of writing this post), in Early Access Program and with Beta being released very soon.

To Express or not Express

Those that are familiar with it ASP.NET MVC know it relies heavily on the use of strings in many areas. For instance, when defining ActionLinks, you write

Html.ActionLink(“Home”, “Index”, “Home”)

where the first parameter is the link text, the second the Action and the third parameter is the Controller. The problem with this of course is that if you type either the second or third parameter incorrectly, you won’t know until runtime. Even if you build your views it won’t help.

An alternative is to use Expression based Html Helpers (another option is to use ReSharper of course :)). These are strongly-typed ActionLinks that do not ship out of the box with ASP.NET MVC, but are available as a separate download in the MVC Futures assembly, which can be thought of as a kind of sandbox for Microsoft to play with. Some of the functionalities in this library have eventually made it to the main core, such as RenderPartial, which was in fact there from pretty much the early Previews of MVC 1, and didn’t get all the excitement until it made it into the core in version 2. Other functionality, including the expression based ActionLinks haven’t made it in yet. When using these helpers, the previous link would be:

Html.ActionLink<HomeController>( a => a.Index, “Home”)

In principle this looks good, and begs the question of why it is not in the main core. Well I don’t know the exact reason, but one could potentially be due to it’s performance. Several people have talked about the difference in terms of rendering when using this version as opposed to the standard string based one. You can find one of those posts here. What I thought I’d do, is actually see how much difference in speed there is between one and the other.

The Project

I’m using a very simple project for this profiling. It’s your standard ASP.NET MVC 2 application. On Index page, I’ve added two blocks of code:

  1. <% for (int i = 0; i < 1000; i++)
  2. {%>
  3.   <%= Html.ActionLink("Link " + i, "Index", "Home")%><br />
  4.   <%
  5. } %>
  6.  
  7. <% for (int i = 0; i < 1000; i++)
  8. {%>
  9.   <%= Html.ActionLink<HomeController>(a => a.Index(), "Link " + i)%><br />
  10.   <%
  11. } %>

The first for loop will render out 1000 links using the string based ActionLink version, whereas the second loop will do the same using the expression-based one.

What we want to do now is run this and see how long it takes for each loop to complete.

Setting up dotTrace Profiler

Working with dotTrace is as easy as it gets. There are two ways to profile an application: Standalone or integrated within Visual Studio. In the case of the former, you can start up dotTrace outside of Visual Studio and point to an application to profile. On the other hand if you have it integrated inside Visual Studio, then all you need to do is click on the Profile menu option:

image

Once we do that, we get a dialog box that provides us a series of options, mainly to do with the type of profiling we are going to perform.

image

Since we’re profiling a web application, we can either use the Development Server or Internet Information Server. In our case we’re going to use the former. dotTrace will automatically pick up the server settings as well as fill out the physical path for our application.

Next come the profiling options. The basic settings are Profiling Type and Meter Kind. The first parameter indicates how profiling will take place. It can be:

  • Sampling: dotTrace will do frequent analysis of calls stacks. It’s the least intrusive, has very little impact on performance, but gives approximate timing.
  • Tracing: dotTrace receives notifications from the CLR on entry/exit of methods. More precise timing and call information.
  • Line-by-Line: dotTrace logs times for every statement in methods. Most precise but also has higher impact on performance.

Tracing is normally the recommended option. Meter Kind defines how dotTrace logs the time: CPU instruction or Performance counter (uses the Windows API and samples are hardware independent).

Profiling our application

Once we have everything setup, we can start profiling our app. dotTrace will launch a small panel that allows us to control data sampling.

image

dotTrace does not by default however launch the browser. In order to do so, we need to either click on the WebDev server and Open in Browser or just type the URL directly in the browser.

image

The next step is to perform the operations we want to profile and then click on GetSnapshot.

image

Since in our case, having rendered the Index action performs these operations, once the page has been loaded, we can click on GetSnapshot and have the profiler launched.

image

I’m not going to get into all of the details of dotTrace in this first post because otherwise it would never end;  we’ll cover some of the aspects in future posts. For now, lets focus on our performance test at hand which is the difference between the two types of ActionLinks (string and expression based).

The easiest way to find what we are looking for is to use the…you guessed it, Find feature. Ctrl+F will bring up a dialog box similar to ReSharper’s Type location. We can then type ActionLink to filter the list of functions down to the ones that interest us

image

We can see that there are two versions, as expected. Let’s drill in to the second one first, the string based one. Hitting Enter will find the first location. We can then press F3 until we find the one that interests us. Remember, Site.Master and other references to this call also exist. We’re specifically looking for the loop, the one with 1000 calls

image

We can see that the ActionLink call takes 121ms for 1000 calls. Drilling in, we can see exactly where the time is spent, and 104ms of that is calling GenerateUrl. Now let’s take a look at the Expression based ActionLink

image

For the same 1000 calls it takes 140ms, which is an increase of approximately 17%. Diving in once again, we can see that 6ms of this is in the parsing of the expression tree, GetRouteValuesFromExpression. What this function does is merely analyze the expression to extract the ActionName from the parameter. The ControllerName it already has since it’s the concrete type the generic method is invoked with, returning both values in a RouteValueDictionary. As such it then needs to call GenerateRouteLink as opposed to GenerateLink since the former takes a RouteValueDictionary as a parameter, whereas the latter takes strings indicating the controller and action. They ultimately both call GenerateUrl.

Summary

From the results, the difference between the two calls is not that significant for 1000 links. As the number of links increment, the difference between the two does not change significantly. For instance, rendering 10.000 links, has a difference of 50ms between one version and another.What’s interesting that having run the same profiling on previous releases, the difference in time was nearly double, so there seems to have been improvement in this area. And as we can see, sometimes what might seem a performance problem, isn't necessarily one.
Tags:   , ,
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (2) | Comment RSSRSS comment feed

List my controllers for me…

Saturday, 10 October 2009 10:01 by hadi

 

Nuff said!

image

Really liking Resharper 5.

Tags:  
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (3) | Comment RSSRSS comment feed

Resharper 5 support for MVC

Friday, 9 October 2009 23:17 by hadi

 

Resharper 5 has a couple of new features for MVC that can make your life somewhat easier. Take a look at the following screenshot:

image

That’s inside an ASPX ViewPage. The first thing is the “Abouta” underlined in blue. The hint tells me that this action does not exist. “Home” on the other hand, which corresponds to a controller is underlined, meaning you can navigate to it from there (ctrl+left mouse click).

In the case of the action not existing, if we haven’t spelt it wrong, we can ask Resharper to create it for us:

image

which generates the corresponding action in the controller:

image

Simple, yet very productive!

Tags:   ,
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (2) | Comment RSSRSS comment feed

The Principle of Least Surprise

Friday, 9 October 2009 11:23 by hadi

 

I’m having a discussion on the ASP.NET MVC forums with one of the guys from the ASP.NET team in regard to the Data Annotations in MVC 2 and I’m not sure I agree with him. Here’s an issue Jak and I have run into:

In MVC 2 there’s a new Html Helper named EditorForModel(); that renders out a form based on the properties of your model, along with the validation messages, labels, etc. So something like this:

 

   <% using (Html.BeginForm()) {%>
 
        <%=Html.EditorForModel() %>     
            <p>
                <input type="submit" value="Save" />
            </p>
    <% } %>

 

you’d get something like this:

image

If you want to do individual fields and thus have finer control, you can use the EditorFor helper, passing in a property name. In other words, the previous could be also rendered as:

    <% using (Html.BeginForm()) {%>
 
        
   <%=Html.EditorFor( model => model.FirstName) %> 
   <%=Html.EditorFor( model => model.LastName) %>
   <%=Html.EditorFor( model => model.Email) %>
        
            <p>
                <input type="submit" value="Save" />
            </p>
    <% } %>

but this time you don’t get the labels:

image

The problem however is that you lose something else: the Validation messages. If you have client-side validation enabled, the previous ASPX file generates a pretty much useless call to the EnableClientValidation JS function:

EnableClientValidation({"Fields":[],"FormId":"form0"}, null);

 

as opposed to:

EnableClientValidation({"Fields":[{"FieldName":"FirstName","ValidationRules":[{"ErrorMessage":"First name is required","ValidationParameters":....
 
// rest omitted for brevity

 

The result of course is that client-validation doesn’t work (and from what I’ve heard causes JS errors in some browsers).

The solution to this is to explicitly add a Validation Message, like so:

<%=Html.ValidationMessage("FirstName")%>

Now I understand that EditorFor is for fine-tuning and there is a corresponding LabelFor (although a ValidationFor doesn’t exist yet), but my main concern here is that it’s breaking the principle of least surprise from an API perspective.

For me, the only difference between EditorFor and EditorForModel should be that in the first I specify a property name explicitly whereas in the latter it just assumes the whole model. Nothing is telling me by the name of the method that the second does a whole bunch more of magic.

One solution is for EditorFor to be renamed to something else if it’s ONLY going to provide the input box (be it a text area, checkbox, radio group, etc..).

Thoughts?

Tags:  
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (6) | Comment RSSRSS comment feed

Testing Model Validations?

Friday, 9 October 2009 10:09 by hadi

 

ASP.NET MVC 2 allows you to do data validation, either using the de-facto Data Annotations or plugging in your own, much in the same way xVal work. If you’re interested in seeing how that works, take a look at this post.

This post however concerns testing. Here’s some code:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Customer customer)
{
    if (ModelState.IsValid)
    {
    return RedirectToAction("Index");
    }
    return View(customer);
}

This code checks to see if my model is valid. If it is, it then saves it (not in the code) and redirects to the index action, thus producing a RedirectToActionResult. If it is not valid, it will return a ViewResult. Here’s the model:

public class Customer
{
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
}

Given the previous, what would you expect the following test to do? Pass or fail?

    [Fact]
    public void wont_give_you_any_hints()
    {
    var controller = new CustomerController();
 
    var customer = new Customer();
 
    customer.FirstName = "Jak a.k.a. Casey";
    customer.LastName = String.Empty;
 
    var result = controller.Create(customer);
 
    Assert.IsType(typeof(ViewResult), result);
    }

I’ll give you a hint. It fails. Now I understand why it fails. My problem however is that for me to test my model is valid is going to force me to change the way I have to write my code, and potentially make it less readable.

Tags:  
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (2) | Comment RSSRSS comment feed

Problem with Client-Side Validation in MVC 2

Wednesday, 7 October 2009 20:31 by Hadi

 

[Note: This post applies to ASP.NET MVC 2, Preview 2.0]

Today while doing the demo for the previous post, I ran into an issue where the Javascript code for the client-side validation (the call to EnableClientValidation ) was not being output during the form rendering.

Take a look at the following two snippets:

First:

    <% Html.BeginForm();%>
 
        <%=Html.EditorForModel() %>     
            <p>
                <input type="submit" value="Save" />
            </p>
    <% Html.EndForm(); %>

 

Second:

  <% using (Html.BeginForm()) {%>
 
        <%=Html.EditorForModel() %>     
            <p>
                <input type="submit" value="Save" />
            </p>
    <% } %>

 

See the difference? The latter is using the using statement. In my previous post I’m using this option and all works well. However, if you go with the first option, the Javascript call will not be output. The reason for this (after debugging the source) is that the call to make this happen takes place in the Dispose method of the MvcForm. Explicitly calling Html.EndForm won’t cause this to take place.

I’ve talked to Mathew from the QA team, and he’s confirmed it’s a known issue. I think the output of the JS code should ideally be decoupled from the form construction. For instance, If I were to use a manual form tag, this wouldn’t work either [I’ve haven’t given it that much thought either].

In the meantime, if you want client-side validation, make sure you use the second option.

Tags:  
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (3) | Comment RSSRSS comment feed

Client-Side Validation in MVC 2

Wednesday, 7 October 2009 07:31 by Hadi

 

ASP.NET MVC 2 Preview 2 now ships with client-side validation built into the box. It follows the same idea as the xVal framework whereby you can define validation rules once and have them enforced both on the server and the client.

By default, MVC uses Data Annotations which is available in System.ComponentModel.DataAnnotations on the server and the jQuery Validator plugin on the client. Much like xVal you can customize these to use whatever you want. I’m preparing some demos for next week of how to do client-side validation and since there isn’t much info on it, I’ve decided to post it.

Server-Side Validation

Server-side validation with Data Annotations works without having to take any additional steps. You decorate your model using attributes and the model binder uses this information to set the ModelState.

    public class Customer
    {
        [Required(ErrorMessage = "First name is required")]
        public string FirstName { get; set; }
        [Required(ErrorMessage = "Last name is required")]
        public string LastName { get; set; }
        public string Email { get; set; }
    }

 

On the server-side you would do the usual to check if the model state is valid and if not display validation messages back to the client:

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(int id, Customer customer)
        {
            if (ModelState.IsValid)
            {
                // TODO: Do whatever...
                return RedirectToAction("Index");
            }
            return View(customer);
        }

 

The form is:

    <%= Html.ValidationSummary() %>
    <% using (Html.BeginForm()) {%>
  
        <%=Html.EditorForModel() %>     
            <p>
                <input type="submit" value="Save" />
            </p>
    <% } %>
 

(I’m using the EditForModel which will automatically generate an input field for each property of the model. If you want finer control you can spit out individual fields or use templates).

Client-Side Validation

Client-Side validation kicks in only if it is explicitly activated in the view. To do this, you need to call EnableClientValidation as shown below:

  
    <% Html.EnableClientValidation(); %>
    <%= Html.ValidationSummary() %>
    <% using (Html.BeginForm()) {%>
  
        <%=Html.EditorForModel() %>     
            <p>
                <input type="submit" value="Save" />
            </p>
    <% } %>

 

By doing this, when the form is generated, the MVC framework will add a call to JS function EnableClientValidation passing in the correct parameters based on the data annotation attributes defined on the model. Last but not least, we need to include 3 Javascript files in the View (I normally put them in Site.Master).

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

 

Make sure you include the last file, where EnableClientValidation is defined. That’s all there is to it. Once you run this, your app will have both client side and server side validation using the default Data Annotations and jQuery Validator.

Download demo from here

Tags:  
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (5) | Comment RSSRSS comment feed

ASP.NET MVC 2 - Preview 1

Friday, 31 July 2009 06:42 by hadi

It's out. You can download it from here. Some of the new things it includes ("extracted" from the readme for your convenience):

 

  • Areas: When creating larger ASP.NET MVC applications, you tend to create controllers and views that might be named the same but belong to different aspects of the application (for example you might have a HomeController for Customers and one for Administration). Areas allows you to create "sub-projects" inside your project to group these.

 

  • [HttpPost]: Shortcut for putting [AcceptVerbs(HttpVerbs.Post)]

 

  • DataAnnotations: The default model binder supports DataAnnotations for validation

 

  • DefaultValueAttribte: For types of Int32, DateTime or Guid's you can now specify a default value on the action declaration to better comply with your routing patterns.

 

  • Supprot for byte[] and Data.Linq.Binary: Default Model binder now supports these types.

 

  • API improvments

 

  • Templated Helpers: Basically allows you to associate types to certain elements for display/editing.

 

The only breaking changes it seems is introduction of the Area keyword and a signature change in DefaultControllerFactory. That means if you're using a custom controller factory for IoC for example (and if you're not, you should be), you'll need to update your app.

There's nothing in the README regarding the inclusion of the strongly-typed helpers from the Futures assembly or any new strongly-typed Html Helpers for element rendering. Not sure if they are included in this assembly or might come in the next preview.

Now to go play with it a little...

Tags:  
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (4) | Comment RSSRSS comment feed