Introducing sBlog.Net – An Open Source Blog Engine

Hello people! It’s been a very long time since I posted anything in this blog, but, here I am! This blog post is regarding something I have been working for a while – it’s a blog engine and I have named it sBlog.Net. The dedicated website is for this project is:


Its experimental and I am always open to questions and suggestions Even though, at this point it supports basic features of a blog, a lot more things are in my mind, so, watch out! . I will let you go to this website and read & experiment more about this.

Given below is a link to the demo of sBlog.Net that is hosted under somee.com. The site is hosted for free, and so you will be seeing a number of ads by somee.com. This demo is just to give you an idea of this blogging engine.


But, before you go let me also introduce you to a group I created to discuss things about sBlog.Net. It is:

Post your questions and comments at the google groups site, lets discuss!

Happy coding ;)

Share

Generating an “Archives” menu in MVC 3

Hello! I am back! In this post, I am going to discuss a method using which you could generate a menu that lists the archives for your website. You would have seen this in number of website / blogs, even this blog for that matter, check out the section labelled “Archives” to your right. The intention of this post is to generate something similar.

The requirements of this archive list are as follows:

  • It goes in the reverse chronological order, begining with current month / year
  • An entry for a month/year can be present only if there are any items for that particular month/year
  • (At this point) lists all the month/year’s for which there is an item

To implement this I am going to use 2 interfaces (IEnumerator and IEnumerable) provided in the System.Collections assembly. Note that this post does not dwelve in to explaining this as MSDN does a really good job :) Here is the link to the MSDN article!

The IEnumerator interface is implemented so as to support simple iteration using the for loop. To facilitate simplicity (and to reduce the amount of code), I have also implemented the IEnumerable interface as it enables us to use the foreach method of looping, thus making the class that supplies the month/year combinations to be a collection.

To begin with, let use create a plain old simple c# object to represent an archive entry. A sample entry that a user would see is January 2012, and the corresponding Archive entry would have the following properties

Year = 2012, Month = 01 and MonthYear = January 2012.

public class Archive
{
   public string Year { get; set; }
   public string Month { get; set; }
   public string MonthYear { get; set; }
}

Then let’s create the class that would represent an item that a website would present to a user. I am calling it a Post. As stated before, the intention is to present a list of month/year, clicking on which would present a user with a list of post’s added during that date/time. So this class should necessarily contain a date/time apart from other fields. Here it is:

public class Post
{
  public string PostName { get; set; }
  public DateTime AddedDateTime { get; set; }
}

Now let’s get to the most interesting part! Let us create the collection class that will implement the functionality we wish to implement. Here is the code listing, some explanation follows the listing.

    public class ArchiveCollection : IEnumerator, IEnumerable
    {
        private readonly List<Post> _srcList;
        protected List<Archive> Archives = new List<Archive>();
        int _current = -1;

        public ArchiveCollection(List<Post> listToBeGrouped)
        {
            _srcList = listToBeGrouped;
            AddArchives();
        }

        public object Current
        {
            get { return Archives[_current]; }
        }

        public bool MoveNext()
        {
            _current++;
            return _current < Archives.Count;
        }

        public void Reset()
        {
            _current = -1;
        }

        public IEnumerator GetEnumerator()
        {
            return Archives.GetEnumerator();
        }

        protected virtual DateTime GetDateTime()
        {
            return DateTime.Now;
        }

        private void AddArchives()
        {
            var dateTime = GetDateTime();
            var currentYear = dateTime.Year;
            var currentMonth = dateTime.Month;
            var dateTimeFormatInfo = new DateTimeFormatInfo();

            var lastEntry = _srcList.OrderByDescending(p => p.AddedDateTime).LastOrDefault();

            if (lastEntry != null)
            {
                var endYear = lastEntry.AddedDateTime.Year;
                var endMonth = lastEntry.AddedDateTime.Month;

                // Probably could simplify using GroupBy !
                while (currentYear >= endYear)
                {
                    if (currentYear == endYear && currentMonth < endMonth)
                        break;

                    if (_srcList.Any(p => p.AddedDateTime.Year == currentYear && p.AddedDateTime.Month == currentMonth))
                    {
                        Archives.Add(new Archive
                        {
                            Year = currentYear.ToString(),
                            Month = currentMonth.ToString("00"),
                            MonthYear = string.Format("{0} {1}", dateTimeFormatInfo.GetMonthName(currentMonth), currentYear)
                        });
                    }

                    if (currentMonth - 1 < 1)
                    {
                        currentMonth = 12;
                        currentYear--;
                    }
                    else
                    {
                        currentMonth--;
                    }
                }
            }
        }
    }

Line 3 declares a readonly list of Post's that the collection would use to generate a list of month/year's. Remember, this list cannot have an entry where there are no posts, and that's why we expect a list of posts to look through. Then in line 4 a new list is created which will hold the archive entries. In the constructor, check out the AddArchives. This is the method that adds all the possible entries in to the list created in line 4. Lets get to this method directly, as other method's are simple, straight-forward and just implements the methods required by the interfaces.

Now, let's get to the most interesting method in this class which is the AddArchives method. In line 46, I first get the earliest entry in the list passed to this class. For example, current month/year is July 2012. If the earliest entry in the list was on 1st January 2011, that entry would be fetched by this line and the end year is thus assumed to be 2011 (line 50) and end month in line 51 will be 1.

Then in the while loop an archive entry is generated for each month/year starting from the current month/year going back to the last month/year in the list. Lines 55 - 56 is used to break the loop if for the end year, the loop crosses the end month.

Now that we have this collection ready, let me show you an example of how this could be used. To do this, I created a controller called the ArchivesController with the following action methods. There is also a static method that returns a list of Post entries that will be used by the collection. As shown in line 5, to use the collection, just instantiate an instance of ArchiveCollection passing the list of posts using the GetPosts method. The index view uses the collection passed as a model to list all the archive entries.

    public class ArchivesController : Controller
    {
        public ActionResult Index()
        {
            var archiveCollection = new ArchiveCollection(GetPosts());
            return View(archiveCollection);
        }

        private  static List<Post> GetPosts()
        {
            var posts = new List<Post>
                                   {
                                       new Post { PostName = "Post 1", AddedDateTime = DateTime.Parse("1/1/2012") },
                                       new Post { PostName = "Post 1", AddedDateTime = DateTime.Parse("12/1/2011") },
                                       new Post { PostName = "Post 1", AddedDateTime = DateTime.Parse("11/1/2011") },
                                       new Post { PostName = "Post 1", AddedDateTime = DateTime.Parse("10/1/2011") },
                                       new Post { PostName = "Post 1", AddedDateTime = DateTime.Parse("9/1/2011") },
                                       new Post { PostName = "Post 1", AddedDateTime = DateTime.Parse("8/1/2011") }
                                   };
            return posts;
        }
   }

Now, displaying the month/year's is not the only intention. We need to provide a link using which users will be able to drill-down and check out the posts for the selected month/year. To do this, lets add a route to the Global.asax.cs file. Here is that route:

routes.MapRoute("Archive", "archives/{year}/{month}",
                new { controller = "Archives", action = "ListByMonthYear" },
                new { year = @"\d{4}", month = @"[0-9]{1,2}" });

In the above snippet, first parameter is the route name, second parameter is the url format for the links generated is "archives/{year}/{month}", third parameter is the controller and action methods to be used for a request that follows this url format. The last parameter just indicates how the year & month parameters should be using a regular expression. "\d{4}" indicates that year should be a 4 digit number and "[0-9]{1,2}" indicates that month should be a 1/2 digit number. Now lets put this route to use in the Index view.

Here is the view listing for Index:

@model ArchiveCollection

@{
    ViewBag.Title = "title";
}

@foreach (Archive archive in Model)
{

@Html.RouteLink(archive.MonthYear, "Archive", new { year = archive.Year, month = archive.Month })

}

Line 7 loops through the model, using the Html.RouteLink helper method to generate a url using the url format specified in the Global.asax.cs file (line 9). The label used is the values in the MonthYear property.

Finally, lets add the ListByMonthYear action method that will take care of returning the posts for the requested month/year combination. When the user clicks on any of the archive links, this action method gets called, passing it the year and month. I leave the implementation to you, as it's out of scope for this post! The action method is given below:

public class ArchivesController : Controller
{
   // -- cut for brevity --

   public ActionResult ListByMonthYear(string year, string month)
   {
       // implementation omitted
       return View();
   }
}

Now, when you launch the application and navigate to /Archives/Index, you will be able to see a list of archive entries, clicking on which would take you to the action method that in turn returns the entries for the selected month/year! Here is a screen shot from a sample run:

This is from a current project of mine and yes, I did write some unit tests, but I am yet to add them to this sample project.Here is the mock class that can be used. The sample project does not contain any unit tests, but feel free to use the following mock to create unit tests! If you recall from the listing of ArchiveCollection class, the GetDateTime method was marked as virtual. This is to assist us in writing mocks for this class. Note that it's not good to just have a public method and override it using the new keywork in the mock. Soon, I will also update the post with some unit tests in the coming days!

    public class MockArchiveCollection : ArchiveCollection
    {
        public MockArchiveCollection(List<Post> posts)
            : base(posts)
        {

        }

        public Archive Single(Archive archive)
        {
            return Archives.SingleOrDefault(a => a.Month == archive.Month && a.Year == archive.Year && a.MonthYear ==
archive.MonthYear);
        }

        protected override DateTime GetDateTime()
        {
            return DateTime.Parse("4/1/2012");
        }
    }

Here is a sample project for your perusal.

If you think that this could be improvised or you have any other comments, post them here! Happy coding!

Share

Providing the ability to upload (and choose) files in CKEditor

Hello all, feels like it’s been forever since I posted anything! So, here I am with an interesting post. This post is about providing the upload functionality in CKEditor using ASP.Net MVC 3. CKEditor is WYSIWIG html editor. This can be used for various purposes. A really appropriate example is a Content Management System (CMS). In a CMS users typically type in the contents of a page and styles them using various tools available in the editor. This enables users who do not know html to create pages . The free CKEditor javascript expects us to implement this. There are few examples out there, but they are not complete and you may be left to search for more information on how to get it working.

So, you might understand from the introduction that this is not a tutorial about using CKEditor. But still, I would like to give a really quick overview of how I got to add CKEditor. To begin with download the CKEditor source for ASP.Net from here. In the sample project attached, after extracting the zip file downloaded, I have add the contents of the “ckeditor” folder to a folder called “JavaScript” within the “Content” folder. Thus, Content/JavaScript will contain folders like adapters, images, lang, plugins etc. The attached sample project only contains the necessary files and not everything. Feel free to add everything if you like!

To use the CKEditor in its simplest form, all it takes is to add a text area. Given below is an example. To use CKEditor in your web pages the following scripts have to be added.

  • jquery
  • ckeditor.js (from Content/JavaScript folder)
  • adapters/jquery.js (from Content/JavaScript folder)

Then, for this example, the model class is PageViewModel. This class has a PageContent property to hold the contents of the ckeditor. Given below is the complete implementation. Explanation follows after the code.

@model HtmlEditor.Models.PageViewModel

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <title>CKEditor - File Uploads Demo</title>
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Content/Javascript/ckeditor.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Content/Javascript/adapters/jquery.js")" type="text/javascript"></script>
    <script type="text/javascript" language="javascript">
        $(document).ready(function () {
            jQuery('.adminRichText').ckeditor();
        });
    </script>
</head>
<body>
    <div>
        @using (Html.BeginForm())
        {
            @Html.TextAreaFor(m => m.PageContent, new { @class = "adminRichText" })
            <br />
            <input type="submit" value="Submit" />
        }

        <br />
        @Model.PageContent
    </div>
</body>
</html>

Line 1 specifies the model for this page. Lines 12-14 includes the necessary script (listed in the list above). Lines 16-18 is where the ckeditor plugin is applied to any element which has a class of adminRichText. From this point onwards the textareas with this class would show up as a ckeditor. In line
25, a text area is rendered using the standard html extension. Note that the class applied is the same as in line 17, for which we have applied the ckeditor plugin. Given below is a sample run:

Now let us get started with the part where there is less documentation. I am going to extend the simple implementation above to allow users to upload files and also use them to provide links in the content pages they create. To do this I need to introduce the config.js file. This file is used to provide the editor rendered various options like the width, height, ui color etc. Initially the Browse Server button and the Upload tabs are not displayed in the editor.

To enable these controls, the following properties have to be added.

CKEDITOR.editorConfig = function( config )
{
    config.filebrowserBrowseUrl = "/Uploads/Browse";
    config.filebrowserWindowWidth = 500;
    config.filebrowserWindowHeight = 650;
    config.filebrowserUploadUrl = "/Uploads/Upload";
};

Line 2 specifies the url which would display the files available in the server. This page will open in a popup, when the user chooses to select a file from the server.

Line 5 specifies the url which would take care of files uploaded using the ckeditor. We have the urls, so let us create a controller to actually take care of this. Add a controller called UploadsController within the Controller folder. Within this add 2 action methods – 1 to enable users to select a file and 1 to upload a file.

Let us look about the Upload action method to start with. With the config options, CKEDitor provides options to upload files and to select files from the server. This has the following tabs:

  • Link Info
  • Target
  • Upload
  • Advanced

Given below are the images with these tabs. First is the image that shows the option to select a file.

When the Browse Server button is clicked, the popup displays the files currently in the server as shown below:

Next is the image that shows the upload tab:

In order to upload a file, users go in to the 3rd tab, choose a file and hits the Send it to the Server button. When this button is hit, ckeditor calls the url specified in the config by filebrowserUploadUrl. It passes the file content using the key name as upload. It also passes in a CKEditorFuncNum which can be used to identify the instance of the ckeditor that made this upload call. CKEditor parameter holds the name of the textarea that holds this content and finally langCode indicates the language of the content passed. The following action method saves this file in to the server’s uploads folder and returns a view which just has the upload status. This status is shown by ckeditor once the upload is complete.

public ActionResult Upload(HttpPostedFileBase upload, string CKEditorFuncNum, string CKEditor, string langCode)
{
    string fileName = upload.FileName;

    string basePath = Server.MapPath("~/Uploads");
    upload.SaveAs(basePath + "\\" + fileName);

    return View();
}

Next, lets have a look at the action method that lists the files in the server and lets users choose them. This method also gets the CKEditorNum property as explained before. This page just returns a list of files in the server along with the CKEditorNum.

public ActionResult Browse(string CKEditorFuncNum)
{
      List<FileInformation> fileInfoList = GetCurrentFiles();

      var model = new FileListingViewModel
      {
        Files = fileInfoList,
        CKEditorFuncNum = CKEditorFuncNum
      };

      return View(model);
}

This is an important part in this post. Its pretty straight-forward to list the files. But we also have to let the user to select one and return it back to the editor. This is where the CKEditorNum comes in to the picture. Let me explain how. CKEditor provides a function called callFunction which can be used to serve this purpose. Given below is the code content of this page. Notice the hidden field added that provides the CKEditorFuncNum provided by ckeditor for identification.

@model HtmlEditor.Models.FileListingViewModel

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <title>Add</title>
    <script src="../../Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(function () {
            $('a').click(function (e) {
                e.preventDefault();
                var ckEditorNum = parseInt($('#CKEditorFuncNum').val());
                window.opener.CKEDITOR.tools.callFunction(ckEditorNum, '/uploads/' + $(this).attr('href'), '');
                window.close();
            });
        });
    </script>
</head>
<body>
    <div>
        Select files<br /><br />
        @foreach (var item in Model.Files)
        {
            <a href="@item.FileName" style="font-size: larger;">@item.FileName</a>
            <br />
        }
        <br /><br />
        @Html.HiddenFor(m => m.CKEditorFuncNum)
    </div>
</body>
</html>

In the above snippet, lines 15 – 22 takes care of returning the selected file (jquery). To begin with, I stop the default action of the click of the anchor tag. Then, I get the CKEditorFuncNum added to the page as a hidden field [With multiple editors you may have to take care of this in a different way]. Note that the file browser opens as a popup. So the parent window is the one that has the ckeditor. So by calling the window.opener.CKEDITOR.tools.callFunction function, by passing in the CKEditorFuncNum, the uploads base folder name and the file name, ckeditor gets to know the selected file and popualtes that in the 1st tab (Link Info).

With this, we have achieved what we intended to achieve – to enable users to upload / select files from the server. Download a sample project that does this from here. Note that the project attached uses ckeditor 3.6.2, but the post links to the most latest version of ckeditor 3.6.3.

Share

Dependency Injection With Ninject And Extending It a Bit Further

In this post I am going to discuss a very interesting concept called “dependency injection (DI)” and also about extending the class that injects the dependencies further to achieve some more functionalities that I needed for a project of mine. I am going to use a mvc 3 application to explain about DI. DI is a type of interface programming that allows you to create loosely coupled systems. This increases testability and also reduces the amount of changes required to a project for adding / removing features. At this point it may be confusing, but once I discuss more about this with some examples, it will be much more clearer.

A system implementing DI could be pictured of as having 3 components:

  • Dependent Consumer
  • Dependency
  • Dependency Injector

Dependency consumer‘s are parts of the system that expects a concrete instance to implement something. Consider the following code listing (listing 1):

public class Consumer
{
    private DbAccessor _accessor;

    public Consumer(DbAccessor accessor)
    {
        _accessor = accessor;
    }

    public void DoSomething()
    {
       // -- snip --
    }
}

public class Tester
{
   public static void Main(string[] args)
   {
        DbAccessor accessor = new DbAccessor();
        Consumer consumer = new Consumer(accessor);
        consumer.DoSomething();
   }
}

If you notice the Main method, in order to create an instance of a Consumer, the method has to first create a DbAccessor instance. This is a Dependency. Thus, the method has to know about both the DbAccessor and Consumer. This is known as tight coupling. Because, if you change the name of this class to say DbType1Accessor and assuming this class is used a number of files, you have to change it in all of these files. A way better example is, say you want to replace DbAccessor with XmlAccessor you have to replace the same in all those numerous files. So with all of these facts, I am sure you understand why strong coupling is bad! Later in the post I will show how this strong coupling can be removed.

Now, let’s get to the most important component, the dependency injector. A Dependency Injector is a component that would help you to free the system from this coupling. And this post concentrates on adding a DI component for your project. I have always used “NInject” for implementing DI in my projects.

It’s extremely easy to setup and get started with NInject. To get started download, the NInject dll from here. For this post I was using NInject v2.0.0 (yeto to update to v2.2 :( ). Once you download the dll, add it to the project using “Add Reference”. Then create a class called NinjectControllerFactory and add the following code snippet to this file. This class is going to act as the principal class for implementing DI. If you notice this class inherits the DefaultControllerFactory, which is the default for the mvc framework.

A controller factory is a component of the mvc framework that helps in creating an instance of a controller as required by the mvc framework. In this case we are attempting to provide loose coupling to all the controllers. The controller factory, which is responsible for creating the controllers is overridden in this case so that when a controller is created now, the new controller factory would take the responsibility of creating an instance of the controoler and enabling the Ninject module to “inject” the dependency required by the controller.

public class NinjectControllerFactory : DefaultControllerFactory
{
	private IKernel kernel = new StandardKernel(new AplicationIocServices());

	protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
	{
	    if (controllerType == null)
        {
		    return null;
        }
	    return (IController)kernel.Get(controllerType);
	}

	private class AplicationIocServices : NinjectModule
	{
	    public override void Load()
	    {
		    Bind<IProductsRepository>().To<FakeProductsRepository>();
		    Bind<ICategoryRepository>().To<FakeCategoryRepository>();
	    }
	}
}

In the above code listing, line 3 creates an instance of StandardKernel which is required for the ninject module to work. The StandardKernel implements the IKernel interface which is used in the overriden GetControllerInstance method to return an instance of the required controller by passing the dependency needed by the controller. Note that, as this class is set to replace the DefaultControllerFactory, it’s very important to override the GetControllerInstance method to return an appropriate controller. If you notice line 3, an instance of the ApplicationIocServices instance is passed to the StandardKernel. This is a private class within the NinjectControllerFactory which is used to specify the bindings between an interface and a concrete instance. This class inherits from the NinjectModule class and overrides the Load method of the NinjectModule class.

Every line within the Load binds an interface to a concrete instance so that ninject can create a concrete type corresponding to the interface type passed when creating a controller instance. So when a controller requests a concrete type for IProductsRepository, ninject module returns an instance of FakeProductsRepository which could be used within the controller.

It’s not over if you just create this class. You have to inform the framework to use this instead of the DefaultControllerFactory using the Application_Start event in the Global.asax.cs file. This is done in line 8. ControllerBuilder class of mvc has the
Current property which is nothing but an instance of a ControllerBuilder for the current
application. The application’s controller factory is set to an instance of the NinjectControllerFactory we created earlier using the SetControllerFactory method of the ControllerBuilder instance. After this point, when a request is received for the HomeController (say), an instance of Home Controller will be created by our custom factory, by injecting in the required dependencies.

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

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}

Following is an example of how this is put to use. Let us assume that the HomeController has an action called Products that displays a list of products that this web site offers for purchase. Without DI, I will have to create an instance of FakeProductsRepository and use it in the controller as shown below:

public class HomeController : Controller
{
	public ActionResult Products()
	{
        FakeProductsRepository repository = new FakeProductsRepository();
	    return View(repository.Products);
	}
}

The above snippet has a strong coupling of the FakeProductsRepository with the HomeController. This is not good because it reduces testability and also makes you modify this code whenever something changes with the FakeProductsRepository class. For example, in case you want the controllers to receive a concrete instance of ProductsRepository instead of an instance of FakeProductsRepository, the only change required is the change in line 9. Thus even if a number of controllers uses the IProductsRepository dependency, nothing would change, as the only change required was in the NinjectControllerFactory class.

public class NinjectControllerFactory : DefaultControllerFactory
{
	// -- snip --

	private class AplicationIocServices : NinjectModule
	{
	    public override void Load()
	    {
		    Bind<IProductsRepository>().To<ProductsRepository>();
		    Bind<ICategoryRepository>().To<FakeCategoryRepository>();
	    }
	}
}

Now that we have set up DI, we can modify the code as shown below. Note that now, the fact that the controller expects a concrete type bound to IProductsRepository could be identified by the parameter to the constructor of the HomeController, which is IProductsRepository. From this point onwards, ninject takes care of creating an instance of the Home controller including passing to it an instance of the FakeProductsRepository because IProductsRepository is bound to FakeProductsRepository.

public class HomeController : Controller
{
	private IProductsRepository productsRepository;

    public HomeController(IProductsRepository productsRepo)
    {
          productsRepository = productsRepo;
    }

	public ActionResult Products()
	{
	    return View(productsRepository.Products);
	}
}

Extending the Ninject Module:

Now, let me get to the most important part of this post. What if I need to create a concrete instance somewhere in a class where Ninject does not come in to the picture? Thats what the remainder of the post is going to deal with. For this part, I again take up one of my favorite area of C# – type constraints :) Let’s add a method called GetConcreteInstance to the NinjectControllerFactory class. This method will be used to get a concrete instance based on the interface type passed. This is a generic method which takes in an interface as a type parameter, finds a concrete instance, casts it to the type T and returns it to the caller.

So, with this method, you don’t have pass every required instance to a controller. This method uses the TryGet method of the StandardKernel to see if a concrete instance exists for the type passed. If not available this method throws an exception.

public class NinjectControllerFactory : DefaultControllerFactory
{
	// -- snip

	public T GetConcreteInstance<T>()
	{
	    object instance = kernel.TryGet<T>();
	    if (instance != null)
        {
		    return (T)instance;
        }
	    throw new InvalidOperationException(string.Format("Unable to create an instance of {0}", typeof(T).FullName));
	}

	// -- snip --
}

Let us look in to an example on how this is put in to use in a controller. Before that let us add a helper class to call this method, so that we abstract the part of getting a reference to the controller factory. Its given below:

public static class InstanceFactory
{
	public static T CreateConcreteInstance<T>()
	{
	    NinjectControllerFactory factory =(NinjectControllerFactory)ControllerBuilder.Current.GetControllerFactory();
	    return (T)factory.GetConcreteInstance<T>();
	}
}

Now, I have added the Categories method to the HomeController. Let’s assume apart from this method, no other method requires the ICategoryRepository. So instead of injecting the dependency to the constructor, within the action method, I use the new helper created earlier to get a concrete instance of ICategoryRepository by passing in ICategoryRepository as the type parameter.

public class HomeController : Controller
{
	private IProductsRepository productsRepository;

	// -- snip --

	public ActionResult Categories()
	{
	    ICategoryRepository categoryRepo = InstanceFactory.CreateConcreteInstance<ICategoryRepository>();
	    return View(categoryRepo.GetCategories());
	}

	// -- snip --
}

In the case of the CategoryController, DI is used as its more likely to be used throughout the controller. So I am just letting ninject take the responsibility for the CategoryController.

public class CategoryController : Controller
{
	private ICategoryRepository categoryRepository;

	public CategoryController(ICategoryRepository categoryRepo)
	{
	    categoryRepository = categoryRepo;
	}

	public ActionResult Index()
	{
	    return View(categoryRepository.GetCategories());
	}
}

Now that I have given you the full picture about DI, let me show how the code in listing 1 can be refactored to free it of the strong coupling.

public class Consumer
{
    private DbAccessor _accessor;

    public Consumer(DbAccessor accessor)
    {
        _accessor = InstanceFactory.CreateConcreteInstance<IDbAccessor>();
    }

    public void DoSomething()
    {
       // -- snip --
    }
}

public class Tester
{
   public static void Main(string[] args)
   {
        Consumer consumer = new Consumer();
        consumer.DoSomething();
   }
}

Given below is another high level implementation of how this new helper class/method could be used.

public class BaseClass
{
	private SomeBusinessFunction func;

	public BaseClass()
	{
	    func = new SomeBusinessFunction();
	}

	public void SomeMethod()
	{
	    func.DealWithSomething();
	}
	}

	public class DerivedClass : BaseClass
	{
	public DerivedClass()
	{

	}
}

public class SomeBusinessFunction
{
	private ICategoryRepository categoryRepo;

	public SomeBusinessFunction()
	{
	    categoryRepo = InstanceFactory.CreateConcreteInstance<ICategoryRepository>();
	}

	public List<Category> DealWithSomething()
	{
	    List<Category> categories = categoryRepo.GetCategories().ToList();

	    // -- do something --

	    return categories;
	}
}

Okay, I know that you have seen a lot code. You can download a sample project here. Hope you enjoyed this post. Happy coding!

Share

ASP.Net MVC Extreme – A Deep Dive Inside View Engines

I am back with another post in the ASP.Net MVC extreme series (as promised)! In this post lets dive into the internals of how a view is selected when an action method returns a View. MVC has the following default view engies – webform and razor and also lets us to add custom view engines. For more inforation on custom view engines, refer to my earlier post here. Custom view engines can be added using the Application_Start event as shown below:

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

   ViewEngines.Engines.Clear();
   ViewEngines.Engines.Add(new CustomRazorViewEngine());

   RegisterGlobalFilters(GlobalFilters.Filters);
   RegisterRoutes(RouteTable.Routes);
}

In the above snippet, ViewEngines is a static class provided by the framework in order to manage the view engies that the framework would look for when searching for views to render. The entire action starts with the ViewResultBase class, which is the base class ViewResult which is responsible for rendering html content to the client. There are a number of other result’s such as FileResult, JsonResult, JavaScriptResult etc and all of these derive from the ActionResult class. ViewResultBase has the ViewEngineCollection property and it’s defined as given below. The engines set up in Application_Start is provided to the ViewResult class using this property. More information on how these engines are used follows soon!

// From mvc sources/reflector
public ViewEngineCollection ViewEngineCollection {
   get {
      return _viewEngineCollection ?? ViewEngines.Engines;
   }
   set {
      _viewEngineCollection = value;
   }
}

A simple action method in mvc would resemble the following:

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

The action method above returns the result of the View method from the Controller class. This method returns a ViewResult instance depending upong the parameters passed from the action method. Note that it could also be a PartialViewResult instance. The Controller type has multiple overloads of the View method. Their definitions are given below:

// From mvc sources/reflector
protected internal ViewResult View() {
    return View(null /* viewName */, null /* masterName */, null /* model */);
}

protected internal ViewResult View(object model) {
    return View(null /* viewName */, null /* masterName */, model);
}

protected internal ViewResult View(string viewName) {
    return View(viewName, null /* masterName */, null /* model */);
}

protected internal ViewResult View(string viewName, string masterName) {
    return View(viewName, masterName, null /* model */);
}

protected internal ViewResult View(string viewName, object model) {
    return View(viewName, null /* masterName */, model);
}

All of these overloads eventually call the following method:

// From mvc sources/reflector
protected internal virtual ViewResult View(string viewName, string masterName, object model) {
    if (model != null) {
	ViewData.Model = model;
    }

    return new ViewResult {
	ViewName = viewName,
	MasterName = masterName,
	ViewData = ViewData,
	TempData = TempData
    };
}

Similarly, the following method takes in an IView and has the following definition:

// From mvc sources/reflector
protected internal ViewResult View(IView view) {
   return View(view, null /* model */);
}

This method eventually calls the following method:

// From mvc sources/reflector
protected internal virtual ViewResult View(IView view, object model) {
    if (model != null) {
	ViewData.Model = model;
    }

    return new ViewResult {
	View = view,
	ViewData = ViewData,
	TempData = TempData
    };
}

If you notice the implementations of View, it creates an instance of ViewResult by passing the view name, master name, view data and temp data in the case of the first method and an IView object, view data and temp data in the case of the other method.

Coding best practices(feel free to skip this if you are aware of coding best practices): When you have a method that also has corresponding overloads, make sure that you don’t repeat the same code in both (or all) the places. Consider the following case. This method of handling overloads is bad!.

// bad practice, do not use!!!
public void FooMethod(int memberForYears, string userName)
{
   int totalDaysMemberFor = memberForYears * 365; // ignoring the fact about leap years
   int _membershipPoints = GetMembershipPoints();
   Console.WriteLine("User {0} was a member for {1} days and has {2} points", userName, totalDaysMemberFor, _membershipPoints);
}

public void FooMethod(int memberForYears, string userName, int membershipPoints)
{
   int totalDaysMemberFor = memberForYears * 365; // ignoring the fact about leap years
   int _membershipPoints = membershipPoints;
   Console.WriteLine("User {0} was a member for {1} days and has {2} points", userName, totalDaysMemberFor, _membershipPoints);
}

A nicer way to do this is given below. The refactored code below does not have repetitive code but utilizes the final method to display the results to the user. If you observe the above 2 methods, the only difference is the _membershipPoints bit which gets the value using the GetMembershipPoints method (not shown). So in the snippet below, the 1st overload is called by passing in the value from the method as the 3rd parameter.

// good practice
public void FooMethod(int memberForYears, string userName)
{
   FooMethod(memberForYears, userName, GetMembershipPoints());
}

public void FooMethod(int memberForYears, string userName, int membershipPoints)
{
   int totalDaysMemberFor = memberForYears * 365; // ignoring the fact about leap years
   int _membershipPoints = membershipPoints;
   Console.WriteLine("User {0} was a member for {1} days and has {2} points", userName, totalDaysMemberFor, _membershipPoints);
}

Before we dig in to the ViewResult class lets get a deeper understanding of the how this class is put in to use.

If you can recollect from my previous post, every controller in mvc implements the IController interface and this has the Execute method. When a request arrives, the Execute method is called. Within this method a call to the ExecuteCore method of the Controller is invoked. The ExecuteCode method then handles the responsibility to the ControllerActionInvoker.InvokeActionResult method. Within this method the ExecuteResult method of the ViewResultBase class is called, after executing the content of the action method according to the request. This method itself certainly deserves a post by the way! After this step the real action starts!!! Lets get in to that :)

The ExecuteResult method is given below:

// From mvc sources/reflector
public override void ExecuteResult(ControllerContext context) {
    if (context == null) {
	throw new ArgumentNullException("context");
    }
    if (String.IsNullOrEmpty(ViewName)) {
	ViewName = context.RouteData.GetRequiredString("action");
    }

    ViewEngineResult result = null;

    if (View == null) {
	result = FindView(context);
	View = result.View;
    }

    TextWriter writer = context.HttpContext.Response.Output;
    ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer);
    View.Render(viewContext, writer);

    if (result != null) {
	result.ViewEngine.ReleaseView(context, View);
    }
}

Note line 13 in the above snippet. This line calls the FindView overridden in the ViewResult (and PartialViewResult) class(es) to find a matching view. This method, uses the ViewEngineCollection in the ViewResultBase class to get a list of the available view engines. And then ViewEngineCollection type’s FindView method is called to find an appropriate view. This is where the engines added come in to play. The ViewEngineCollection.FindView method is given below:

// From mvc sources/reflector
public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName) {
    if (controllerContext == null) {
	throw new ArgumentNullException("controllerContext");
    }
    if (string.IsNullOrEmpty(viewName)) {
	throw new ArgumentException(MvcResources.Common_NullOrEmpty, "viewName");
    }

    return Find(e => e.FindView(controllerContext, viewName, masterName, true),
		e => e.FindView(controllerContext, viewName, masterName, false));
}

The Find method called in line 10 uses the engines defined for the application to find an appropriate view. To explore more in to this method, it’s important to see the ViewEngines class.

// From mvc sources/reflector
public static class ViewEngines {
	private readonly static ViewEngineCollection _engines = new ViewEngineCollection {
	    new WebFormViewEngine(),
	    new RazorViewEngine(),
	};

	public static ViewEngineCollection Engines {
	    get {
		return _engines;
	    }
	}
}

ViewResultBase class’s ViewEngineCollection property is set to the ViewEngines.Engines property, which is initialized with an instance of the ViewEngineCollection class created by passing the 2 default view engines available in mvc 3. If you remember (yes it’s been a long post ;) ) we use the ViewEngines.Engines property to add custom view engines. The Find method uses the engines set during instantiation to find an appropriate view. The view engine collection would either have the default engines or the custom engines or both. If this process fails, you see the generic error screen (given below) that lists all the locations searched by the framework.

As you may know, the action starts from the controller. Refer to my earlier post for more details about this. In a future post I will also try to connect the dots between these 2 posts, if I feel anything is missing. Also, I am reviewing this post to catch anything I missed, so it may be updated in the following days!

Finally, do post your comments and happy coding!

Share

ASP.Net MVC – Custom View Engines (Using the razor view engine as the base)

Okay, it’s ASP.Net MVC 3 time again! In this post I am going to discuss about custom view engines. I do not have a lot of real-time experience with custom view engines, but I wanted to try out one of my ideas of organizing the folder in a way that I feel was much more clearer. This is what I am talking about:

Views/
...Home/
......Pages/
.........Page1.cshtml
.........Page2.cshtml
......PartialPages/
........._UserControl1.cshtml
........._UserControl2.cshtml

From the textual folder structure above, I guess my intention is clear. In case you are familiar with the folder structure of MVC, There is a single “Views” folder and within this folder there are individual folders for every controller. Finally, the user controls and pages go in to these folders. If a page/user control is being shared it goes in to the “Shared” folder. In simple words, I just wanted to segregate the cshtml files further by creating a “Pages” and “PartialPages” folder.

As the name suggests, pages would go in to the “Pages” folder and user controls would go in to the “PartialPages” folder. To implement this I have created a custom view engine by inheriting the RazorViewEngine class. As the location of every file would change, we have to specify this by overriding the base string arrays that specify the possible locations of a certain type of a file (master, page, partial page).

Given below is the complete class. “%1″ in every possible path would have to be replaced with either “Pages” or “PartialPages” depending upon the method in question.

public class CustomRazorViewEngine : RazorViewEngine
{
	public CustomRazorViewEngine() : base()
	{
	    AreaViewLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/%1/{0}.cshtml",
						     "~/Areas/{2}/Views/{1}/%1/{0}.vbhtml",
						     "~/Areas/{2}/Views/Shared/%1/{0}.cshtml",
						     "~/Areas/{2}/Views/Shared/%1/{0}.vbhtml" };
	    AreaMasterLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/%1/{0}.cshtml",
						       "~/Areas/{2}/Views/{1}/%1/{0}.vbhtml",
						       "~/Areas/{2}/Views/Shared/%1/{0}.cshtml",
						       "~/Areas/{2}/Views/Shared/%1/{0}.vbhtml" };
	    AreaPartialViewLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/%1/{0}.cshtml",
							    "~/Areas/{2}/Views/{1}/%1/{0}.vbhtml",
							    "~/Areas/{2}/Views/Shared/%1/{0}.cshtml",
							    "~/Areas/{2}/Views/Shared/%1/{0}.vbhtml" };
	    ViewLocationFormats = new string[] { "~/Views/{1}/%1/{0}.cshtml",
						 "~/Views/{1}/%1/{0}.vbhtml",
						 "~/Views/Shared/%1/{0}.cshtml",
						 "~/Views/Shared/%1/{0}.vbhtml" };
	    MasterLocationFormats = new string[] { "~/Views/{1}/%1/{0}.cshtml",
						   "~/Views/{1}/%1/{0}.vbhtml",
						   "~/Views/Shared/%1/{0}.cshtml",
						   "~/Views/Shared/%1/{0}.vbhtml" };
	    PartialViewLocationFormats = new string[] { "~/Views/{1}/%1/{0}.cshtml",
							"~/Views/{1}/%1/{0}.vbhtml",
							"~/Views/Shared/%1/{0}.cshtml",
							"~/Views/Shared/%1/{0}.vbhtml" };
	    FileExtensions = new string[] { "cshtml", "vbhtml" };
	}

	protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
	{
	    return base.CreateView(controllerContext, viewPath.Replace("%1","Pages"), masterPath.Replace("%1","Pages"));
	}

	protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
	{
	    return base.CreatePartialView(controllerContext, partialPath.Replace("%1","PartialPages"));
	}

	protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
	{
	    return (base.FileExists(controllerContext, virtualPath.Replace("%1", "Pages")) ||
		    base.FileExists(controllerContext, virtualPath.Replace("%1", "PartialPages")));
	}
}

To download the file, click here (right click – save as – remove the .txt extension).

As you see above, to implement your custom view engine, you just have to override the following 3 methods:

  • CreateView – This method is called with the corresponding parameters if the view requested is a page
  • CreatePartialView – This method is called with the corresponding parameters if the view requested is a partial page / user control
  • FileExists – This method also has to be overridden in this case because the implementation of this method in the base class won’t know where to look for the file because of the %1 in the path. If this method is not overridden FileExists would always return false which would cause view engine to fail in the process of finding a matching view even if one exists

Now, update _ViewStart.cshtml to specify the location of the master page as shown below:

@{
    Layout = "~/Views/Shared/Pages/_Layout.cshtml";
}

Once we have the class that implements the custom razor engine, and the corresponding change to the _ViewStart.cshtml file, we have to inform the framework to use this instead of the default engine, as the default engine won’t work anymore as the folder structure has changed. To do this modify the Application_Start method in Global.asax.cs to include lines 5 & 6. Line 5 clears all the engines currently added (in this case, just the default engine) and line 6 adds the new custom engine we created.

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

    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new CustomRazorViewEngine());

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

Also, look forward to another post that dwelves in to internals of view engines in mvc 3!!!

Post your comments and happy coding!

Share

MVC Custom Model Binders and CheckBoxList

Back to ASP.Net MVC! In this post, I am going to discuss about custom model binders and a real-time use of custom model binders in ASP.Net MVC. Before getting in to custom model binders, as the name suggests, there is also a default model binder. If you are interested in custom model binders for mvc, I am sure you are aware about the model binding capabilities of the ASP.Net MVC framework. For starters let me shortly introduce you to default model binding. Assume there is a class as given below:

public class UserInfo
{
    public string UserName { get; set; }
    public string UserEmail { get; set; }
}

With this object, you can do the following to get these 2 information from a user. A default model binder comes in to picture in this case.

  • Have an action method, called, Index
  • The action method returns a view which is strongly typed to the UserInfo class
  • Have an action method called Index decorated with the [HttpPost] attribute and taking UserInfo as a parameter
  • When user enters something and presses the “Submit” button, the action method decorated with [HttpPost] is called
  • The DefaultModelBinder takes the responsibility of mapping the route values and form values to an instance of UserInfo and then passes it to the action method

As you noticed in the listing above, default model binders make it easy in case you have a simple object as above. But, if your model is not a simple object, you may have to use custom model binders. Let us consider building a check box list. In this case, you display an arbitrary list of check box items. So the default model binder would not suffice. So in order to resolve this issue, we need custom model binders. Towards the end of the post, there is a fully working project that utilizes the check box list user control I have created. I hope it acts as a resource to explain the project more comprehensively than I could do here. Without further ado, let me get started on how custom model binders could be used.

The intention is to create a check box list which does not enforce any limits on the number of items. Every check box item could be considered as a collection of the following elements:

  • A check box itself
  • A label containing what the check box represents
  • A hidden field to store the value
  • A hidden field to store the check box state

Note: This implementation is quite different from other ways of implementing a check box list. Towards the end of this post, there are a few helpful links. Have a look at them too!

In order to create these elements, I am using a few custom html helper extensions. This is contained within a class called CustomHtmlHelpers. I am not going to list out the content of this file, but, just give a short description of what every method does.

  • CheckBoxInput – This method creates a chechbox (without a label), a hidden field to track the status of the checkbox. This is required because, if the checkbox is unchecked, there won’t be a value posted to the server when the submit button is clicked. In general, check box lists available on the internet will help you get the values checked by the user, but you will have to regenerate the mode using a database query (or something else). But in this case I reconstruct the entire list using the form values posted.
  • CheckBoxInputLabel – This method creates a label for every checkbox. Clicking on this label would also
  • CheckBoxValue – This generates a hidden field that holds the values for the checkbox
  • CheckBoxListHeader – This generates a header for every individual check box list. This contains a label and a hidden field to store the header

With these extensions, the following user control denotes a sigle check box list:

@model SampleAppForCheckBoxList.Models.CheckBoxListViewModel
@using SampleAppForCheckBoxList.Infrastructure

<div class="cpHeader">
    @Html.CheckBoxListHeader(Model.HeaderText)
</div>
<div class="cpContent">
    @foreach (var item in Model.Items)
    {
        @Html.CheckBoxValue(Model.HeaderText, item, Model.Items.IndexOf(item))
        @Html.CheckBoxInput(Model.HeaderText, item, Model.Items.IndexOf(item))
        @Html.CheckBoxInputLabel(Model.HeaderText, item, Model.Items.IndexOf(item))
        <br />
    }
</div>

If you notice in the above snippet, section under “cpHeader” denotes the header area and “cpContent” denotes the content area – where all the check boxes are listed. Line 2 imports the custom html helper described in the earlier step.

Note: This could also be added to the web.config.

Now, let us create a custom model binder. A custom model binder in ASP.Net MVC should implement the IModelBinder interface. This interface has a single method called BindModel which returns an object. Given below is the implementation of this custom model binder.

public class CheckBoxListViewModelBinder : IModelBinder
{
	public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
	{
	    List<CheckBoxListViewModel> models = new List<CheckBoxListViewModel>();

	    string[] formKeys = controllerContext.HttpContext.Request.Form.AllKeys.ToArray();

	    List<string> rootItems = formKeys.Where(s => s.StartsWith("hdrTitle")).ToList();

	    foreach (var item in rootItems)
	    {
		string hdrValue = item.Split('_')[1];
		string[] txtValues = formKeys.Where(s => s.StartsWith("lblLabel_" + hdrValue)).ToArray();
		string[] valValues = formKeys.Where(s => s.StartsWith("valValue_" + hdrValue)).ToArray();
		string[] hdnValues = formKeys.Where(s => s.StartsWith("hdnChk_" + hdrValue)).ToArray();

		CheckBoxListViewModel model = new CheckBoxListViewModel();
		model.HeaderText = Regex.Replace(hdrValue, "([a-z])([A-Z])", "$1 $2");
		model.Items = new List<CheckBoxListItem>();
		for (int index = 0; index < txtValues.Count(); index++)
		{
		    CheckBoxListItem _item = new CheckBoxListItem();
		    _item.Text = bindingContext.GetValue(txtValues[index]);
		    _item.Value = bindingContext.GetValue(valValues[index]);
		    _item.IsChecked = bool.Parse(bindingContext.GetValue(hdnValues[index]));

		    model.Items.Add(_item);
		}

		models.Add(model);
	    }

	    if (rootItems.Count == 1)
		return models.First();
	    else
		return models;
	}
}

As you can see from the code listing above, the method receives 2 parameters: a ControllerContext instance and a ModelBindingContext instance. The bindingContext can be used to get the value posted for a certain input element, but, it does not provide a method by which we can get a list of all the fields posted. So I use the Form property from the controllerContext.HttpContext.Request.Form instance. Then as you noticed from the html helper, every element uses a certain id/name format. Using this the values are gathered for every element including the header text. Following is a high level algorithm:

  • Find out the number of header elements – this denotes the number of check box lists used. The id/name format is
    hdrTitle_{header_Text}
  • Then using this every other element can be identified as given below

    • Text of the check box is identified using id/name format of lblLabel_{header_Text}_{index}
    • Value of the check box is identified using id/name format of valValue_{header_Text}_{index}
    • Check box checked status of the check box is identified using id/name format of hdnChk_{header_Text}_{index}
  • A CheckBoxListViewModel object is contructed for every check box list and returned.

Now that we have a custom binder, let us see how to put this in to use. You will have to instruct the framework to invoke this binder in case an action method has a parameter of this type. So adding the following 2 lines to Global.asax.cs Application_Start method would take care of this.

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

    ModelBinders.Binders.Add(typeof(CheckBoxListViewModel), new CheckBoxListViewModelBinder());
    ModelBinders.Binders.Add(typeof(List<CheckBoxListViewModel>), new CheckBoxListViewModelBinder());

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

Lines 5 & 6 are of prime importance. These lines indicate that if a parameter of type CheckBoxListViewModel or List<CheckBoxListViewModel> is expected, initialize an instance of CheckBoxListViewModelBinder and pass the controller context and the binding context.

Another important thing to notice is the jquery required to store the status of the check box in the hidden field created for this purpose. Following is the jquery required to do this.

$(document).ready(function () {
    $('.chkClickable').click(function () {
        if ($(this).is(':checked')) {
            $(this).next('.hdnStatus').val('true');
        }
        else {
            $(this).next('.hdnStatus').val('false');
        }
    });
});

Finally, let us put this in to use. If you look in to the DemoController this user control is put in to use as given below:

public ActionResult Index()
{
    return View(GetModel());
}

[HttpPost]
public ActionResult Index(CheckBoxListViewModel model)
{
    ViewData["Choices"] = string.Join(",", model.GetSelectedItems());
    return View(model);
}

private CheckBoxListViewModel GetModel()
{
    var model = new CheckBoxListViewModel();
    model.HeaderText = "Select Languages";
    model.Items = new List<CheckBoxListItem>{ new CheckBoxListItem { Text = "C#", Value = "CSharp", IsChecked = false },
					      new CheckBoxListItem { Text = "Ruby", Value = "Ruby", IsChecked = false },
					      new CheckBoxListItem { Text = "PHP", Value = "PHP", IsChecked = false },
					      new CheckBoxListItem { Text = "Java", Value = "Java", IsChecked = false },
					      new CheckBoxListItem { Text = "Scala", Value = "Scala", IsChecked = false }
    };

    return model;
}

GetModel is simply a method that returns a view model for the check box list. This contains a header text and the items to be displayed in the list. Note that this could very well be a call to the database. The Index action method passes this to the view and the view would in turn pass it on to the user control which would display it.

The action method Index decorated with the [HttpPost] attribute would be invoked when the user submits the form. The method has a CheckBoxListViewModel parameter. So during the post action mvc would invoke the custom binder and repopulate with the user’s choices. The model has the GetSelectedItems method which could be used to identify the items selected by the user.

The project also has another example which has 2 check box lists. This is where the following line from the Global.asax.cs class comes in to use:

ModelBinders.Binders.Add(typeof(List<CheckBoxListViewModel>), new CheckBoxListViewModelBinder());

Note that this method would post a lot more fields (data) in the request than the other method which only posts the selected values.

A demo always helps isn’t it? Here it is!!!

Download the sample app with the user control and associated code files here

Link to github for this project is here – You will be able to get the most latest from here always, because I will check in here in case I make any changes.

Some nice links:

  • Another implementation of check box list is here. I do have similar implementation that returns only the selected values. My implementation uses mvc templates instead of html extensions. When I get a chance I will post my implementation too.
  • A link about a fix for mvc check boxes is here.

Happy coding! Post your comments!!!

Share

ASP.Net MVC Extreme – How Stuff Works

You might have seen the following image, that discusses the control flow of a typical MVC request. In this post I would like to take a deep dive into every one of these blocks in “detail”, down to the last line :) I presume this post is never going to be complete as I may have a clearer notion of some things in the future, when I analyze this further!

mvc general pipeline

UrlRoutingModule class implements the IHttpModule interface, thus implicitly registering itself with IIS to receive all the requests for a certain instance running IIS. UrlRoutingModule gets the request at this method – OnApplicationPostResolveRequestCache when the user enters the url. This could be identified by having a look at the Init method of UrlRoutingModule. This method receives the HttpApplication as the parameter. The Context is retrieved from the HttpApplication object and a HttpContextBase object is created, which is a HttpContextWrapper (RemapHandler call – goes to HttpContext) object. Then UrlRoutingModule.PostResolveRequestCache is called with this object. Given below is the extract of this class from reflector.

// From reflector
public class UrlRoutingModule : IHttpModule
{
    //-- snip --

    // Methods
    protected virtual void Init(HttpApplication application);
    private void OnApplicationPostResolveRequestCache(object sender, EventArgs e);
    //-- snip --
    public virtual void PostResolveRequestCache(HttpContextBase context);
    //-- snip --

    // Properties
    public RouteCollection RouteCollection { get; set; }
}

PostResolveRequestCache does a lot of things. Some of them are: The RouteData object obtained from the RouteCollection property has a GetRouteData method. Using this method the RouteData for the corresponding HttpContextBase is obtained. This RouteData property has the MvcRouteHandler to be used as the RouteHandler property.Using this MvcRouteHandler instance, the GetHttpHandler method of the MvcRouteHandler is used to get the reference to the MvcHandler, by passing in a RequestContext object.

HttpContextBase instance passed to the UrlRoutingModule is used to remap the handler at IIS, which would now be the MvcHandler. Given below is an excercept from this method using reflector.

// From reflector
public virtual void PostResolveRequestCache(HttpContextBase context)
{
    RouteData routeData = this.RouteCollection.GetRouteData(context);
    if (routeData != null)
    {
        IRouteHandler routeHandler = routeData.RouteHandler;

        //-- snip --

        if (!(routeHandler is StopRoutingHandler))
        {
            RequestContext requestContext = new RequestContext(context, routeData);
            context.Request.RequestContext = requestContext;
            IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);

            //-- snip --

            if (httpHandler is UrlAuthFailureHandler)
            {
                //-- snip --
            }
            else
            {
                context.RemapHandler(httpHandler);
            }
        }
    }
}

HttpContextWrapper.RemapHandler gets the MvcHandler. This in turn calls the RemapHandler method in the HttpContext instance. It also has the IIS7WorkerRequest object and its SetRemapHandler method takes 2 parameters, handler type and handler name. This is where a link between the IIS and the handler is established. I am yet to dig in to this area further. Will keep this post updated! HttpContext (Context) has the WorkerRequest property which gets the MvcHandler instance.

// From reflector
public void RemapHandler(IHttpHandler handler)
{
    IIS7WorkerRequest request = this._wr as IIS7WorkerRequest;
    if (request != null)
    {
        //-- snip --

        string handlerType = null;
        string handlerName = null;
        if (handler != null)
        {
            Type type = handler.GetType();
            handlerType = type.AssemblyQualifiedName;
            handlerName = type.FullName;
        }
        request.SetRemapHandler(handlerType, handlerName);
    }
    this._remapHandler = handler;
}

Let’s dig inside the SetRemapHandler method of IIS7WorkerRequest class. Earlier, I said about the linkage to IIS. This is how it’s done. The SetRemapHadler method of IIS7WorkerRequest makes an unmanaged method call to MdgSetRemapHandler method which belongs to the UnsafeIISMethods class. An excercept from reflector is given below:

// From reflector
internal void SetRemapHandler(string handlerType, string handlerName)
{
    Misc.ThrowIfFailedHr(UnsafeIISMethods.MgdSetRemapHandler(this._context, handlerName, handlerType));
}

MvcHandler has a ProcessRequest method, just like any other handlers as it implements the IHttpHandler interface. So using the linkage between the IIS and the handler, I would guess the ProcessRequest method is called by the IIS. Then the request passes on to the MvcHandler. From this point onwards it’s upto the MvcHandler to identify the correct controller and invoke its execute method. Now, lets dig inside the MvcHandler type.

MvcHandler’s ProcessRequest method’s first step would be get an instance of the Controller and the IControllerFactory using the ProcessRequestInit method. The factory instance is required in order to release the controller after successful/failed execution of the chosen action. MvcHandler uses the Controller factory instance and tries to get a IController instance. If successful, the Execute method is called.

// From reflector
protected internal virtual void ProcessRequest(HttpContextBase httpContext)
{
    SecurityUtil.ProcessInApplicationTrust(delegate {
        IController controller;
        IControllerFactory factory;
        this.ProcessRequestInit(httpContext, out controller, out factory);
        try
        {
            controller.Execute(this.RequestContext);
        }
        finally
        {
            factory.ReleaseController(controller);
        }
    });
}

The IControllerFactory could be the default controller factory or a custom factory initiailized (set) during the Application_Start event, as shown below:

protected void Application_Start()
{
   AreaRegistration.RegisterAllAreas();
   RegisterRoutes(RouteTable.Routes);

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

All controllers inherit from the Controller base class, which in turn inherits from the ControllerBase which implements the IController interface. When the MvcHandler calls the Execute method in ProcessRequest using the IController instance, it executes the Execute method in ControllerBase, which calls ExecuteCore which is implemented in Controller as in ControllerBase its an abstract method. ExecuteCore finds the appropriate action method and proceeds. Just for the kicks here is an extract for this method from the reflector.

// From reflector
protected override void ExecuteCore()
{
    this.PossiblyLoadTempData();
    try
    {
        string requiredString = this.RouteData.GetRequiredString("action");
        if (!this.ActionInvoker.InvokeAction(base.ControllerContext, requiredString))
        {
            this.HandleUnknownAction(requiredString);
        }
    }
    finally
    {
        this.PossiblySaveTempData();
    }
}
Share

Custom Error Attributes (MVC 3)

In this post, I would like to discuss about custom error attributes in MVC 3. If you are a developer, you should be familiar with the “yellow screen of death (YSOD)”.¬†Annotating your controller with [HandleError] would take care of this.This attribute would expect a view called Error in the Shared views folder. Note that there should be a corresponding Error action method in the ‘Home’ controller. In case the view of the error is any different or you wish to have a html page you need to add a customErrors section in your web.config, but I am going to skip this as it’s out of scope for this post. This post deals with creating a custom error attribute. This attribute would do the same thing – redirect you to an error view. But it would do another thing apart from this. That is to log the error to a table. This post does not delve in to actually implementing the database layer as that part is straight forward. In order to get started, add a new class file called MyAppErrorAttribute. This class should inherit the HandleErrorAttribute and override the OnException method as shown below:

public class MyAppErrorAttribute : HandleErrorAttribute
{
  public override void OnException(ExceptionContext filterContext)
  {
     Exception exception = filterContext.Exception;

     // Call the method to log the exception
     // -- method call to log the exception

     filterContext.ExceptionHandled = true;
     filterContext.Result = new RedirectResult("~/Home/Error");
     base.OnException(filterContext);
  }
}

The OnException method gets the exception from the ExceptionContext. Now this is just a normal Exception object which could be handled anyway you wish to. In my case, I am getting the exception message, the entire exception, when the exception occurred and who was user logged in during that time. After this we need to set the ‘ExceptionContext.ExceptionHandled’ attribute to true so that the user does not see the YSOD. Also, you need to set the ‘ExceptionContext.Result’ property to specify the view to be redirected when OnException method of the base class is called. At this point, you could annotate your controllers with the [MyAppError] attribute. So when there is an exception, the exception would be logged and then the user would get to see the error view page.

[MyAppError]
public class SomeController : Controller
{
     // -- controller logic
}

But, in case you/somebody is going to be adding a number of other controllers, you/they may not remember about this attribute. So this is what you could do. Global.asax.cs has a RegisterGlobalFilters method, where you could add filters that would apply to all of the controllers. How this could be achieved is given below in the following snippet. Make sure you also have the RegisterGlobalFilters(GlobalFilters.Filters); call in Application_Start method for the global filters registered to work.

public class MvcApplication : System.Web.HttpApplication
{
   public static void RegisterGlobalFilters(GlobalFilterCollection filters)
   {
     filters.Add(new MyAppErrorAttribute());
   }

   protected void Application_Start()
   {
      // -- other code
      RegisterGlobalFilters(GlobalFilters.Filters);
      // -- other code
    }
}

After this step, any exception raised within any controller would invoke our custom error attribute, logging the exception and then redirecting to the default error view. Hope this helps and do leave your comments about this post!

Share