web 2.0

Simple Dependency Injection using a Custom MVC Controller Factory

Whenever I develop an MVC application there is always some degree of data access required. As a best practice, I usually define a interface that my repository objects will adhere to. Creating an interface is generally a requirement for Dependency Injection (DI). DI is a very important pattern if you plan on doing any unit testing later on. For the purpose of this demo, I am going to keep things simple and only create a fake repository.  Here is the code:

public interface IRepository
{
    Person GetPerson( int id ); 
}

public class FakeRepository : IRepository
{        
    public Person GetPerson( int id )
    {
        return new Person { Id = id, FirstName = "Mike", LastName = "Ceranski" };
    }
}

Obviously, in a real-world application you would probably utilize the Entity Framework or LINQ to SQL in order to implement the IRepository interface. However, for the purposes of this demo the FakeRepository illustrates the point. Moving on, the next step is to create a base controller class which all of the other controllers in the application will derive from. The BaseController class has a IRepository property which gets set by the constructor. By having this constructor we can easily “inject” our repository objects.

public class BaseController : Controller
{        
    public IRepository Repository { get; private set; }

    public BaseController(IRepository repository)
    {
        Repository = repository;
    }
}

So now its time to create the "Person" controller which inherits from the BaseController class. We also add a single action named "Details" which will get return a Person model from the repository:

public class PersonController : BaseController
{
    public PersonController(IRepository repository) : base(repository) { }

    public ActionResult Details( int id = 1)
    {
        return View( Repository.GetPerson(id) );
    }
}

So at this point you may think your work is done, right? Well, if you were to run the application at this point and try to view the Details for the person with the ID 1 (“/Person/Details/1”) you would get an error stating that “No parameterless constructor is defined for this object”. That’s because the default controller factory used in MVC always uses the default constructor to create a controller. Since our PersonController does not have a parameterless constuctor defined, the application throws an error. Obviously, we will need to do a little more work in order to make MVC use our DI friendly constructor. Luckily this is easily accomplished by creating and registering our own custom controller factory. Here is the code:

public class CustomControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        return Activator.CreateInstance(controllerType, new FakeRepository()) as IController;
    }
}

The code above overrides the CreateController method. It uses the Activator.CreateInstance method to create the controller using our custom constructor and passes in a new instance of the FakeRepository class. So now the final step is to register the CustomControllerFactory in the Global.asax:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterRoutes(RouteTable.Routes);

    ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));
}

Now, when I run my application and access the URL "/Person/Details/1" I get the following results:

image

The end result is a MVC application which allows you to easily inject repository objects for testing purposes!  The sample code is attached.

DI_MVC_Example.zip (252.38 kb)

Unit Testing Secure Controller Actions with Moq

One of the hardest things to unit test in MVC is security. Security is tough to test because there is a lot of setup involved in mocking the HttpContext, the Principal and the Identity. For example, in WeBlog I am using the following code in the Edit Post action.

Post post = Repository.FirstOrDefault<Post>(x => x.ID == id);

if (post == null) return View("NotFound");
if (!HttpContext.User.CanEditPost(post)) return View("PermissionDenied");

In order to make sure this code works properly I need to test it with an authorized and unauthorized user. Unfortunately, the HttpContext.User will not automatically be created for your tests so you have to mock one for each test that your perform. So lets start this journey by reviewing the code required to mock the HttpContext using the popular opensource library Moq. This code is a combination of code I discovered on Stackoverflow and Scott Hanselman’s MvcMockHelpers:

MockContext

public static Mock<HttpContextBase> MockContext( IPrincipal principal = null )
{
    var context = new Mock<HttpContextBase>();
    var request = new Mock<HttpRequestBase>();
    var response = new Mock<HttpResponseBase>();
    var session = new Mock<HttpSessionStateBase>();
    var server = new Mock<HttpServerUtilityBase>();

    context.Setup(ctx => ctx.Request).Returns(request.Object);
    context.Setup(ctx => ctx.Response).Returns(response.Object);
    context.Setup(ctx => ctx.Session).Returns(session.Object);
    context.Setup(ctx => ctx.Server).Returns(server.Object);

    if( principal != null )
        context.Setup(ctx => ctx.User).Returns(principal);            

    return context;
}

If you are familiar with Scott’s MvcMockHelpers then you will probably notice that I modified the method signature to include an optional IPrincipal object. If the value is not null then I set the HttpContext.User. I also modified the SetFakeControllerContext extension method to take the IPrincipal parameter as well.

public static void SetFakeControllerContext(this Controller controller, IPrincipal principal = null )
{
    var httpContext = FakeHttpContext( principal );
    ControllerContext context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
    controller.ControllerContext = context;
    controller.Url = new UrlHelper( context.RequestContext, new RouteCollection() );            
}

Now that we have the major pieces in place, its just a matter of creating a Fake user and passing it into the SetFakeControllerContext method. To create the IPrincipal, I am using these two Mock classes which were posted by Razzie on Stackoverflow:

MockPrincipal

 
public class MockPrincipal : IPrincipal
{
  private IIdentity _identity;
  private readonly string[] _roles;

  public MockPrincipal(IIdentity identity, string[] roles)
  {
    _identity = identity;
    _roles = roles;
  }

  public IIdentity Identity
  {
    get { return _identity; }
    set { this._identity = value; }
  }

  public bool IsInRole(string role)
  {
    if (_roles == null)
      return false;
    return _roles.Contains(role);
  }
}

MockIdentity

public class MockIdentity : IIdentity
  {
    private readonly string _name;

    public MockIdentity(string userName)    {
      _name = userName;
    }

    public override string AuthenticationType
    {
      get { throw new System.NotImplementedException(); }
    }

    public override bool IsAuthenticated
    {
      get { return !String.IsNullOrEmpty(_name); }
    }

    public override string Name
    {
      get { return _name; }
    }
  }

Putting the pieces together

So based on the code above I made two tests which create the Mock users and test their ability to edit a post. The first test should return the “PermissionDenied” View. Therefore, I create a new MockPrincipal which is in the Subscriber role. The Subscriber role is a read-only account which should prohibit the user from editing anything in the application.

[TestMethod]
public void EditActionShouldReturnPermissionDeniedViewForUnauthorizedUser() {
    var principal = new MockPrincipal(new MockIdentity("Guest"), new string[] { Role.Subscriber });
    var postController = new PostController(_repository);
    postController.SetFakeControllerContext(principal);

    var result = postController.Edit(_fakePost.ID) as ViewResult;
    Assert.AreEqual("PermissionDenied", result.ViewName);
}

Next, we perform a similar test with an Admin user which should be able to edit any post.

[TestMethod]
public void EditActionShouldReturnValidViewForAuthorizedUser()
{            
    var principal = new MockPrincipal(new MockIdentity("Admin"), new string[] {Role.Admin});       
    var postController = new PostController(_repository);
    postController.SetFakeControllerContext(principal);
    
    var result = postController.Edit(_fakePost.ID) as ViewResult;
    Assert.IsInstanceOfType(result.ViewData.Model, typeof(PostFormViewModel));
}

And the end result is a successful test!

image

Custom Configuration Sections FTW

As a .NET developer you will probably create hundred of configuration files over the course of your career. Most of the time when we use a configuration file it is for simple things like a database connection string. However, sometimes configuration data needs to be relational and can require a more complex structure than traditional name value pairs. For example, lets say that I am developing a data import tool which uses the configuration file to store data mapping information. Here is an example of what my configuration file might look  like:

<import>
   <jobs>
      <job name="Foo">
         <fieldMappings>
            <mapping source="column1" destination="TimeStamp"/>
            <mapping source="column2" destination="Name"/>           
         </fieldMappings>         
      </job>
      <job name="Bar">
         <fieldMappings>
            <mapping source="column1" destination="DateTime"/>
            <mapping source="column2" destination="IPAddress"/>           
         </fieldMappings>         
      </job>
   </jobs>
</import>

Yes, the configuration data I just defined is simple XML and I could parse it on my own. However, I really do not want to have to do all of this XML parsing by myself. After all the purpose of creating a custom configuration section is to leverage the pre-existing configuration classes and let .NET do all the heavy lifting for me. By using the built-in classes I can easily enumerate my configuration data by looping over the data and accessing the object properties like this:

ImportElement import = (ImportElement)ConfigurationManager.GetSection("import");
foreach (JobElement job in import.Jobs)
{
    foreach( FieldMappingElement mapping in job.FieldMappings) 
    {
        ...
        mapping.Destination = mapping.Source;
        ...
    }   
}

The first step in creating our custom configuration section is to define the ImportElement class. This is the root node of the configuration section. The class is very simple and only contains a property to access the jobs which reside underneath it:

public class ImportElement : ConfigurationSection
{
    // Fields
    private static readonly ConfigurationProperty jobs = 
        new ConfigurationProperty("jobs", typeof(JobCollection), null, ConfigurationPropertyOptions.IsRequired);

    // Methods
    public DataMapping()
    {
        base.Properties.Add(jobs);
    }

    // Properties
    [ConfigurationProperty("jobs", IsRequired = true)]
    public JobCollection Jobs
    {
        get
        {
            return (JobCollection)base[jobs];
        }
    }
}

The important thing to notice is that the ImportElement class inherits from System.Configuration.ConfigurationSection. The ConfigurationSection class knows how to parse XML and shields us from doing any of the dirty work. In general, the less XML parsing I have to do, the happier I am. However if you have a strange fetish for XML parsing then please stop reading this article here and uninstall Visual Studio from your machine. Next, download the JDK, install Eclipse and start writing Java code. Once you are fed up with manual XML parsing please come back and finish the rest of this tutorial. :-)

Anyway, getting back to the tutorial…the ImportElement class also exposes a property called Jobs which is of type JobCollection. The JobCollection class is also defined as a custom class. However, JobCollection will inherit from ConfigurationElementCollection instead of ConfigurationSection because it is a collection of JobElements:

[ConfigurationCollection(typeof(JobElement), AddItemName = "job", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class JobCollection : ConfigurationElementCollection
{
    // Methods
    protected override ConfigurationElement CreateNewElement()
    {
        return new JobElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((JobElement)element).Name;
    }

    // Properties
    new public JobElement this[string jobName]
    {
        get
        {
            return (JobElement)base.BaseGet(jobName);
        }
    }
}

Notice that the ConfigurationCollection attribute is used to declare that this collection contains a list of JobElement(s). Since the Job Element also contains a list of field mappings you would repeat these steps to create the JobElement and FieldMappingCollection classes. With that said, lets move on to the FieldMapping class which contains a few attributes for the source and destination columns used in the import process:

public class MappingElement : ConfigurationSection
{
    // Fields
    private static readonly ConfigurationProperty _destination = 
        new ConfigurationProperty("destination", typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired);
    private static readonly ConfigurationProperty _source = 
        new ConfigurationProperty("source", typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired);

    // Methods
    public MappingElement()
    {
        base.Properties.Add(_source);
        base.Properties.Add(_destination);
    }

    // Properties
    [ConfigurationProperty("destination", IsRequired = true)]
    public string Destination
    {
        get
        {
            return (string)base[_destination];
        }
    }

    [ConfigurationProperty("source", IsRequired = true)]
    public string Source
    {
        get
        {
            return (string)base[_source];
        }
    }
}

Now I would like to point on that I am using simple string properties in my MappingElement class. However, you can use integers, enums, datetimes or whatever else you need in order to achieve your goals. As long as you can serialize and deserialize your values then the sky is the limit.

At this point we have built all of our configuration classes. However, we still need to tell the application how to associate our custom configuration classes with the corresponding section of our config file. This is accomplished by adding a little code to the configSections element of the application config file:

<configuration>
  <configSections>
    <section name="import" type="MyProject.Configuration.Import, MyProject"/>
  </configSections>
...
</configuration>

The name attribute should match the root node of your custom config section. The type attribute contains two values separated by a comma. The first part is the fully qualified classname that represents the root element in your custom config section. The second part of the attribute is the assembly name where the code resides. Once you have the configSections defined you are ready to roll!

Building Better MVC Code with T4MVC

If you are a ASP.NET web developer than chances are that you have heard of or dealt with problems related to “Magic Strings”. Magic strings are taboo because they introduce a degree of fragility in your code due to the fact that they are not strongly typed. The classic example, is referencing a View Name or Route in your controller action using a string value:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return RedirectToAction("Foo");            
    }

    public ActionResult Foo()
    {
      return View();
    }
}

As you would expect, when the Index action is invoked the user gets redirected to “Foo”. Unfortunately, if I rename the “Foo” method to “Bar” my code will still compile but it will ultimately fail at runtime. This is all due to the fact that are RedirectToAction method is using the magic string “Foo” which is not strongly typed and therefore not caught by the compiler.

As a workaround to this problem some people have went so far as to declare constants in their code for all the view names and actions. Unfortunately this is not a good solution because there is a great deal of work involved in creating and maintaining all of those constants. So the question becomes “How can I eliminate the magic strings in my code, find errors at compile time, and still make it easy to maintain?”. Well the answer is T4. T4 stands for the Text Template Transformation Toolkit. In the simplest terms, T4 is code that generates code. More specifically in MVC we have the T4MVC template which can be used create strongly typed helpers for referring to your controllers, actions, views, images, scripts and etcetera. For example, with T4MVC the code above can be written as:

 
public partial class HomeController : Controller
{
    public virtual ActionResult Index()
    {
        return RedirectToAction(MVC.Home.Foo());
    }

    public virtual ActionResult Foo()
    {
        return View();
    }
}

So now if I rename “Foo” to “Bar” the compiler will catch the error. In addition to making your controller code better, T4MVC also plays an important role in your view pages. For example consider the following snippet of code:

<head>
    <title>Magic Strings are BAD</title>
    <link rel="stylesheet" type="text/css"  href='/Themes/Emporium/default.css' />    
    <script src="/Scripts/jquery-1.4.2.min.js" type="text/javascript"></script>    
    <script src="/Scripts/jquery-ui-1.8.1.custom.min.js" type="text/javascript"></script>            
    <script src="/Scripts/weblog.js" type="text/javascript"></script>
</head>

<%= Html.ActionLink("Delete Contact", "Delete", "Contact", new { id = Model.ContactID })%>

Although this code is perfectly normal we have to be careful if we rename a script or change the name of a controller action because it will break the page. Luckily, T4MVC to the rescue. Here is the same code using T4MVC generated constants:

<head>
    <title>Magic Strings are BAD</title>
    <link rel="stylesheet" type="text/css" href="<%= Links.Themes.Emporium.default_css %>" media="all" /> 
    <script src="<%= Links.Scripts.jquery_1_4_2_min_js %>" type="text/javascript"></script>
    <script src="<%= Links.Scripts.jquery_ui_1_8_1_custom_min_js %>" type="text/javascript"></script>
    <script src="<%= Links.Scripts.weblog_js %>" type="text/javascript"></script>      
</head>

<%= Html.ActionLink( "Delete Contact", MVC.Contact.Delete( Model.ContactID )) %>

 
So hopefully by this point you are sold on the idea of using T4MVC in your MVC application. Now its just a matter of configuring it. Fortunately, T4MVC is easy to add to your application. You simply download the T4MVC zip file, extract the templates and drop them in the root directory of your MVC project. Once you include the files in your project the T4 template will execute. The templates will inspect the contents of your application and generate strongly typed references for all the assets within it. After that its just a matter of replacing your magic string references with the T4MVC generated code.

T4MVC was created by David Ebbo and was recently absorbed by the MVC Contrib project which I blogged about a couple of weeks ago. For more information and examples of how to utilize T4MVC in your application visit the T4MVC codeplex page. Also check out this intro video from Channel 9:

Get Microsoft Silverlight

Looking for an MVC Grid Control? Try MVC Contrib!

Like most .NET Web Developers I was ecstatic when MVC was released. To put it plainly, I hate WebForms. However I do find myself missing some of the great WebForm controls like the DataGridView. The DataGridView was present in every WebForm application that I wrote. I really appreciated all the subtle bells and whistles that Microsoft added to the grid over the years. I wrote my own grid control for classic ASP and I know firsthand that it is a significant undertaking to make a grid control that if feature rich and flexible enough to handle complex situations. Therefore I was not crazy about taking on the task again…

Initially, I adopted jqGrid as my new de facto grid control. From a end user’s perspective, jqGrid provides a top-notch user experience. Unfortunately, the control is heavily dependent on JavaScript so its not always the best solution for Mobile websites. In addition, jqGrid does require a fair amount of plumbing. Although it’s not difficult to implement it does take time and does not provide the rapid development experience that I grew accustomed to with the DataGridView control.

For about the last 12 months I went old school. Yes, I have manually been coding my tables by looping over a enumerable list and creating rows and columns. Just like I did ten years ago! Its ridiculous. Luckily, I recently stumbled upon the MVC Contrib Grid. In approximately 10 minutes, I downloaded the library, added a reference to the assembly and fully implemented a grid with paging and sorting! You will not believe how easy it is.

MVCContribGrid

Step 1: Creating the Controller Action

public ActionResult Manage()
{
    var categories = Repository.All<Category>();    
    return View(categories);
}


Step 2: Create the View Page

<%@ Import Namespace="MvcContrib.UI.Grid" %>
...
<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">    
    <%= Html.Grid(Model).Columns( column => {    
           column.For( x => x.Name );
           column.For( x => x.Description);
    })%>
</asp:Content>  

 

Step 3: Wait! I Need Sorting

A grid is no good unless it can sort. Time to modify the controller action and view to support sorting. First of all, you need to added a reference to MvcContib.Sorting and MvcContrib.UI.Grid. Next modify the method signature to accept a GridSortOptions object. This object contains the sorting information that was submitted from the view page.

 

using MvcContrib.Sorting;
using MvcContrib.UI.Grid;
...
public ActionResult Manage(GridSortOptions sort)
{
    var categories = Repository.All<Category>();
    if (sort.Column != null)            
        categories = categories.OrderBy(sort.Column, sort.Direction);            
    ViewData["sort"] = sort;
    return View(categories);
}
 

Ok, now we just need to modify the grid on the view page to show sortable column headers.

 

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">    
    <%= Html.Grid(Model).Columns( column => {    
        column.For( x => x.Name ).Sortable(true);
        column.For( x => x.Description).Sortable(true);               
        }).Sort((GridSortOptions)ViewData["sort"])%>
    <%= Html.Pager((IPagination)Model) %>
</asp:Content>

 

Step 4: You Want Paging? No Problem.

Paging has never been easier. Just add another argument to your controller action which takes a nullable int named “page”.

 

using MvcContrib.UI.Grid;

...
        
public ActionResult Manage(GridSortOptions sort, int? page)
{
    var categories = Repository.All<Category>();
    if (sort.Column != null)            
        categories = categories.OrderBy(sort.Column, sort.Direction);
    ViewData["sort"] = sort;
    return View(categories.AsPagination(page ?? 1, 10));
}

 

Now we need to add the paging control on the view page:

 

<%@ Import Namespace="MvcContrib.UI.Grid" %>
<%@ Import Namespace="MvcContrib.UI.Paging" %>

...

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">    
    <%= Html.Grid(Model).Columns( column => {    
        column.For( x => x.Name ).Sortable(true);
        column.For( x => x.Description).Sortable(true);
     }).Sort((GridSortOptions)ViewData["sort"])%>
     
    <%= Html.Pager((IPagination)Model) %>
</asp:Content>

Admittedly, the jqGrid does have a superior look and feel and provides paging and sorting without making a post back. Unfortunately, jqGrid does require a little bit of know-how and can be frustrating to implement. Not too mention it has a heavy dependency on JavaScript which can be problematic for mobile compliant websites. In contrast, the MVC Contrib Grid couldn’t be any simpler. So what are you waiting for? Try it yourself…

Tags: ,

ASPNet | dotNet | MVC