Saturday, 31 December 2011

Razor extension method Each

It is possible to augment razor views with not only helpers, but also razor extension methods.

In this example, an extension method which will take a template and from this template generate a rendered result of a list of the IEnumerable of items passed in for the extension method will be presented. It is named Each and was created by Phil Haack.

I will present the source code quickly to just repeat Phil Haack's code. Let's first add a new class called IndexedItemModel:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TestActionMethodSelectorAttribute.Extensions
{
public class IndexedItem<TModel>
{
public IndexedItem(int index, TModel item)
{
this.Index = index;
this.Item = item;
}

public int Index { get; private set; }
public TModel Item { get; private set; }

}
}


Let's add the extension method next:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.WebPages;

namespace TestActionMethodSelectorAttribute.Extensions
{

public static class RazorCollectionExtensions
{

public static HelperResult Each(this IEnumerable<TItem> items,
Func<IndexedItem<TItem>, HelperResult> template)
{
return new HelperResult(
writer =>
{
for (int i = 0; i < items.Count(); i++)
{
template(new IndexedItem<TItem>(i, items.ElementAt(i))).WriteTo(writer);
}
}
);
}

}

}


An example of its usage is shown next in a view:



@{
ViewBag.Title = "Home Page";

var cars = new []
{
new { name = "Audi", color = "Blue", make = "A4" },
new { name = "BMW", color = "Black", make = "M5" },
new { name = "Volvo", color = "Red", make = "240" },
new { name = "Renault", color = "Black", make = "19" }
};

}

@cars.Each(@<li>Car is an @item.Item.name @item.Item.make of color @item.Item.color</li>)



Take note of the "magic" @item property in use here. What we see here in effect is a convenient way to iterate over a list of objects, in this case an array of anonymous objects which we call "cars" and we just add in some car objects to this array using a collection initializer. Then we output this list with our new Each method which is a razor extension method and specify our template. You need to prefix the first letter in the parenthesis with the @ sign, then use @item to refer to the object. In our Each method we use IndexedModel type for each item in the list. This got both an index and an Item of type TModel (TItem) passing in our item type, in this case the anonymous type that constitutes the "cars" object.

Thanks to Phil Haack for this nice method! I like this Each method a lot. No need to write that long @foreach razor helper any more. This also should fit nicely into linq expressions like:
@Model.MyList.Where(myItem => myItem.Age > 19).Each(@
<li>@item.Name </li>)
to output a list of the name propery for all people above 19 years old in our Model.MyList property, just to take an example.

This nice method was presented by Phil Haack here:



Note for those viewing this video, not everything went smooth for Phil Haack in this demonstration, however there were lots of "hidden gems" he presented there at the MIX11 conference in Las Vegas.

Disclaimer: I added this blog post to extract the source code from his demo into an easily available sample.

It should be relatively easy now to start creating Razor extension methods as an alternative to HTML helpers and Razor html helpers in MVC by taking a look at this example. Note the use of HelperResult and WriteTo (corresponding Response.Write in ASP.NET).

Friday, 30 December 2011

Analyzing routing in your MVC application

Routing and ASP.NET MVC woes !!!

So you have created a MVC application and worked on it a bit, and now your Global.asax contains calls to a setup of your RouteCollection that has got complex logic inside it and now you need to understand your routing better and perhaps fix that particular scenario where routing does not seem to work (keep in mind for instance that the first match algorithm is used when using your MVC routing table). How to understand those routes in a better way without staring at your code. How about interpreting it at realtime using a runtime debugger for just that case. First off, download the
ASP.NET MVC Routing Debugger Visualizer tool.

Go to the following url:
http://visualstudiogallery.msdn.microsoft.com/2993e666-4534-49c8-807f-e8bffcaee7e0

Keep in mind that this should be easily installed in Visual Studio 2010 using the Tools => Extension Manager dialog in DevEnv.

Now we need to "patch" your system to allow this tool to work.

First off edit the devenv.exe.config file to allow loading remote sources:
Open the file
C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe.config

Inside the runtime xml element node add the following:
<loadFromRemoteSources enabled="true" />

Just to double check, check that the dll is added to the following folder:
C:\Program Files\Microsoft Visual Studio 10.0\Common7\Packages\Debugger\Visualizers

There should now be a file called MvcRouteVisualizer.dll in this folder, this is the library which constitutes the ASP.NET MVC Route debugger visualizer tool.

Start the MVC application with debugging turned on and add a breakpoint in a MVC controller action, I tested this tool out with the HomeController About action in my basic templated ASP.NET MVC application for instance. Hit Ctrl+D+Q (quickwatch) and add a watch to the System.Web.Routing.RouteTable.Routes object (which is a collection of the routes to monitor for our app) and hit the available magnify icon button to the right of the value column of our watch window in our debugger.

If all now went well, you should have this nifty tool to display the routes in our MVC app. This way, if the routing seem to have gone berserk and you cant understand why your nice routing table is not correctly set up, MVC Route visualizer routing tool comes to your rescue.

Here is a screenshot of this great tool, happy coding!

Wednesday, 28 December 2011

Creating custom ActionResult

It is possible to inherit the ActionResult class and create a custom ActionResult.
The following class creates a new kind of ActionResult for spewing out the serialized string of an inputted data contract instance.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Runtime.Serialization;

namespace TestActionMethodSelectorAttribute.ActionResult
{

public class DataContractSerializedResult : System.Web.Mvc.ActionResult
{

private object data;

public DataContractSerializedResult(object data)
{
this.data = data;
}

public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.ContentType = "text/xml";
DataContractSerializer serializer = new DataContractSerializer(data.GetType());
serializer.WriteObject(response.OutputStream, data);
}
}

}


You will need to add a reference to the System.Runtime.Serialization assembly and namespace. We use DataContractSerializer to serialize the object to a string value. The stream in use is the context.HttpContext.Response.OutputStream, where context is the ControllerContext (current).

It is required to set the ContentType to "text/xml" to output xml.

Usage, adding a test method to homecontroller (ignore Hungarian notation, this is for demonstration purposes..) :


public DataContractSerializedResult About2()
{
return new DataContractSerializedResult(
new AgeNameDataContract
{
Age = 93,
Name = "Gamla Olga"
});
}


Then we get the xml outputted of the data contract passed in:



The morale of the story, to create a new kind of ActionResult:

- inherit from ActionResult
- implement abstract method ExecuteResult

Timing your MVC Actions

Add the following attribute to your MVC actions to view the timing of your mvc actions using System.Diagnostics.Stopwatch class.

This is another filter attribute example.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Diagnostics;

namespace TestActionMethodSelectorAttribute.Attributes
{
public class StopwatchAttribute : ActionFilterAttribute
{
private Stopwatch _stopWatch;

public StopwatchAttribute()
{
_stopWatch = new Stopwatch();
}

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
_stopWatch.Start();
}

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
_stopWatch.Stop();
var response = filterContext.HttpContext.Response;
response.AddHeader("X-elapsed-milliseconds", _stopWatch.ElapsedMilliseconds.ToString());
}
}
}


Usage (homecontroller):


[Stopwatch]
public ActionResult About()
{
return View();
}


It is nice to output the elapsed time in millisecond in the http headers, since we then easily can monitor the values outside Visual Studio, in our browser:

Using ActionMethodSelectorAttribute in MVC

If you want an MVC controller action to be only available for Ajax methods, use theAjaxMethodSelectorAttribute. Inherit this abstract class to create the attribute AjaxOnlyAttribute below and tag this attribute with your method:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace TestActionMethodSelectorAttribute.Attributes
{
public class AjaxOnlyAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
return controllerContext.HttpContext.Request.IsAjaxRequest();
}
}
}


Usage (testing the attribute out in HomeController):



[AjaxOnly]
public ActionResult About()
{
return View();
}


If the current request is not an AjaxRequest, a Http 404 is returned. The attribute [HttpPost] and [HttpGet]is inherited from the ActionMethodSelectorAttribute. They also implement the abstract method IsValidForRequest.

Sunday, 25 December 2011

Asynchronous MVC controllers end to end example

=== PREAMBLE ===

My intended audience:

1) You are a programmer or articial being understanding code (probably the former)
2) You work with ASP.NET MVC
3) You must take in use asynchronous processing to handle a slow and time consuming
MVC action and want to learn how to implement an AsyncController.


If this is the case, please read on!

== PREAMBLE ===


I guess many of you know how to create an ordinary MVC controller inheriting from System.Web.Mvc.Controller class, but what about creating an Asynchronous MVC controller?

It is possible to opt-in asynchronous controllers in MVC out of the box of the MVC framework. This will be a code sample of how this is possible. The goal of the asynchronous controller will be to provide better scalability, especially for complex calculations that take long which are accessed by many simultaneous users. Beware though, the standard synchronous design is easier to relate to and will be suitable in many standard scenarios. Asynchronous controllers should only be applied where there is a good reason to expect bottlenecks to be present in the code and in a real production environment.

Moving on to the asynchronous controller. Instead of inheriting from the controller class, inherit from the System.Web.Mvc.AsyncController class in MVC. The following code shows how to create an asynchronous controller.

Code sample follows:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Threading;

namespace SubstitutePartInCompositionContainer.Controllers
{
public class TestAsyncController : AsyncController
{


[AsyncTimeout(60000)]
public ActionResult IndexAsync()
{
AsyncManager.OutstandingOperations.Increment();
ThreadPool.QueueUserWorkItem((s) =>
{
ServiceReference1.NewsServiceClient client =
new ServiceReference1.NewsServiceClient();

TempData["news"] = client.GetSomeNews("Steinkjer");
AsyncManager.OutstandingOperations.Decrement();
}, null);

return View();
}

public ActionResult IndexCompleted()
{
ViewBag.DateStamp = DateTime.Now;
ViewBag.News = TempData["news"] as string;
return View();
}

}
}



The class in this example is called TestAsyncController. It inherits from the AsyncController class. The class contains two action methods which is called IndexAsync and IndexCompleted. In general, for every asynchronoous MVC action, there must be two method suffixed with Async and Completed, just like every controller must be suffixed with Controller (part of the design by contract conventions in MVC).

I put the attribute [AsyncTimeout(60000)] here, it is possible to specify in milliseconds how long an async timeout should be allowed to execute before timing out. It is also possible to use the attribute [NoAsynctimeout] instead.

Further on, I use the static method ThreadPool.QueueUserWorkItem to add an asynchronous call in the current Thread Pool. I use the AsyncManager.OutstandingOperations.Increment() and corresponding Decrement() methods to keep track of the pending asynchronous calls. AsyncManager is part of System.Web.Mvc.Async namespace. This book keeping is required for correctly arriving at the Complete method that will receive the asynchronous result. For convenience, I move the result to the TempData dictionary. This will be available for me in the Complete method in my controller. Since the data I get is a string, I just copy it to the ViewBag (dynamic object) and this is then just displayed in the MVC view Index.cshtml in the folder TestAsync.

Here is the service contract for the NewsService used (WCF service):


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace TestServices
{

[ServiceContract]
public interface INewsService
{

[OperationContract(AsyncPattern=true)]
IAsyncResult BeginGetSomeNews(string city, AsyncCallback callback,
object asyncState);

string EndGetSomeNews(IAsyncResult result);

}

}



As you can see, the WCF service tags the operation BeginGetSomeNews with the AsyncPattern equals set to true to allow asynchronous execution. Not only will the IIS service not receive a blocking call, the service itself is also run asynchronous in this case. The WCF service also got a pair of methods this time prefixed with Begin and End. Only the Begin method is attributed with [AsyncPattern=true], the end method is not even attributed with OperationItem attribute without any overloads. This is because the end method is just a callback for the Begin method. As in asynchronous programming, the Begin method starts by receiving its parameters, followed by AsyncCallback callback, object asyncState paramteters. The End method returns string in this case and also receives such an object.

The service implementation looks like this:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading;

namespace TestServices
{

public class NewsService : INewsService
{

public IAsyncResult BeginGetSomeNews(string city, AsyncCallback callback,
object asyncState)
{
Thread.Sleep(3000); //simulate some sleep
return new
CompletedAsyncResult("Here are some news for " + city);
}

public string EndGetSomeNews(IAsyncResult result)
{
var resultFromAsync = result as CompletedAsyncResult;
return resultFromAsync.Data;
}

}

}



I use a class called CompletedAsyncResult, this looks like this (MSDN is the source):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace TestServices
{

public class CompletedAsyncResult : IAsyncResult
{
T data;

public CompletedAsyncResult(T data)
{ this.data = data; }

public T Data
{ get { return data; } }

#region IAsyncResult Members
public object AsyncState
{ get { return (object)data; } }

public WaitHandle AsyncWaitHandle
{ get { throw new Exception("The method or operation is not implemented."); } }

public bool CompletedSynchronously
{ get { return true; } }

public bool IsCompleted
{ get { return true; } }
#endregion
}
}


Then, I just added a Service Reference to the WCF class library containing my service to generate a proxy or service agent to access my WCF service in my controller, as seen in the first code.

Important GOTCHAS about asynchronous MVC controllers:


  • There is no explicit call between the Async and Completed method in the MVC controller inheriting from AsyncController. This is code by design or contract.

  • We must "help" MVC keep track of the outstandingoperations for the AsyncManager in our code. When the counter turns to zero again, the async operation decrementing the value last will call its Complete method.. Use AsyncManager throughout.

  • Google blogger does not handle generic arguments well, but the CompletedAsyncResult object takes string as a generic type argument in my demo code here. It could be a complex type such as a data contract.

  • There are many more methods of achieving this, this is just one example.

Friday, 16 September 2011

Simple access of embedded resources in DLLs in MVC views

I was working with embedded views in a DLL in a MVC Razor 3 project today and I had to be able to refer to embedded Javascript .js files, images (jpg and png) and css files in the precompiled views. To make this work I tagged the files as Embedded Resource in my project, compiled the project into a dll and in the other mvc project which used the dll I could get it to fetch the embedded resources easily adding a new MVC controller action.

The mvc controller action looks like this:

The code below goes into the Home controller, ContentFile action method, which
returns a FileStreamResult below.



public FileStreamResult ContentFile(string id)
{
string resourceName = Assembly.GetExecutingAssembly().GetManifestResourceNames().ToList().FirstOrDefault(f => f.EndsWith(id));
return new FileStreamResult(Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName), GetMIMEType(id));
}

private string GetMIMEType(string fileId)
{
if (fileId.EndsWith(".js"))
{
return "text/javascript";
}
else if (fileId.EndsWith(".css"))
{
return "text/stylesheet";
}
else if (fileId.EndsWith(".jpg"))
{
return "image/jpeg";
}
return "text";
}


To use this in the views, write this:



<script type="text/javascript" src="/Home/ContentFile/test.js">
</script>

<link rel="Stylesheet" href="/Home/ContentFile/blue.css">

<img src="/Home/ContentFile/forest.jpg" />



To load up an embedded resource we look into the executing dll, which instead should perhaps load a specified assembly if necessary, and then GetManifestResourceStream and retrieving the matching resource name passed in. The MIME type must be set and is resolved by looking at the resource name passed in.

So the morale is that if you want to load a content file from a DLL in a MVC view, use a controller action and return a FileStreamResult and then load up the content file by writing the route to the ContentFile action.

Sunday, 11 September 2011

Testing out the WatiN unit testing

WatiN, or "Web application testing in .Net", is based on a similar package for Ruby on Rails called WatiR. This is a browser automation package that gives the ability to run say a MsTest where you open up an url in Internet Explorer 6,7,8 or 9 or Firefox 2 or 3, then locate a gui element in a web page by its id and write in some text, if it is textbox and click a button. This is making it possible easily write GUI tests for web applications running in an IE or FireFox environment, covering most users. WatiN also gives logging options and makes it possible to create screenshots and so on.

Lets start with a equivalent "Hello world" unit test using WatiN.

First off, create a new Mvc 3 Web Application, select Internet Application as the template, choose to add a unit test. Check that you got Nuget insstalled.

Then write in the Nuget console:


Install-Package WatiN


This will download the necessary DLL files to the unit test project and add to its references. These DLL files are:



  • Interop.SHDocVw - Mark in the references this DLL and choose Embed Interop Types to false.


  • WatiN.Core


  • WatinUnitTest



Now add a unit test or basic unit test and then write the following test method
inside your test class:



[TestMethod]
public void TestLogInToMrs()
{
string targetServer = "http://mrx.hex.no";
using (var browser = new IE(targetServer))
{

LogintoCerebralParese(targetServer, browser);
}
}

private static void LogintoCerebralParese(string targetServer, IE browser)
{
browser.ShowWindow(WatiN.Core.Native.Windows.NativeMethods.WindowShowStyle.ShowMaximized);
browser.Link(l => l.Url == targetServer + "/CerebralPareseRegister").Click();
browser.TextField(t => t.Name == "ctl00$ContentPlaceHolderMain$RoleComboBox").SetAttributeValue("readonly", "");
browser.TextField(t => t.Name == "ctl00$ContentPlaceHolderMain$RoleComboBox").TypeText("Registeransvarlig");
browser.Button("ContentPlaceHolderMain_LoginButton").Click();
}



In this example, an instance of an IE object is instantiated inside the using block. The url specified in the constructor argument is requested. Then the unit test
maximizes the window, then it will search on the login page for a Link object (basically searching for the A tags) by url matching CerebralPareseRegister.
It will then look for a TextField, again using a lambda overload (Linq is supported in WatIN, which is written in C#), overriding its readonly html property using the SetAttributeValue method and setting readonly to empty string, unlocking the readonly textbox. Then it writes in "Registeransvarlig" (a role in my test scenario) in the textfield, using the TypeText method with the argument passed into the text box. The last line looks for a button, i.e. an input tag element with id equal to the passed in argument and invokes the click method which will click the button.

The test then will check that it is possible to login to this registry. Without giving out to much details to our global audience, we got web registries which there will be about 50 registries later and this single test will test logging into a single registry (CerebralPareseRegistry). We would then probably test all 50 registries and verify that we can log in to the different registries. The Internet Explorer browser is not thread safe and therefore there is a risk that unit tests running in parallel will crash the IE browser. The good thing then, is that when using the IE browser in these parallel tests, they will run in STA (Single thread apartment) and therefore it will avoid the possible crash. An optimization is in the TestInitialize method use the same IE object and then dispose it in the TestComplete method. Instead, use a single IE object per test to keep thread safety. This will increase the test time. The good thing is that these automated web gui tests can be run in automatic mode and for example runned every night in the nightly build. The WatiN framework makes it therefore possible to do full integration unit tests using browser automation so that you can verify that the web application is working for the end user for its core functionality, such as log in to a web application, perform a search and so on.

The WatiN tests should be testing the core end-user functionality. The different parts of your web application, for example a MVC 3 application, should also have unit tests of their own.

As I have suggested in previous posts, the MvcContrib TestHelper should be used when testing Controllers and their actions in MVC 3. Unit tests in javascript can use the helper class of Stephen Walther. The views can also use the Razor Single File Generator to tests their views. Finally testing the DAL layer Entity Framework supports testing POCO objects using the Seed function if you use Entity Framework Objects.

WatiN supports a multitude of functionality and this blogpost just wanted to mention it.

Check out the http://watin.org website to see the documentation of WatiN and download the package, if you do not want to use Nuget. WatiN is open source and therefore fully customizable.

Tuesday, 6 September 2011

Adventures with the MvcContrib TestHelper

Unit testing a MVC Controller
When unit testing a MVC controller, stop reinventing the wheel and take a look at the MvcContrib TestHelper. Add a reference to the MvcContrib.TestHelper.dll and unit testing different functionality of your controller and its actions should be a walk in the park. Yes, using Moq to build up a mocked object is possible, but since MvcContrib TestHelper supports much of the needed functionality, why not start using it?

How to start using the MvcContrib TestHelper?
Download the MvcContrib TestHelper with the MvcContrib release package from this location: Mvc Contrib

Install the MVC contrib zipped file. Actually there is no installer, just a bunch of DLL files. It is the file MvcContrib.TestHelper.dll that you are interested in. Add this dll as a reference to the Visual Studio 2010 test project in your solution (remember to add this file to your solution by saying "Copy to output folder" and modify your WiX scripts, if needed), then create a new basic unit test or unit test and at the top add the using statement:


using MvcContrib.TestHelper;



Verify that the view result is returned and view name and model type matches in a unit test for a MVC action


Given that we have modified the Index mvc view to be strongly typed by a class Bird in our Models folder, the following code can verify in a single assertion that the returned ActionResult is a ViewResult, that the rendered view name is "Index" and that the model, that is the strongly type that the view is associated with is a given type as follows:


[TestMethod]
public void IndexTestViewResult()
{
var controller = new HomeController();
ActionResult result = controller.Index();
result.AssertViewRendered().ForView("Index").WithViewData();
}



First off, I just new my controller I want to test, HomeController in this case.
Then using the extension methods in MvcContrib.TestHelper I call AsserViewRendere() which just asserts that ActionResult is of type ViewResult. Further, I check with the ForView extension method (take note of the chaining going on here) that the view name is Index. The third part of this single assert checks that the View data is of type Bird.

In this particular example, make note that my Index method looks like the following in my HomeController:


public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";

return View("Index", new Bird { SpeciesName = "Crow",
CanFly = true, WeightInGrams = 400, WingspanInCentimetres = 80 });
}

.
.
.

}


Obviously the Bird class is just a simple sample in this case.. The second argument
could be assigned to variable called model and passed in for cleaner code. The point I want to make here is that when you return a ViewResult, specifically specify the View Name explicitly, as this then can be verified with the ForView extension method in a unit test.

For more advanced controller tests there are lots of functionality in MvcTestContrib.TestHelper DLL to help out. Do not reinvent the wheel to get started with unit testing your controllers, use MvcContrib TestHelper!

Towards more complex controller action tests in MVC


Just to get started with a custom HttpContext, I wanted to test out the TestControllerBuilder class in MvcContrib.TestHelper. With this class, I adjust the unit test for the index action method a bit:


[TestMethod]
public void IndexTestViewResult()
{
TestControllerBuilder builder = new TestControllerBuilder();
var controller = builder.CreateController();
builder.HttpContext.Cache["test"] = "test1";
builder.InitializeController(controller);
ActionResult result = controller.Index();
result.AssertViewRendered().ForView("Index").WithViewData();
}


Now, I use the TestControllerBuilder class to create a controller of type HomeController. The builder is then tested out with setting the HttpContext.Cache to a test key-value pair. Further on, the line above instantiates the HomeController by using the CreateController static generic factory method by passing in the home controller as a generic type argument. Then the controller is initialized with the TestControllerBuilder. The unit test passes. Obviously, this just show how the HttpContext can be mocked using the TestControllerBuilder.

One important note here is the strange error I got thrown at me when running the test the first time.

Test method TestMvcContribUnitTests.Tests.Controllers.HomeControllerTest.IndexTestViewResult threw exception:
System.InvalidOperationException: Unable to create a factory. Be sure a mocking framework is available.


To avoid this error and get the test to pass, add also a reference to a mocking framework. By glancing into the code at the Mvc Contrib Codeplex page, I see that Rhino Mocks and Moq is the two mocking frameworks with support for TestHelper in MvcContrib. Since I have worked most with Moq, I just added a reference to Moq.dll (copy a reference to the Moq.dll assembly file, copy local set to true), and then the test passed.

This now, shows how to get a HttpContext which can be adjusted (Request, Response, Cache and so on), using Moq and MvcContrib TestHelper. The developer can then focus on the task at hand when it comes to unit test, namely to write efficiently unit tests that are relevant and not reinvent the wheel to get HttpContext up and running in Moq, without using MvcContrib TestHelper.

I will look into additional adventures of using MvcContrib TestHelper. If there are other use-case scenarios that should be presented, it would be nice to know.



Testing a RedirectToAction inside a mvc controller action


To test the redirection of an action inside a mvc controller action, use the
following:

Suppose we have return the following:


..
return RedirectToAction("About");
..


The test can then verify that we are returning a RedirectToActionResult and that
the controller action's name is "About" as follows:


..
result.AssertActionRedirect().ToAction("About");
..


In case we return a RedirectToActionResult with overload:


..
return RedirectToAction("About", "Home");
..


To test this we can write:


..
result.AssertActionRedirect().ToController("Home").ToAction("About");
..


Testing the routing in an MVC application


To test out the routes in your MVC application, the following unit test is served as an example using MvcContrib TestHelper:



[TestMethod]
public void RouteTestHomeIndex()
{
var routeTable = RouteTable.Routes;
routeTable.Clear();
routeTable.MapRoute(null, "{controller}/{action}/{id}",
new { controller= "Home", action= "Index",
id = UrlParameter.Optional });

"~/Home/Index".ShouldMapTo(action => action.Index());
"~/Home/About".ShouldMapTo(action => action.About());
}



First line of the unit tests grabs a reference to the RouteTable.Routes property, defined in the System.Web.Routing namespace. The routetable is then cleared and then
the MapRoute method adds a route definition to test. We set up the default route using the MapRoute method. Then we test the two routes "~/Home/Index" and "~/Home/About". These two values are strings and MvcContrib TestHelper has extension method which will check that the route specified in the string maps to a controller using the ShouldMapTo extension method with a generic argument specifying the controller, and in the parameter the action method of the contorller is specifed. Actually, controller => controller.Index is probably a better lambda argument here.

This shows that testing out routes are simple using MvcContrib TestHelper. Just use the string extension methods to test out which controller and which method a certain route should take.

Monday, 5 September 2011

Additional methods in the unit testing of Javascript

More methods to the unit testing of javascript
I am building upon the great example of unit testing in javascript by Stephen Walther, and will now present additional methods to the JavascriptUnitTestingFramework.js file he presented.

Let me first list up the new contents:



var assert = {

areEqual: function (expected, actual, message) {
if (expected !== actual) {
throw new Error("Expected value " + expected
+ " is not equal to " + actual + ". " + message);
}
},

areNotEqual: function (expected, actual, message) {
if (expected === actual) {
throw new Error("Expected value " + expected
+ " is equal to " + actual + ". " + message);
}
},

isTrue: function (actual, message) {
if (!actual) {
throw new Error("The provided actual value" + actual + " is not evaluating to true. " + message);
}
},

isNull: function (actual, message) {
if (actual != null) {
throw new Error("The provided actual value " + actual + " must be null. " + message);
}
},

isNotNull: function (actual, message) {
if (actual == null) {
throw new Error("The provided actual value " + actual + "must be not null." + message);
}
},

isFalse: function (actual, message) {
if (actual) {
throw new Error("The provided actual value " + actual + " must be false. " + message);
}
},

isInstanceOfType: function (actual, type, message) {
if ((actual instanceof type) == false) {
throw new Error("The provided actual value " + actual + " is not an instance of type " + type + ". " + message);
}
},

referenceEquals: function (actual, expected, message) {
if (actual !== expected) {
throw new Error("The provided actual and expected values does not point to the same object. Actual is " + actual + " and expected is " + expected + " " + message);
}
}

};



I have added much of the methods of the Assert class in C#. The Assert class have static methods such as ReferenceEquals, IsTrue, IsFalse, AreNotEqual and so on and these methods have now been added above.


Lets continue with the javascript unit tests using this js file.



//At the start of the file for your javascript unit tests
//add a reference to the unit testing reference file JavascriptUnitTestingFramework.js
//Use the reference element and three slashes.

function testAddNumbers() {
// Act
var result = addNumbers(1, 3);

// Assert
assert.areEqual(4, result, "addNumbers did not return right value!");
}

function testFactorial() {
var result = factorial(5);
assert.areEqual(120, result, "factorial did not return righ value!");
}

function testIsTrue() {
assert.isTrue(110 > 0, "This must evaluate to true for the test to pass.");
}

function testIsNull() {
var city = null;
assert.isNull(city, "Must be null");
}

function testIsNotNull() {
var city = { name: "London" };
assert.isNotNull(city, "Must be not null");
}

function testIsFalse() {
var actual = 4 > 5;
assert.isFalse(actual, "The expression must evaluate to false.");

}

function testIsInstanceOfType() {
assert.isInstanceOfType(new String("mystring"), String, "The provided actual value must be an instance of type String.");
assert.isInstanceOfType([1, 2, 3, 4], Array, "The provided value must be an
instance of an array.");
}

function testAreNotEqual() {
assert.areNotEqual("abc", "abbc", "Provided expected value and actual value are not equal");
}

function testAreEqual() {
assert.areEqual("def", "def", "The two provided values does not agree.");
}

function testReferenceEquals() {
var a = { city: "Manchester" };
// var c = { country: "Ireland" };
var b = a;
assert.referenceEquals(a, b, "The two objects does not point to the same object.");
}



The unit tests written in C# then looks like this:



[TestMethod]
public void TestFactorial()
{
var jsHelper = new JavaScriptTestHelper(this.TestContext);

jsHelper.LoadFile("JavaScriptUnitTestFramework.js");
jsHelper.LoadFile(@"..\..\..\MvcApplication1\Scripts\Math.js");
jsHelper.LoadFile("MathTest.js");

jsHelper.ExecuteTest("testFactorial");

}

[TestMethod]
public void TestIsTrue()
{
var jsHelper = new JavaScriptTestHelper(this.TestContext);

jsHelper.LoadFile("JavaScriptUnitTestFramework.js");
jsHelper.LoadFile(@"..\..\..\MvcApplication1\Scripts\Math.js");
jsHelper.LoadFile("MathTest.js");
jsHelper.ExecuteTest("testIsTrue");
}

[TestMethod]
public void TestIsNull()
{
var jsHelper = new JavaScriptTestHelper(this.TestContext);
jsHelper.LoadFile("JavaScriptUnitTestFramework.js");
jsHelper.LoadFile(@"..\..\..\MvcApplication1\Scripts\Math.js");
jsHelper.LoadFile("MathTest.js");
jsHelper.ExecuteTest("testIsNull");
}


[TestMethod]
public void TestIsNotNull()
{
var jsHelper = new JavaScriptTestHelper(this.TestContext);
jsHelper.LoadFile("JavaScriptUnitTestFramework.js");
jsHelper.LoadFile(@"..\..\..\MvcApplication1\Scripts\Math.js");
jsHelper.LoadFile("MathTest.js");
jsHelper.ExecuteTest("testIsNotNull");
}

[TestMethod]
public void TestAreEqual()
{
var jsHelper = new JavaScriptTestHelper(this.TestContext);

jsHelper.LoadFile("JavaScriptUnitTestFramework.js");
jsHelper.LoadFile(@"..\..\..\MvcApplication1\Scripts\Math.js");
jsHelper.LoadFile("MathTest.js");
jsHelper.ExecuteTest("testAreEqual");
}

[TestMethod]
public void TestIsFalse()
{
var jsHelper = new JavaScriptTestHelper(this.TestContext);

jsHelper.LoadFile("JavaScriptUnitTestFramework.js");
jsHelper.LoadFile(@"..\..\..\MvcApplication1\Scripts\Math.js");
jsHelper.LoadFile("MathTest.js");
jsHelper.ExecuteTest("testIsFalse");
}

[TestMethod]
public void TestIsInstanceOfType()
{
var jsHelper = new JavaScriptTestHelper(this.TestContext);
jsHelper.LoadFile("JavaScriptUnitTestFramework.js");
jsHelper.LoadFile(@"..\..\..\MvcApplication1\Scripts\Math.js");
jsHelper.LoadFile("MathTest.js");
jsHelper.ExecuteTest("testIsInstanceOfType");
}

[TestMethod]
public void TestAreNotEqual()
{
var jsHelper = new JavaScriptTestHelper(this.TestContext);
jsHelper.LoadFile("JavaScriptUnitTestFramework.js");
jsHelper.LoadFile(@"..\..\..\MvcApplication1\Scripts\Math.js");
jsHelper.LoadFile("MathTest.js");
jsHelper.ExecuteTest("testAreNotEqual");

}

[TestMethod]
public void TestReferenceEquals()
{
var jsHelper = new JavaScriptTestHelper(this.TestContext);
jsHelper.LoadFile("JavaScriptUnitTestFramework.js");
jsHelper.LoadFile(@"..\..\..\MvcApplication1\Scripts\Math.js");
jsHelper.LoadFile("MathTest.js");
jsHelper.ExecuteTest("testReferenceEquals");

}



Ok, so as the methods above show that much of the action should take place in the TestInitialize method. I will leave that to figure out for yourself, basically the methods will have some similar Arrange for the individual unit tests.

So what we now have is a basic way of performing unit tests against javascript using MSTest with methods such as AreNotEqual, AreEqual, IsNull, IsNotNull, ReferenceEquals, IsTrue, IsFalse that are available when doing ordinary C# unit tests.

Using Stephen Walter's solution makes the client code developer focus at the task at hand at writing Javascript code and companion unit test. I would not suggest that you unit test the jQuery based javascript "Gui code", since you need to have a document loaded (with companion DOM tree). Instead, what you should unit test of your javascript code would be your custom logic which is kind of independent of the "GUI" and as such is suitable to doing unit tests and TDD. I find myself now using these unit tests as a quick way of performing TDD with javascript. When developing the factorial function for example, I could verify that the code I was writing by remembering my university days of how a factorial function was indeed spot on by executing a unit test. These unit tests are alsovery convenient to modify and executes very quickly, outside any browser and web server.

I will now include a zipped file that contains a Visual Studio 2010 solution with a test project that shows how the unit tests are for javascript code is running under MSTest. You will need Microsoft Visual Studio 2010 with support for test projects to open up the solution, this is not supported in Visual Studio 2010 Express.. Many thanks to Stephen Walther for making the unit testing in javascript possible!

Download the zipped solution with the javscript unit testing framework and companion unit tests in C¤ / javscript here right here from 2Shared drop location:

Download zipped solution here of this article [zip]

Unit testing in Javascript done the right way!

Sunday, 4 September 2011

Unit testing of javascript in MVC 3 application

Goal: Unit testing the javascript code
In todays modern web applications, unit testing all your layers should be a goal. Often a developer unit tests the C#-code, so why only write unit tests for the server code, when the client code (such as javascript) is just as important? The end user uses both, and if there are custom logic in your javascript the code should definately have its own unit tests. In this article I will explain my own little adventure into looking at the possibilities I have to unit test my javascript code.

Initial spin
I have trying to resolve the issue of how to proper unit test javascript code in a MVC application the latest days. Basically I initially started out with the idea of definining which javascript code I would like to load and which unit test I would like to run. I ended up creating a test solution which was essentially working, but I did not like the end result. The good part was that I was using the QUnit unit testing framework that much of jQuery is based upon. I basically wrote the necessary code to define the javascript and the unit tests to run and I then looped through the list to launch off the browser to display results from QUnit. Yes, this works and yes it uses the elegant QUnit framework - but there are several negative sides of this browser launcher approach. The really negative part is that these browser launched tests needs non-automatic supervision. The tester must inspect the results in the browser and there is really a lot of dependendency going on. We need a working browser and web server, so this is not a general unit test. I was striving to find the solution, and in general I wanted to use MS Test, i.e. I wanted to define ordinary unit tests that were "javascript flavored". Before venturing too deep into this seemingly mess, I discovered that somebody else already had thought of this.

Stephen Walter to the rescue
In his blog article, Stephen Walter explains how to do the proper unit test
with MsTest, which is just what I wanted. Best of all, since we now can use MsTest this will support automatic running of unit tests and fits nicely into MSBuild and the rest of the test infrastructure. Finally the javascript code can be put under control! What I then did was read through Stephen Walter's article and test out his complementary solution. It worked perfectly out of the box, and I do not see much changes that needs to be done to make this suit perfect into MVC 3 as Stephen Walter already shows the solution in such an application.

Summing up the article of Steven Walter
I just want to confirm to the rest of the interested party that Steven Walter's solution to unit tests in javascript is working perfectly. I will present his solution in summary form next. First of all, the unit test project added to the MVC
project that should have tests for javascript must have a reference to the Microsoft Script Control. This is an ActiveX COM component. The addon can be downloaded using the link next: Microsoft Script Control 1.0. Once this DLL has been added to the unit test project, you want to add a unit test. This will not be a basic unit test, as this kind of test does not have a TestContext, which will be needed. Second, add a folder called helpers, and add Stephen Walter's helper class for running the javascript code. The javascript code and javascript unit test will not run in a browser envrironment, but use the ScriptControl class. This will behind the scenes actually use the JScript engine which means that the browser in effect we test is Internet Explorer 8. This will actually suit our needs, since the loading of the additional libraries such as jQuery to support cross browser support should also be needed. The plumbing code to set up the ScriptControl with the correct .js library files I would suggest is set up in the TestInitialize method of your unit test, and it should call a common method, preferably also in Helpers folder to load up the "default" jquery javascript files once javascript code that uses jQueryis to be tested. Beware of the ordering of loading the js files. The js files should be as default be built using build type content (we will load up these files using "loose files"). The path pointing to the js files should point to the javascript files in the Content/Scripts folder. In general, javascript that should be tested and be available for the views should in general reside in the Content/Scripts folder for a MVC application. The tests written in javascript is in Steven Walters example put in a folder called JavascriptTests in the test project. This looks like a good practice. In general, the folder structure under Content/Scripts should somehow match the folder structure under JavascriptTests, once one gets more javascript tests added.

In Steven Walther's article there is a specific step of setting up the test settings for the javascript code to deploy a folder for the javascript code during the execution of the test. This step should be carefully read, since the tests needs to find the javascript files during the testexecution. Basically, a .testsetting file needs to be added to the solution to make this possible, so I just refer to the article.

Let me present the helper class which Steven Walter created for instantiating and initializing the ScriptControl instance.



public class JavaScriptTestHelper : IDisposable {

private ScriptControl _sc;
private TestContext _context;

///
/// You need to use this helper with Unit Tests and not
/// Basic Unit Tests because you need a Test Context
///

/// Unit Test Test Context
public JavaScriptTestHelper(TestContext testContext) {
if (testContext == null) {
throw new ArgumentNullException("TestContext");
}
_context = testContext;

_sc = new ScriptControl();
_sc.Language = "JScript";
_sc.AllowUI = false;
}

///
/// Load the contents of a JavaScript file into the
/// Script Engine.
///

/// Path to JavaScript file
public void LoadFile(string path) {
var fileContents = File.ReadAllText(path);
_sc.AddCode(fileContents);
}

///
/// Pass the path of the test that you want to execute.
///

/// JavaScript function name
public void ExecuteTest(string testMethodName) {
dynamic result = null;
try {
result = _sc.Run(testMethodName, new object[] { });
} catch {
var error = ((IScriptControl)_sc).Error;
if (error != null) {
var description = error.Description;
var line = error.Line;
var column = error.Column;
var text = error.Text;
var source = error.Source;
if (_context != null) {
var details = String.Format("{0} \r\nLine: {1} Column: {2}", source, line, column);
_context.WriteLine(details);
}
}
throw new AssertFailedException(error.Description);
}
}

public void Dispose() {
_sc = null;
}



The JavascriptTestHelper class of Steven Walter basically news up a ScriptControl class and contains two methods to load a javscript file (.js) and then exceute the test. Of course, several javascript files can be added. Note that the ScriptControl instance which is a COM object needs to be nulled when disposing the object.

Ok, so this is the class that will be used when writing the [TestMethod] in C# for the javascript test. Basically we must arrange the test using this testhelper to load up the .js files, and then use the test helper to execute the javascript test. The test method name must be added also to the ScriptController instance before starting up.

Every javascript unit test will of course in essence be written in Javascript, the C# based unit test is just a wrapper, the really interesting part is as always in Javscript when it comes to the client code. So each javascript class will then refer to a utility library. Steven Walther gives a very simple example of such a library, which is nothing more than providing a AreEqual function. The unit test written in javascript will then refer to this "library", using the ///
syntax. This library will be in the base path of he JavascriptTests folder for now. The path must point to this JavascriptUnitTestLibrary.js file. The AreEqual method is really simple and the addition of more methods to support different errors should be a overcoming task. I will myself try out addind more such methods. The sad part is that this code does not use QUnit to support more function that Steven Walter's AreEqual metod, but this method covers very much of the needed functionality. I will soon add more examples of unit testing functions soon into this file.

Here is the JavascriptUnitTestLibrary.js file:

var assert = {

areEqual: function (expected, actual, message) {
if (expected !== actual) {
throw new Error("Expected value " + expected
+ " is not equal to " + actual + ". " + message);
}
}

};

The little library does nothing more than define an object with a single method areEqual which will throw an error. The script controller will in the helper class
catch this error and then rethrow it into an AssertFailedException, which MSTest will then recognize and we are getting our fancy detection of errors in Javascript that MSTest will see! Elegant!

So the only thing next when it comes to the javascript unit test is to write the test and use this utility library. Lets add a new test for demonstrational purposes to the addTwoNumbers method Steven Walther was presenting in this article, the factorial of a number, let's put this additional code to MathTest.js (the reference line at the top should only be listed once).

MathTest.js:

///
function testFactorial() {
var result = factorial(5);
assert.areEqual(120, result, "factorial did not return righ value!");
}

This test will then assert that the factorial of five is equal to 120 (check with your calculator!). The MathTest.js file is added to the JavascriptTests folder.

Ok, so next up is then writing the unit test, add a new unit test to the test project
and then write the following:

[TestMethod]
public void TestFactorial()
{
var jsHelper = new JavaScriptTestHelper(this.TestContext);
jsHelper.LoadFile("JavaScriptUnitTestFramework.js");
jsHelper.LoadFile(@"..\..\..\MvcApplication1\Scripts\Math.js");
jsHelper.LoadFile("MathTest.js");
jsHelper.ExecuteTest("testFactorial");
}

If you can't understand why the code in the JavascriptTests are references as seemingly being in the same folder as the unit test (which is one folder up), this is handled by the testsettings file added previously. Refer to Steven Walthers article.

The test method in my file, UnitTest1.cs is then newing up the test helper class
and make note, passes in the testcontext of my unit test, which is why a basic unit
test will not suffice in this case. Then the ordering of loading the js files is
important. First the unit test framework js file is added. Then the javascript
code is added which will be tested. Next up the javascript code that contains the
javascript based test is added. If your javascript code uses a lot of jQuery libraries, additional js files should be added before the user provided javascript
code. The ordering is as previously mentioned important, and the paths should be correct. Basically one wants to go up three levels of the current directory and then go into the Scripts or Content/Scripts folder to the target .js file. I really suggest that the Scripts folder should be the place that custom javascript is added and that the .js files that the user creates should be in sub folders here. The base directory of the Scripts folder should only contain the jquery libraries and similar, not the user based code, as this is not very scalable as the web project grows..

Finally the ExecuteTest is called and the parameter provided is the name of the javascript test.

I also of course had to add the factorial function in the Math.js. This code looks like this:


function factorial(n) {
if (n > 1) {
return n * factorial(n - 1);
}
else {
return 1;
}
}

This factorial function uses recursion to return the factorial of a number. The code is almost the same as a C# based function for the factorial.

Then I just ran the unit test with Ctrl+R and Ctrl+T and saw it pass in the test results. Great stuff Steven Walther! I believe this is the correct way to do unit tests in javascript, i.e. not using QUnit.

The next obvious task is to implement more code to Steven Walther's JavascriptUnitTestLibrary.js file. This should be a near future task I will look into.

I have looked at other parts of unit testing MVC applications. Unit testing controllers are actually very good supported, as these are ordinary classes, which requests can be mocked. The unit testing of views is possible using the RazorSingleFileGenerator or RazorGenerator extension (although many means that unit testing a MVC view should be avoided).

One open issue is how to unit test a MVC 3 Razor helper, I will look into this perhaps using RazorSingleFileGenerator extension in the near future..



Friday, 5 August 2011

Automatic DisplayAttribute using PostSharp

The Problem


I worked with a MVC 3 web application the other day and was asked to translate the properties to Norwegian. The MVC 3 views are written in Razor view engine and the models are set to DataContract classes. These classes consists of multiple properties and each property needs to have a DisplayAttribute where the Name property is set to the text to display. An overload of the DisplayAttribute is to provide the type of a Resource file (public) followed by the Name attribute, which will in this case be the Resource key inside the Resource file.

After translating large DataContract classes with many DataMember properties, I thought this was a very tedious process. Another challenge was that I got runtime
exceptions when opening the MVC 3 view in a browser just to see an exception being
thrown at me because the resource file did not have a matching resource key which
should be tied to a property by given Name in the DisplayAttribute.

Attributes being difficult


The source of this problem is actually that Attributes in C# cannot define the Resource key directly, but by a string literals. The reason for this is limitations in the types supported in the parameters of a attribute. The ResourceType of the DisplayAttribute is set to the Resource file Type (the resx file is actually a class, inspect the designer.cs file to see its structure). The Name attribute is as previously mentioned a string literal, hardly very refactoring friendly.

Finding a solution


In another project at my work we have used PostSharp to aid in such repetitive tasks, where each property or class needs to be tagged with attributes in a certain pattern. I created a test project and implemented a PostSharp attribute / aspect called AutoDisplayAttribute. This attribute is set on the class level and will decorate all properties with a required display attribute and a resource key set to the property name. The client of this aspect can enforce lookup in the Resource File which means an error will be raised if there are no matching Resource key. The default behavior of this aspect is to avoid setting the DisplayAttribute if no matches are found in the Resource File specified (forceLookup).


Download ILSpy and SharpCrafter's PostSharp


I also used ILSpy to inspect the results in the DLL file of my test project, and the properties were all decorated with my desired DisplayAttribute. ILSpy is free software and is similar to Reflector. The tool is very useful to inspect metadata for DLL files and disassemble them to reveal the source code.

ILSpy

If you have not used PostSharp earlier, you need to download the setup from SharpCrafters. The version I used is PostSharp version 2.1 CTP 3. The download page should be available here:

PostSharp 2.1 Community Edition CTP 3

The PostSharp.dll file must be added in the References to your test project to test out the source code I will present next.

The source code for the AutoDisplayAttribute



The source code for the AutoDisplayAttribute follows below.



// We set up multicast inheritance so the aspect is automatically added to children types.
[MulticastAttributeUsage(MulticastTargets.Class, Inheritance = MulticastInheritance.Strict)]
[Serializable]
public sealed class AutoDisplayAttribute : TypeLevelAspect, IAspectProvider
{

private Type _resourceType;
private bool _forceLookUp;

public AutoDisplayAttribute(Type resourceType, bool forceLookup = false) : base()
{
_resourceType = resourceType;
_forceLookUp = forceLookup;
}

// This method is called at build time and should just provide other aspects.
public IEnumerable ProvideAspects(object targetElement)
{
Type targetType = (Type)targetElement;
var targetTypeProperties = GetTargetTypeProperties(targetType).Distinct();

// Add a Display attribute to every relevant property.
foreach (PropertyInfo property in targetTypeProperties)
{
if (!property.IsDefined(typeof(NotAutoDisplayAttribute), false) &&
!property.IsDefined(typeof(DisplayAttribute), false))
{
if ((!_forceLookUp) && (_resourceType.GetProperty(property.Name) == null))
{
continue;
}
CustomAttributeIntroductionAspect introduceDisplayAspect =
CreateDisplayAttributeIntroductionAspect();
InitDisplayAttributeForProperty(introduceDisplayAspect, property);
yield return new AspectInstance(property, introduceDisplayAspect);
}
}
}

private void InitDisplayAttributeForProperty(CustomAttributeIntroductionAspect introduceDisplayAspect, PropertyInfo property)
{
introduceDisplayAspect.CustomAttribute.NamedArguments.Add("ResourceType", _resourceType);
introduceDisplayAspect.CustomAttribute.NamedArguments.Add("Name", property.Name);
}

private static PropertyInfo[] GetTargetTypeProperties(Type targetType)
{
return targetType.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);
}

private static CustomAttributeIntroductionAspect CreateDisplayAttributeIntroductionAspect()
{
CustomAttributeIntroductionAspect introduceDisplayAspect =
new CustomAttributeIntroductionAspect(
new ObjectConstruction(typeof(DisplayAttribute).GetConstructor(Type.EmptyTypes)));
return introduceDisplayAspect;
}
}

[AttributeUsage(AttributeTargets.Property)]
public sealed class NotAutoDisplayAttribute : Attribute
{

}



AutoDisplayAttribute code explained


The class above generates the DisplayAttribute for properties inside the
class the AutoDisplayAttribute is applied on, which is the Attribute which is used to lookup the string to display for a given property.


The TypeLevelAspect is the parent class for AutoDisplayAttribute and the class also
implements the IAspectProvider interface. The interface consists of the public method ProvideAspects which will return an IEnumerable of AspectInstance. All these supportive classes and interface is part of the PostSharp API which is used in the code to provide the "magic" post-compilation code executed right during/after the default compilation process.

Talk and embrace


I like this AutoDisplayAttribute a lot. The aspect will definately be a time saver. If you set forceLookup to true on all classes that should have translated properties (usually data contracts), excluding the properties tagged with NotAutoDisplayAttribute, you will get compilation errors when the Resource lookup defined in a Display(Name="MyProperty", ResourceType=typeof(MyResourceType)], which is a huge benefit compared to having run time exceptions thrown at you when the display lookup fails. To fix such an exception, add the resource key and associated resource value in the resource file and build again. If the build went fine, the display attributes are set up. When you refactor a property (i.e. rename), the AutoDisplayAttribute will indirectly require that the resource key is also refactored. To avoid this, it is possible to rather stick to adding the DisplayAttribute manually, but try to keep up this when having DataContract classes with many properties that must be translated and displayed using a resource file. Instead, when having AutoDisplayAttribute on all data contracts and forcing lookup, the compilation errors will guide you to keep the lookup process in a "type-safe" manner, requiring that for each property name there must be a resource key with the same case-sensitive name. In addition, this attribute / aspect is a huge time saver and when the data contracts are tagged with this attribute, it merely consists of adding the [AutoDisplay(typeof(MyResource), forceLookup:true)] tag at the class (instead of lots of [Display(..)] attributes polluting your data contract..

Use-case of this attribute


A minimalistic example follows.

Consider this data contract class. Note the AutoDisplayAttribute at the top of the class.


[AutoDisplay(typeof(Resource1), forceLookup:true)]
public class TestModel
{

public DateTime? BirthDate { get; set; }

public string FirstName { get; set; }

}


Lets follow up with a simple razor view sample



@Html.LabelFor(model => model.BirthDate)
@Html.TextBoxFor(model => model.BirthDate, new { id = "dtpBirthDate" })

@Html.LabelFor(model => model.FirstName)
@Html.TextBoxFor(model => model.FirstName, new { id = "tbFirstName" })


Of course, this attribute is very general and can be used in other frameworks
than MVC 3. When running the application, the labels should now use the value from the Resource file by given resource key.

Please note that the forceLookup is set default to false. To enforce lookup and letting the compiler aiding you that the resource file do indeed have the resource key, set the forceLookup to true explicitly.

In the end, a screen shot from ILSpy to show the magic revealed.



Download sample solution here:

Download sample MVC 3 solution with AutoDisplayAttribute implementation


Regards, Tore Aurstad

Sunday, 17 July 2011

Slides about Ecmascript 5 arrays

I am publishing some slides about Ecmascript 5 arrays written in Norwegian in this article.