<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[ASP.NET - Greg Shackles]]></title><description><![CDATA[ASP.NET - Greg Shackles]]></description><link>https://gregshackles.com/</link><image><url>https://gregshackles.com/favicon.png</url><title>ASP.NET - Greg Shackles</title><link>https://gregshackles.com/</link></image><generator>Ghost 4.32</generator><lastBuildDate>Tue, 09 Jun 2026 21:21:00 GMT</lastBuildDate><atom:link href="https://gregshackles.com/tag/asp-net/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Custom Ordering of Action Filters in ASP.NET MVC]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I recently stumbled across something with ASP.NET MVC action filters where they weren&#x2019;t being executed in quite the order I was expecting. More specifically, I had made a poor assumption that filters defined at the Controller level would all execute prior to any action-level filters. After all,</p>]]></description><link>https://gregshackles.com/custom-ordering-of-action-filters-in-asp-net-mvc/</link><guid isPermaLink="false">61ce48a0437e8200017d4100</guid><category><![CDATA[ASP.NET]]></category><category><![CDATA[MVC]]></category><dc:creator><![CDATA[Greg Shackles]]></dc:creator><pubDate>Tue, 28 Sep 2010 13:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I recently stumbled across something with ASP.NET MVC action filters where they weren&#x2019;t being executed in quite the order I was expecting. More specifically, I had made a poor assumption that filters defined at the Controller level would all execute prior to any action-level filters. After all, that was the behavior I thought I had seen before, but it turned out that it worked a bit differently. In this post I will explore exactly how ASP.NET MVC finds and orders filters, and what your options are for working with it.</p>
<h2 id="introductiontoactionfilterattribute">Introduction to ActionFilterAttribute</h2>
<p>I&#x2019;ll start off with a quick introduction to <a href="http://msdn.microsoft.com/en-us/library/dd470536(v=VS.90).aspx">ActionFilterAttribute</a>, in case you are not familiar with it. ActionFilterAttribute is an sbtract class you can extend to gain access to different injection points in the execution of an action method. The attribute can decorate either an action method or an entire controller. In the case of decorating the controller, the filter will get applied to any action method inside that controller. If an action method in that controller also defines the same filter, and that filter does not allow for multiple instances, the filter on the action gets overridden by the one on the controller. In this example, both FilterOne and FilterTwo will be applied to the Index() action:</p>
<pre><code class="language-language-csharp">[FilterOne()]
public class HomeController : CustomController
{
	[FilterTwo()]
	public ActionResult Index()
	{
		return View();
	}
}
</code></pre>
<p>For more information on the basics of using filters, check out <a href="http://msdn.microsoft.com/en-us/library/dd381609.aspx">this article</a>.</p>
<h2 id="keepingyourfiltersinorder">Keeping Your Filters In Order</h2>
<p>What happens when you need your filters to execute in a certain order? Fortunately, the attribute provides an <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.filterattribute.order(v=VS.90).aspx">Order property</a> for just such an occasion, but it comes with certain behaviors to keep in mind. First, it&#x2019;s important to remember that filters that implement OnActionExecuting or OnActionExecuted will fire before any filters that do not, simply because those events happen first. You are also restricted to entering values of 0 or greater. Otherwise, filters are applied in ascending order according to the value of their Order property.</p>
<p>If no value is provided, the default value for Order is -1. This is exactly where my original confusion came in: any filter that does not specify a value for Order will fire before any filter that does, since -1 is less than 0. One I introduced a strict order for the filters on my base controller, I started seeing all the other filters executing before them, which was definitely not ideal.</p>
<h2 id="implementationdetails">Implementation Details</h2>
<p>Since ASP.NET MVC is open source, I figured I would take a look to see how it was implemented to help see what my options were for working around my problem. The Controller class has a property called ActionInvoker, defined as:</p>
<pre><code class="language-language-csharp">public IActionInvoker ActionInvoker {
	get {
		if (_actionInvoker == null) {
			_actionInvoker = CreateActionInvoker();
		}
		return _actionInvoker;
	}
	set {
		_actionInvoker = value;
	}
}

protected virtual IActionInvoker CreateActionInvoker() {
	return new ControllerActionInvoker();
}
</code></pre>
<p>By default, it holds an instance of ControllerActionInvoker. In that class, there are a few methods that dictate how filters are discovered and applied for an action. The main starting point in here is the InvokeAction method, which as the name implies, tries to begin invoking a specific action on a controller. It retrieves a list of filters on the action by calling GetFilters(ControllerContext, ActionDescriptor):</p>
<pre><code class="language-language-csharp">protected virtual FilterInfo GetFilters(
    ControllerContext controllerContext,
    ActionDescriptor actionDescriptor) {
	FilterInfo filters = actionDescriptor.GetFilters();

	// if the current controller implements one of the filter interfaces, it should be added to the list at position 0
	ControllerBase controller = controllerContext.Controller;
	AddControllerToFilterList(controller, filters.ActionFilters);
	AddControllerToFilterList(controller, filters.ResultFilters);
	AddControllerToFilterList(controller, filters.AuthorizationFilters);
	AddControllerToFilterList(controller, filters.ExceptionFilters);

	return filters;
}
</code></pre>
<p>That method gets a list of filters from the action and then segments them off into different lists based on their type. You&#x2019;ll see why this happens soon. The actual ordering of the filters happens in actionDescriptor.GetFilters():</p>
<pre><code class="language-language-csharp">internal static FilterInfo GetFilters(MethodInfo methodInfo) {
	// Enumerable.OrderBy() is a stable sort, so this method preserves scope ordering.
	FilterAttribute[] typeFilters =
            (FilterAttribute[])methodInfo
                .ReflectedType
                .GetCustomAttributes(typeof(FilterAttribute), true);
	FilterAttribute[] methodFilters =
            (FilterAttribute[])methodInfo
                .GetCustomAttributes(typeof(FilterAttribute), true);
	List&lt;FilterAttribute&gt; orderedFilters =
            RemoveOverriddenFilters(
                typeFilters.Concat(methodFilters)
            ).OrderBy(attr =&gt; attr.Order).ToList();

	FilterInfo filterInfo = new FilterInfo();
	MergeFiltersIntoList(orderedFilters, filterInfo.ActionFilters);
	MergeFiltersIntoList(orderedFilters, filterInfo.AuthorizationFilters);
	MergeFiltersIntoList(orderedFilters, filterInfo.ExceptionFilters);
	MergeFiltersIntoList(orderedFilters, filterInfo.ResultFilters);
	return filterInfo;
}
</code></pre>
<p>It grabs filters from the controller and action method, removes overridden filters based on the rules I mentioned earlier, and then orders them based on the Order property. If we jump back to the InvokeAction method, we can see that it executes authorization filters first, and then moves on to execute the remaining filters:</p>
<pre><code class="language-language-csharp">AuthorizationContext authContext =
    InvokeAuthorizationFilters(
        controllerContext,
        filterInfo.AuthorizationFilters,
        actionDescriptor);

if (authContext.Result != null) {
	// the auth filter signaled that we should let it short-circuit the request
	InvokeActionResult(controllerContext, authContext.Result);
}
else {
	if (controllerContext.Controller.ValidateRequest) {
		ValidateRequest(controllerContext);
	}

	IDictionary&lt;string, object&gt; parameters =
            GetParameterValues(controllerContext, actionDescriptor);
	ActionExecutedContext postActionContext =
            InvokeActionMethodWithFilters(
                controllerContext, filterInfo.ActionFilters,
                actionDescriptor, parameters);
	InvokeActionResultWithFilters(
            controllerContext, filterInfo.ResultFilters,
            postActionContext.Result);
}
</code></pre>
<h2 id="customizationoptions">Customization Options</h2>
<p>So now we have seen how filters are applied, and the underlying implementation of it. What options are there for achieving the filter order you want?</p>
<p>In this case, the simplest solution is probably the best one &#x2013; it just requires being aware of the traps we&#x2019;ve talked about to avoid running into them. If you have define some filter order ranges, you can be sure that certain filters will be applied before others are run. The big catch of course is that it means every time you add a filter to an action or a controller you need to specify an order, to make sure it doesn&#x2019;t get executed before the filters that should go first.</p>
<p>That said, ASP.NET MVC is full of extensibility points where you can plug in pretty much any behavior you want, so this seemed like a good chance to try that out again. For this example we&#x2019;ll augment the existing ordering by also providing a way of prioritizing certain filters. To get started, let&#x2019;s define two test filters that simply write out to the response stream when they get executed:</p>
<pre><code class="language-language-csharp">public class FilterOne : ActionFilterAttribute
{
	public override void OnActionExecuting(ActionExecutingContext filterContext)
	{
		filterContext.HttpContext.Response.Write(&quot;One&lt;br /&gt;&quot;);
	}
}

public class FilterTwo : ActionFilterAttribute
{
	public override void OnActionExecuting(ActionExecutingContext filterContext)
	{
		filterContext.HttpContext.Response.Write(&quot;Two&lt;br /&gt;&quot;);
	}
}
</code></pre>
<p>And then we&#x2019;ll define a controller and action method for testing those filters:</p>
<pre><code class="language-language-csharp">[FilterOne(Order = 1), FilterTwo(Order = 2)]
public class HomeController
{
	public ContentResult Index()
	{
		return Content(&quot;&quot;);
	}
}
</code></pre>
<p>If you run it, you&#x2019;ll see that FilterOne executes before FilterTwo, as expected. Now let&#x2019;s build up a small framework for prioritizing filters. First, here is an extension method for IList I&#x2019;ll use later to fluently add all items in a collection to a list:</p>
<pre><code class="language-language-csharp">public static class ListExtensions
{
	public static IList&lt;T&gt; AddAll&lt;T&gt;(this IList&lt;T&gt; destination, IEnumerable&lt;T&gt; source)
	{
		foreach (T item in source)
		{
			destination.Add(item);
		}

		return destination;
	}
}
</code></pre>
<p>For this example, a filter either is or isn&#x2019;t prioritized, so there won&#x2019;t be different levels of priority. To say a filter should get prioritized, it should implement the IPriorityFilter interface:</p>
<pre><code class="language-language-csharp">public interface IPriorityFilter
{
}
</code></pre>
<p>FilterTwo should be updated so that it is marked as a priority:</p>
<pre><code class="language-language-csharp">public class FilterTwo : ActionFilterAttribute, IPriorityFilter
</code></pre>
<p>Now we need to define our own custom IActionInvoker, which is where all the real logic goes. Since the default MVC ControllerActionInvoker does almost everything we want, we can leverage that and just swap out the part we want to change:</p>
<pre><code class="language-language-csharp">public class PrioritizedControllerActionInvoker : ControllerActionInvoker
{
	protected override FilterInfo GetFilters(
            ControllerContext controllerContext,
            ActionDescriptor actionDescriptor)
	{
		FilterInfo filterInfo = actionDescriptor.GetFilters();

		prioritizeFilters(filterInfo.ActionFilters);
		prioritizeFilters(filterInfo.AuthorizationFilters);
		prioritizeFilters(filterInfo.ExceptionFilters);
		prioritizeFilters(filterInfo.ResultFilters);

		return filterInfo;
	}

	private void prioritizeFilters&lt;T&gt;(IList&lt;T&gt; filters)
	{
		IList&lt;T&gt; originalFilters = filters.ToList();
		IEnumerable&lt;T&gt; priorityFilters =
                    originalFilters
                       .Where(filter =&gt; (filter as IPriorityFilter) != null);

		filters.Clear();

		filters
			.AddAll(priorityFilters)
			.AddAll(
				originalFilters.Except(priorityFilters)
			);
	}
}
</code></pre>
<p>It uses the default implementation of ActionDescriptor.GetFilters() so we don&#x2019;t need to worry about all the details, and then just rearranges the order of the filters based on the presence of IPriorityFilter. Next we&#x2019;ll need a custom controller that uses it:</p>
<pre><code class="language-language-csharp">public abstract class CustomController : Controller
{
	protected override IActionInvoker CreateActionInvoker()
	{
		return new PrioritizedControllerActionInvoker();
	}
}
</code></pre>
<p>Finally, update HomeController so that it uses the custom controller instead of the default one:</p>
<pre><code class="language-language-csharp">public class HomeController : CustomController
</code></pre>
<p>And that&#x2019;s it! If you fire the page up again, you&#x2019;ll see FilterTwo processed before FilterOne, even though the default ordering says otherwise.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Anonymous View Models in ASP.NET MVC Using Dynamics]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>The introduction of the dynamic keyword in C# 4.0 allows you to do a lot of things you couldn&#x2019;t do otherwise, but it also makes it easy to forget that C# is still not a dynamic language, so there are limitations. Recently I found myself wanting to</p>]]></description><link>https://gregshackles.com/anonymous-view-models-in-asp-net-mvc-using-dynamics/</link><guid isPermaLink="false">61ce48a0437e8200017d40ff</guid><category><![CDATA[ASP.NET]]></category><category><![CDATA[MVC]]></category><dc:creator><![CDATA[Greg Shackles]]></dc:creator><pubDate>Sun, 19 Sep 2010 13:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>The introduction of the dynamic keyword in C# 4.0 allows you to do a lot of things you couldn&#x2019;t do otherwise, but it also makes it easy to forget that C# is still not a dynamic language, so there are limitations. Recently I found myself wanting to whip up a quick test page for something, with a very simple controller action and view. It wasn&#x2019;t meant to be permanent, so creating a dedicated view model class in the project seemed like overkill. I figured I could just return an anonymous object as the model, and use a dynamic view to display it. I was wrong.</p>
<h2 id="thelimitsofanonymousclasses">The Limits of Anonymous Classes</h2>
<p>Let&#x2019;s take a look at a quick example to demonstrate the problem. Here is my very simple controller action, that uses an anonymous class as the view model:</p>
<pre><code class="language-language-csharp">public ActionResult UsingDynamic()
{
  return View(new
  {
    TestString = &quot;This is a test string&quot;
  });
}
</code></pre>
<p>Now let&#x2019;s make sure the data gets sent correctly to the view. First we&#x2019;ll try just printing the model to the page using its ToString() method:</p>
<pre><code class="language-language-aspnet">&lt;%: Model %&gt;
</code></pre>
<p>We get the output:</p>
<pre><code>{ TestString = This is a test string }
</code></pre>
<p>So far so good! We see an object that has the TestString property and value we wanted. Now let&#x2019;s try printing out the value of TestString:</p>
<pre><code class="language-language-aspnet">&lt;%: Model.TestString %&gt;
</code></pre>
<p>This time ASP.NET throws an exception back at us, saying &#x201C;&#x2018;object&#x2019; does not contain a definition for &#x2018;TestString&#x2019;&#x201D;. How can this be? When we printed the object we could clearly see it had a property named TestString, and had a value for it. The answer here lies in the fact that anonymous classes are internal by default, meaning they are only accessible to the assembly in which they were created. Once you cross that assembly boundary, it gets treated as a regular object, which does not have the TestString property.</p>
<p>So if anonymous classes are internal, how can we accomplish what we want? There are a few ways I could think of.</p>
<h2 id="useapoco">Use a POCO</h2>
<p>I know I said this was the solution I was trying to avoid, but I thought it was worth mentioning because in a majority of cases, having a well defined view model is a good choice. To wire this up using a defined view model, it would look something like this:</p>
<pre><code class="language-language-csharp">public class PocoViewModel
{
    public string TestString { get; set; }
}
</code></pre>
<p>And the controller action:</p>
<pre><code class="language-language-csharp">public ActionResult UsingPoco()
{
    return View(new PocoViewModel()
    {
        TestString = &quot;This is a test string&quot;
    });
}
</code></pre>
<p>The view would just need to inherit from ViewPage and it would work as expected.</p>
<h2 id="expandoobjects">ExpandoObjects</h2>
<p>Another new addition in .NET 4.0 is the <a href="http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx?ppud=4">ExpandoObject</a>. An ExpandoObject is an object that allows for dynamically adding and removing members at runtime. Since that is its purpose, it gets us something pretty similar to what we were trying to achieve with the anonymous class, but it will make it over the assembly boundary. The controller action using an ExpandoObject would look like:</p>
<pre><code class="language-language-csharp">public ActionResult UsingExpando()
{
    dynamic viewModel = new ExpandoObject();
    viewModel.TestString = &quot;This is a test string&quot;;

    return View(viewModel);
}
</code></pre>
<p>The view should inherit from ViewPage (which is now actually the default), and it would be able to successfully access the TestString property. This is actually pretty much what they&#x2019;re doing in ASP.NET MVC 3 with the new ViewModel property in Controller.</p>
<h2 id="dynamicreflection">Dynamic Reflection</h2>
<p>But what if you don&#x2019;t want to use an ExpandoObject, and just want to throw an anonymous class at your view and have it just work? You can actually make this happen with an impressively small amount of code. First, we&#x2019;ll create a custom dynamic class that wraps another object instance, and uses reflection to provide property access to that instance. To do that, the class will extend the <a href="http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx">DynamicObject</a> class, which handles most of the heavy lifting for dealing with dynamics. If we wanted to do everything outselves, we could implement <a href="http://msdn.microsoft.com/en-us/library/system.dynamic.idynamicmetaobjectprovider.aspx">IDynamicMetaObjectProvider</a> ourselves (which DynamicObject does), but in this case there&#x2019;s no real reason to, so why not let DynamicObject do the hard work for us?</p>
<pre><code class="language-language-csharp">public class DynamicPageObject : DynamicObject
{
    private object _originalObject;

    public DynamicPageObject(object originalObject)
    {
        _originalObject = originalObject;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = _originalObject
                    .GetType()
                    .InvokeMember(binder.Name,
                                  BindingFlags.GetProperty
                                      | BindingFlags.Instance
                                      | BindingFlags.Public,
                                  null,
                                  _originalObject,
                                  null);

        return true;
    }
}
</code></pre>
<p>There we override the TryGetMember(&#x2026;) function of DynamicObject, to allow it to use reflection over the original object to provide its member access. It&#x2019;s pretty simple reflection, and that&#x2019;s all there is to it.</p>
<p>Next we&#x2019;ll create our own class that extends ViewPage that will automatically wrap the model in a DynamicPageObject:</p>
<pre><code class="language-language-csharp">public class DynamicPage : ViewPage
{
    public new dynamic Model { get; set; }

    protected override void SetViewData(ViewDataDictionary viewData)
    {
        base.SetViewData(viewData);

        Model = new DynamicPageObject(viewData.Model);
    }
}
</code></pre>
<p>We override the base Model property to use a dynamic model, which gets set to a DynamicPageObject that wraps around the original model. That&#x2019;s all the code we need to make this work, so let&#x2019;s give it a shot. The controller action is identical to the one from the original example, using an anonymous class:</p>
<pre><code class="language-language-csharp">public ActionResult UsingCustomDynamic()
{
    return View(new
    {
        TestString = &quot;This is a test string&quot;
    });
}
</code></pre>
<p>For the view, the only thing we need to do is have it inherit from DynamicPage and we&#x2019;re done. Now we have a controller passing in an anonymous class as a view model, and a view that can handle that dynamically.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Attribute-Based Property Aliases Using MongoDB and NoRM]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Since <a href="http://www.mongodb.org/">MongoDB</a> is a document database, collections don&#x2019;t have an enforced schema. Each document in a collection needs to store the names of all of its properties, making the length of that name more significant. Using abbreviated property names helps cut down on the storage space needed for</p>]]></description><link>https://gregshackles.com/attribute-based-property-aliases-using-mongodb-and-norm/</link><guid isPermaLink="false">61ce48a0437e8200017d40fe</guid><category><![CDATA[ASP.NET]]></category><category><![CDATA[MongoDB]]></category><category><![CDATA[NoRM]]></category><dc:creator><![CDATA[Greg Shackles]]></dc:creator><pubDate>Thu, 12 Aug 2010 13:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Since <a href="http://www.mongodb.org/">MongoDB</a> is a document database, collections don&#x2019;t have an enforced schema. Each document in a collection needs to store the names of all of its properties, making the length of that name more significant. Using abbreviated property names helps cut down on the storage space needed for each document, but it&#x2019;s not ideal to mirror those abbreviated names in your object model. To help solve this problem, the <a href="http://normproject.org/">NoRM</a> driver provides an easy mechanism for defining custom mappings between the document and your model. First I&#x2019;ll go through the standard way of doing it, and then I&#x2019;ll present a custom solution that helps cut down on the amount of code you have to write by using attributes.</p>
<h2 id="themodel">The Model</h2>
<p>First, let&#x2019;s define a very simple model for trying this out. I have an interface that all Mongo model objects will implement, that makes sure they have a Mongo identifier property:</p>
<pre><code class="language-language-csharp">public interface IMongoObject
{
    ObjectId Id { get; set; }
}
</code></pre>
<p>Then we have a Person class:</p>
<pre><code class="language-language-csharp">public class Person : IMongoObject
{
    public ObjectId Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}
</code></pre>
<p>In MongoDB, I have a collection named Person, populated with a small amount of data:</p>
<pre><code>&gt; db.Person.find();
{ &quot;_id&quot; : ObjectId(&quot;4c64077b763a000000002f4c&quot;), &quot;fn&quot; : &quot;Greg&quot;, &quot;ln&quot; : &quot;Shackles&quot; }
{ &quot;_id&quot; : ObjectId(&quot;4c640792763a000000002f4d&quot;), &quot;fn&quot; : &quot;John&quot;, &quot;ln&quot; : &quot;Doe&quot; }
{ &quot;_id&quot; : ObjectId(&quot;4c640796763a000000002f4e&quot;), &quot;fn&quot; : &quot;Jane&quot;, &quot;ln&quot; : &quot;Doe&quot; }
</code></pre>
<p>You can see there that the documents use &#x201C;fn&#x201D; and &#x201C;ln&#x201D; instead of &#x201C;FirstName&#x201D; and &#x201C;LastName&#x201D;. Since the data access classes aren&#x2019;t what I want to focus on, here are the (very basic) DAO classes we&#x2019;ll use:</p>
<pre><code class="language-language-csharp">public abstract class DaoBase&lt;T&gt;
    where T : IMongoObject
{
    private string _connectionString;

    public DaoBase(string connectionString)
    {
        _connectionString = connectionString;
    }

    protected IQueryable&lt;T&gt; FindAll()
    {
        using (var mongo = Mongo.Create(_connectionString))
        {
            return mongo.GetCollection&lt;T&gt;().AsQueryable();
        }
    }
}
</code></pre>
<pre><code class="language-language-csharp">public class PersonDao : DaoBase&lt;Person&gt;, IPersonDao
{
    public PersonDao(string connectionString)
        : base(connectionString)
    {
    }

    public IEnumerable&lt;Person&gt; FindAllPeople()
    {
        return FindAll();
    }

    public IEnumerable&lt;Person&gt; FindByLastName(string lastName)
    {
        return FindAll().Where(person =&gt; person.LastName == lastName);
    }
}
</code></pre>
<h2 id="thetest">The Test</h2>
<p>To make sure everything works, let&#x2019;s set up a very simple page that will grab all the documents from the collection and display them as a list. Here&#x2019;s the controller:</p>
<pre><code class="language-language-csharp">public class HomeController : Controller
{
    [Inject]
    public IPersonDao PersonDao { get; set; }

    public ActionResult Index()
    {
        var people =
            PersonDao
                .FindAllPeople()
                .OrderBy(person =&gt; person.LastName)
                .ThenBy(person =&gt; person.FirstName);

        return View(people);
    }
}
</code></pre>
<p>I&#x2019;m using <a href="http://ninject.org/">Ninject</a> to create and inject the PersonDao dependency into the controller. That&#x2019;s outside the scope of this post, but you can dig into the sample if you want to see how that works. Here&#x2019;s the relevant part of the view:</p>
<pre><code class="language-language-aspnet">&lt;ul&gt;
    &lt;% foreach (var person in Model)
       { %&gt;

        &lt;li&gt;
            &lt;%: person.LastName %&gt;, &lt;%: person.FirstName %&gt;
        &lt;/li&gt;

    &lt;% } %&gt;
&lt;/ul&gt;
</code></pre>
<h2 id="gotmaps">Got Maps?</h2>
<p>If you tried to run that test page right now NoRM would throw an error at you saying that it couldn&#x2019;t find properties on Person for &#x201C;fn&#x201D; and &#x201C;ln&#x201D;. If you don&#x2019;t tell it otherwise, it assumes that it should map a document property to a model property with the same name. To customize this we can define a MongoConfigurationMap. If you&#x2019;re familiar with FluentNHibernate, this should feel pretty familiar.</p>
<pre><code class="language-language-csharp">public class PersonMap : MongoConfigurationMap
{
    public PersonMap()
    {
        For&lt;Person&gt;(config =&gt;
        {
            config
                .ForProperty(person =&gt; person.FirstName)
                .UseAlias(&quot;fn&quot;);

            config
                .ForProperty(person =&gt; person.LastName)
                .UseAlias(&quot;ln&quot;);
        });
    }
}
</code></pre>
<p>Now NoRM will know to map a Person object, right? Almost. We just need to register that map so it knows to use it. In the constructor for PersonDao, let&#x2019;s add this line to register it:</p>
<pre><code class="language-language-csharp">MongoConfiguration.Initialize(config =&gt; config.AddMap&lt;PersonMap&gt;());
</code></pre>
<p>Now if we fire up the test page we&#x2019;ll get a nice ordered list of names, fresh out of MongoDB.</p>
<h2 id="usingattributes">Using Attributes</h2>
<p>Defining a map is very simple, but I didn&#x2019;t like the idea of defining a new map for every class, just to set some string aliases. To get around that, I decided to create an attribute to put on properties that specifies an alias name, and then a custom map that uses reflection to create a map based on the attributes.</p>
<p>The attribute is very simple, and just takes in a string:</p>
<pre><code class="language-language-csharp">public class MongoAliasAttribute : Attribute
{
    public string AliasName { get; set; }

    public MongoAliasAttribute()
    {
    }

    public MongoAliasAttribute(string aliasName)
    {
        AliasName = aliasName;
    }
}
</code></pre>
<p>The heavy lifting all happens in the typed AttributeMap:</p>
<pre><code class="language-language-csharp">public class AttributeMap&lt;T&gt; : MongoConfigurationMap
{
    public AttributeMap()
    {
        var mappings = getAliasMappings();

        For&lt;T&gt;(config =&gt;
        {
            foreach (var mapping in mappings)
            {
                config
                    .ForProperty(getPropertyByNameExpression(mapping.Key))
                    .UseAlias(mapping.Value);
            }
        });
    }

    private Expression&lt;Func&lt;T, object&gt;&gt; getPropertyByNameExpression(string propertyName)
    {
        ParameterExpression param = Expression.Parameter(typeof(T));
        UnaryExpression body =
            Expression.Convert(
                Expression.Property(param, propertyName),
                typeof(object)
            );

        return Expression.Lambda&lt;Func&lt;T, object&gt;&gt;(body, param);
    }

    private Dictionary&lt;string, string&gt; getAliasMappings()
    {
        var mappings = new Dictionary&lt;string, string&gt;();

        foreach (var item in typeof(T).GetProperties())
        {
            MongoAliasAttribute aliasAttribute =
                item.GetCustomAttributes(false)
                    .OfType&lt;MongoAliasAttribute&gt;()
                    .FirstOrDefault();

            if (aliasAttribute != null)
            {
                mappings.Add(item.Name, aliasAttribute.AliasName);
            }
        }

        return mappings;
    }
}
</code></pre>
<p>First, the getAliasMappings() function reflects on the current type, and finds any properties decorated with MongoAliasAttribute, returning a dictionary that maps property names to their aliases. Then for each mapping, it tells NoRM to alias the properties. Since the ForProperty method expects a lambda expression for specifying which property to alias, the getPropertyByNameExpression() function builds that expression.</p>
<p>Now to register this map with NoRM. To make this easier to use for other classes, let&#x2019;s move the registration into DaoBase and remove the MongoConfiguration.Initialize() call from the PersonDao constructor. Next we&#x2019;ll define a Map() method in the base class, and call it from the constructor:</p>
<pre><code class="language-language-csharp">protected virtual void Map()
{
    MongoConfiguration.Initialize(config =&gt; config.AddMap&lt;AttributeMap&lt;T&gt;&gt;());
}
</code></pre>
<p>Finally, we update the Person model object so that it specifies the aliases it wants to use:</p>
<pre><code class="language-language-csharp">public class Person : IMongoObject
{
    public ObjectId Id { get; set; }

    [MongoAlias(&quot;fn&quot;)]
    public string FirstName { get; set; }

    [MongoAlias(&quot;ln&quot;)]
    public string LastName { get; set; }
}
</code></pre>
<p>If we fire up the test page now everything should work exactly like it did when using PersonMap, and now we don&#x2019;t need a new mapping class every time we want to alias properties in a new collection. The next step here, which I&#x2019;ll leave as an exercise for the reader, is to automatically search the assembly for classes that implement IMongoObject and register an AttributeMap for each of them.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[ASP.NET MVC: Do You Know Where Your TempData Is?]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I recently discovered that despite the fact that I&#x2019;d been using the TempData dictionary in my applications, I didn&#x2019;t really have a full grasp on what it was doing behind the scenes.  Of course this meant learning the lesson the hard way once something stopped working</p>]]></description><link>https://gregshackles.com/asp-net-mvc-do-you-know-where-your-tempdata-is/</link><guid isPermaLink="false">61ce48a0437e8200017d40fc</guid><category><![CDATA[ASP.NET]]></category><category><![CDATA[MVC]]></category><dc:creator><![CDATA[Greg Shackles]]></dc:creator><pubDate>Wed, 14 Jul 2010 13:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I recently discovered that despite the fact that I&#x2019;d been using the TempData dictionary in my applications, I didn&#x2019;t really have a full grasp on what it was doing behind the scenes.  Of course this meant learning the lesson the hard way once something stopped working like I thought it would.  I only really had myself to blame since in the end it was a simple case of RTFM, but it seemed like a good opportunity to dig in and see how TempData really works.</p>
<h2 id="whatistempdata">What is TempData?</h2>
<p>Let&#x2019;s start by describing what TempData gives you. Basically, it&#x2019;s a bucket where you can dump data that is only needed for the following request. That is, anything you put into TempData is discarded after the next request completes. This is useful for one-time messages, such as form validation errors. The important thing to take note of there is that this applies to the next request in the session, so that request can potentially happen in a different browser window or tab. If you need something more persistent, Session is likely what you&#x2019;re looking for.</p>
<h2 id="whereistempdatastored">Where Is TempData Stored?</h2>
<p>This is the part that came back to bite me.  By default, TempData is stored in the session.  Yes, the session!  Most of the time this probably doesn&#x2019;t matter to you, since as long as you get your objects back when you want them you have no reason to worry about where it was kept.  However, let&#x2019;s say you decide you want to switch away from the default <a href="http://msdn.microsoft.com/en-us/library/ms178586.aspx">Session-State Mode</a>, and use State Server Mode or SQL Server Mode.  These modes require that all objects stored in session be serializable.  This is exactly what I did, and without knowing that TempData used the session, it was non-obvious why I started seeing session errors.</p>
<p>You might have noticed that I said that TempData is kept in the session by DEFAULT, meaning you are not tied to that if you decide you don&#x2019;t like it that way.  Let&#x2019;s take a look at some of the <a href="http://aspnet.codeplex.com/releases/view/41742">source code to ASP.NET MVC 2</a> and see how things work.</p>
<p>ITempDataProvider and SessionStateTempDataProvider<br>
In the System.Web.Mvc namespace you&#x2019;ll find a very simple interface called ITempDataProvider that looks like this:</p>
<pre><code class="language-language-csharp">public interface ITempDataProvider {
    IDictionary&lt;string, object&gt; LoadTempData(ControllerContext controllerContext);
    void SaveTempData(ControllerContext controllerContext,
                                IDictionary&lt;string, object&gt; values);
}
</code></pre>
<p>Not much to see there. It simply defines the methods of saving and loading the dictionary. In the same namespace is SessionStateTempDataProvider which implements ITempDataProvider. When loading the dictionary out of the session, it explicitly removes it afterwards to make sure only one request gets access to it:</p>
<pre><code class="language-language-csharp">public virtual IDictionary&lt;string, object&gt; LoadTempData(
    ControllerContext controllerContext) {

    HttpSessionStateBase session = controllerContext.HttpContext.Session;

    if (session != null) {
        Dictionary&lt;string, object&gt; tempDataDictionary =
            session[TempDataSessionStateKey] as Dictionary&lt;string, object&gt;;

        if (tempDataDictionary != null) {
            // If we got it from Session, remove it so that no other request gets it
            session.Remove(TempDataSessionStateKey);
            return tempDataDictionary;
        }
    }

    return new Dictionary&lt;string, object&gt;(StringComparer.OrdinalIgnoreCase);
}
</code></pre>
<p>The controller object has a public property for the TempData provider which that uses the session provider by default:</p>
<pre><code class="language-language-csharp">public ITempDataProvider TempDataProvider {
    get {
        if (_tempDataProvider == null) {
            _tempDataProvider = CreateTempDataProvider();
        }
        return _tempDataProvider;
    }
    set {
        _tempDataProvider = value;
    }
}

protected virtual ITempDataProvider CreateTempDataProvider() {
    return new SessionStateTempDataProvider();
}
</code></pre>
<h2 id="howthetempdataprovidergetsused">How the TempData Provider Gets Used</h2>
<p>If you want to tell your controllers to use a different provider, you set it up in your controller&#x2019;s constructor and you&#x2019;re good to go. You might have also noticed that the LoadTempData(ControllerContext) function in ITempDataProvider returns an IDictionary, but the TempData property on the controller (actually, ControllerBase to be specific), is of type TempDataDictionary. This is another MVC class that wraps around an IDictionary and provides all the functionality we need from TempData. This is a big class so I won&#x2019;t go over everything, but there are a couple parts to highlight. First, you can see that the class is marked as being serializable, so that it can properly be put into session:</p>
<pre><code class="language-language-csharp">[Serializable]
    public class TempDataDictionary : IDictionary&lt;string, object&gt;, ISerializable {
</code></pre>
<p>Second, there is the Load(ControllerContext, ITempDataProvider) function that uses the specified provider to hydrate the dictionary:</p>
<pre><code class="language-language-csharp">public void Load(ControllerContext controllerContext,
                      ITempDataProvider tempDataProvider) {
    IDictionary&lt;string, object&gt; providerDictionary =
        tempDataProvider.LoadTempData(controllerContext);

    _data = (providerDictionary != null)
        ? new Dictionary&lt;string, object&gt;(
              providerDictionary, StringComparer.OrdinalIgnoreCase) :
        new Dictionary&lt;string, object&gt;(StringComparer.OrdinalIgnoreCase);

    _initialKeys = new HashSet&lt;string&gt;(
                      _data.Keys, StringComparer.OrdinalIgnoreCase);

    _retainedKeys.Clear();
}
</code></pre>
<p>Similarly, it also has a Save(ControllerContext, ITempDataProvider) function that uses the provider to save out the new dictionary:</p>
<pre><code class="language-language-csharp">public void Save(ControllerContext controllerContext,
                       ITempDataProvider tempDataProvider) {

    string[] keysToKeep =
        _initialKeys
            .Union(_retainedKeys, StringComparer.OrdinalIgnoreCase)
            .ToArray();

    string[] keysToRemove =
        _data
            .Keys
                .Except(keysToKeep, StringComparer.OrdinalIgnoreCase)
                .ToArray();

    foreach (string key in keysToRemove) {
        _data.Remove(key);
    }

    tempDataProvider.SaveTempData(controllerContext, _data);
}
</code></pre>
<p>The only part left is figuring when in the pipeline TempData gets load, and then when it gets saved out again. The answers to both are found in the <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.executecore.aspx">ExecuteCore() method in Controller</a>. This method gets called by MVC to invoke the current action. In order, it loads TempData, then executes the current action, then saves out the new dictionary:</p>
<pre><code class="language-language-csharp">protected override void ExecuteCore() {
    PossiblyLoadTempData();

    try {
        string actionName = RouteData.GetRequiredString(&quot;action&quot;);

        if (!ActionInvoker.InvokeAction(ControllerContext, actionName)) {
            HandleUnknownAction(actionName);
        }
    }
    finally {
        PossiblySaveTempData();
    }
}
</code></pre>
<p>ASP.NET MVC 2 introduced the concept of RenderAction, where you could call out from a view to another controller action and render it within that view. If you do this, the child action actually shares TempData with the parent request. I have found this useful in passing something down to a child request to avoid having to redo a database call for something needed by both the parent and the child. This logic is part of the PossiblyLoadTempData() and PossiblySaveTempData() functions referenced in ExecureCore():</p>
<pre><code class="language-language-csharp">internal void PossiblyLoadTempData() {
    if (!ControllerContext.IsChildAction) {
        TempData.Load(ControllerContext, TempDataProvider);
    }
}

internal void PossiblySaveTempData() {
    if (!ControllerContext.IsChildAction) {
        TempData.Save(ControllerContext, TempDataProvider);
    }
}
</code></pre>
<p>Those are the highlights of how TempData works under the hood, and how you can plug in a different provider to tailor the behavior to what you want. You can also find references to it outside of the controller in other places where you have access to TempData, such as ViewContext, ViewPage, etc. As of right now the session provider is the only one in the main assembly. The MvcFutures assembly includes the CookieTempDataProvider class which provides cookie-based TempData storage.</p>
<h2 id="amongodbtempdataprovider">A MongoDB TempData Provider</h2>
<p>I think we&#x2019;ve looked at enough ASP.NET MVC code now, so let&#x2019;s try writing a custom provider. For this example I&#x2019;m going to store the data in a <a href="http://www.mongodb.org/">MongoDB</a> collection. Now, keep in mind that this example is meant to show how to implement a custom provider, so I&#x2019;m not trying to make a case that you should store your TempData in MongoDB. For this example I&#x2019;m going to use the <a href="http://github.com/samus/mongodb-csharp">MongoDB-CSharp driver</a>.</p>
<p>First, let&#x2019;s define the model object that we&#x2019;re going to store in MongoDB.</p>
<pre><code class="language-language-csharp">public class MongoTempData
{
    public string SessionIdentifier { get; set; }

    public string Key { get; set; }

    public object Value { get; set; }
}
</code></pre>
<p>Now we can define our TempData provider to store that model. To avoid sending a user someone else&#x2019;s TempData, we&#x2019;ll need a way of uniquely identifying users. Since this is a crude demo, I&#x2019;ll just use the user&#x2019;s host address. Obviously, don&#x2019;t do this in production code.</p>
<pre><code class="language-language-csharp">public class MongoTempDataProvider : ITempDataProvider
{
    private string _collectionName;
    private string _databaseName;

    public MongoTempDataProvider(string databaseName, string collectionName)
    {
        _collectionName = collectionName;
        _databaseName = databaseName;
    }
}
</code></pre>
<p>Now for the function for loading data from the collection. Since I&#x2019;m not specifying the hostname or port for the database, it assumes a default of localhost and 27017. Different values can be provided via the contructors to the Mongo object.</p>
<pre><code class="language-language-csharp">public IDictionary&lt;string, object&gt; LoadTempData(ControllerContext controllerContext)
{
    var tempDataDictionary = new Dictionary&lt;string, object&gt;();

    using (Mongo mongo = new Mongo())
    {
        mongo.Connect();

        IMongoCollection&lt;MongoTempData&gt; collection =
            mongo
                .GetDatabase(_databaseName)
                .GetCollection&lt;MongoTempData&gt;(_collectionName);

        IEnumerable&lt;MongoTempData&gt; tempData = collection.Find(item =&gt;
            item.SessionIdentifier ==
                controllerContext.HttpContext.Request.UserHostAddress
        ).Documents;

        foreach (var tempDataItem in tempData)
        {
            tempDataDictionary.Add(tempDataItem.Key, tempDataItem.Value);

            collection.Remove(tempDataItem);
        }
    }

    return tempDataDictionary;
}
</code></pre>
<p>That will connect to the database and read in any TempData that is queued up for the current user. Once an item is read into the dictionary it gets removed from the collection, to make sure no other requests can get it.</p>
<p>Now, the save method:</p>
<pre><code class="language-language-csharp">public void SaveTempData(ControllerContext controllerContext,
                                    IDictionary&lt;string, object&gt; values)
{
    using (Mongo mongo = new Mongo())
    {
        mongo.Connect();

        IMongoCollection&lt;MongoTempData&gt; collection =
            mongo
                .GetDatabase(_databaseName)
                .GetCollection&lt;MongoTempData&gt;(_collectionName);

        IEnumerable&lt;MongoTempData&gt; oldItems =
            collection.Find(item =&gt;
                item.SessionIdentifier ==
                    controllerContext.HttpContext.Request.UserHostAddress
            ).Documents;

        foreach (var tempDataItem in oldItems)
        {
            collection.Remove(tempDataItem);
        }

        if (values != null &amp;&amp; values.Count &gt; 0)
        {
            collection.Insert(
                values.Select(tempDataValue =&gt;
                    new MongoTempData
                    {
                        SessionIdentifier =
                            controllerContext.HttpContext.Request.UserHostAddress,
                        Key = tempDataValue.Key,
                        Value = tempDataValue.Value
                    }
                )
            );
        }
    }
}
</code></pre>
<p>That will clear out any old data in the dictionary and replace it with the new values. That&#x2019;s all the code required for the provider, so now we just need to plug it into the controller. We&#x2019;ll create a base controller class that our controllers will inherit from, to avoid having to specify the TempDataProvider in every controller.</p>
<pre><code class="language-language-csharp">public abstract class MongoControllerBase : Controller
{
    public MongoControllerBase()
    {
        TempDataProvider = new MongoTempDataProvider(&quot;test&quot;, &quot;MongoTempData&quot;);
    }
}
</code></pre>
<p>Next we&#x2019;ll define a test controller with two actions. The first action will insert some data into TempData, and the second will print out the contents of TempData. Remember that the controller needs to inherit from our base controller in order to use our custom provider. If you don&#x2019;t, it will default to using the session provider.</p>
<pre><code class="language-language-csharp">public class HomeController : MongoControllerBase
{
    public ActionResult Index()
    {
        TempData[&quot;CurrentDateTime&quot;] = DateTime.Now;
        TempData[&quot;MeaningOfLife&quot;] = 42;

        return Content(&quot;TempData Updated&quot;);
    }

    public ActionResult ReadTempData()
    {
        return View();
    }
}
</code></pre>
<p>Here&#x2019;s our view for ReadTempData:</p>
<pre><code class="language-language-aspnet">Contents of TempData:

&lt;br /&gt;
&lt;br /&gt;

&lt;% foreach (var tempDataItem in TempData)
   { %&gt;

    Key: &lt;%: tempDataItem.Key %&gt;; Value: &lt;%: tempDataItem.Value %&gt;
    &lt;br /&gt;

&lt;% } %&gt;
</code></pre>
<p>If you fire up the application, you should see text that says &#x201C;TempData Updated&#x201D;. Now if you hit /Home/ReadTempData, you should see something that looks like:</p>
<pre><code>Contents of TempData:

Key: CurrentDateTime; Value: 7/14/2010 10:52:45 PM
Key: MeaningOfLife; Value: 42
</code></pre>
<p>If you refresh the page, you will see that the contents of TempData are now empty.</p>
<p>For me, this was one big reminder that you should know exactly how something works before making assumptions about it. Since ASP.NET MVC is open source, it was very easy to load up the solution and poke around under the hood and see precisely how it behaves.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Dynamic Views in ASP.NET MVC 2]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>One of the new features introduced in C# 4.0 is the dynamic keyword. So far I haven&#x2019;t had much use for it, but lately I&#x2019;ve discovered that it can be very useful when designing ASP.NET MVC views. It also has <a href="http://msdn.microsoft.com/en-us/library/dd264736.aspx">uses when interacting with</a></p>]]></description><link>https://gregshackles.com/dynamic-views-in-asp-net-mvc-2/</link><guid isPermaLink="false">61ce48a0437e8200017d40fb</guid><category><![CDATA[ASP.NET]]></category><category><![CDATA[MVC]]></category><dc:creator><![CDATA[Greg Shackles]]></dc:creator><pubDate>Sun, 04 Jul 2010 13:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>One of the new features introduced in C# 4.0 is the dynamic keyword. So far I haven&#x2019;t had much use for it, but lately I&#x2019;ve discovered that it can be very useful when designing ASP.NET MVC views. It also has <a href="http://msdn.microsoft.com/en-us/library/dd264736.aspx">uses when interacting with COM APIs and other dynamic languages</a>, but I&#x2019;m going to focus on its use in MVC.</p>
<p>If you&#x2019;re using .NET 4.0 and ASP.NET MVC 2, and go to add a new view that is not strongly typed, you might notice that the first line will look like this:</p>
<pre><code class="language-language-aspnet">&lt;%@ Page Language=&quot;C#&quot; Inherits=&quot;System.Web.Mvc.ViewPage&lt;dynamic&gt;&quot; %&gt;
</code></pre>
<p>The thing to pay attention to here is that by default, non-strongly typed views now use a dynamic model by default. As with any use of dynamic you lose the compiler&#x2019;s type checking in your view (if you&#x2019;re not compiling your views I would recommend doing so), and your intellisense of course. That said, you do gain quite a bit of freedom when you only have to worry about the properties of the model, rather than the specific type.</p>
<p>Let&#x2019;s use a very simple example to demonstrate a cool use of dynamic view models with a partial view. We will define a partial view that displays today&#x2019;s date, and can take in a set of options about what aspects of the date to display. The options class is defined as:</p>
<pre><code class="language-language-csharp">public class DateDisplayOptions
{
    public bool ShowYear { get; set; }

    public bool ShowTime { get; set; }
}
</code></pre>
<p>Then we have the partial defined like this, using the options class as its view model:</p>
<pre><code class="language-language-aspnet">&lt;%@ Control Language=&quot;C#&quot; Inherits=&quot;System.Web.Mvc.ViewUserControl&lt;DynamicViewSample.Models.DateDisplayOptions&gt;&quot; %&gt;

&lt;%: DateTime.Now.ToString(&quot;MMMM d&quot;) %&gt;

&lt;% if (Model.ShowYear)
   { %&gt;
    &lt;%: DateTime.Now.ToString(&quot;, yyyy&quot;)%&gt;

&lt;% } %&gt;

&lt;% if (Model.ShowTime)
   { %&gt;

    &lt;%: DateTime.Now.ToShortTimeString() %&gt;

&lt;% } %&gt;
</code></pre>
<p>That will use the options to format today&#x2019;s date and time appropriately. Now let&#x2019;s say that we wanted to make it so that if you don&#x2019;t pass an options object to the partial, it uses some default values. First, we add a constructor to DateDisplayOptions to set default values:</p>
<pre><code class="language-language-csharp">public DateDisplayOptions()
{
    ShowYear = true;
    ShowTime = false;
}
</code></pre>
<p>Next, we have to tell the view to allow for receiving a null view model:</p>
<pre><code class="language-language-aspnet">&lt;%@ Control Language=&quot;C#&quot; Inherits=&quot;System.Web.Mvc.ViewUserControl&lt;DynamicViewSample.Models.DateDisplayOptions&gt;&quot; %&gt;
&lt;%@ Import Namespace=&quot;DynamicViewSample.Models&quot; %&gt;

&lt;%
    DateDisplayOptions options = Model ?? new DateDisplayOptions();
%&gt;

&lt;%: DateTime.Now.ToString(&quot;MMMM d&quot;) %&gt;

&lt;% if (options.ShowYear)
   { %&gt;

    &lt;%: DateTime.Now.ToString(&quot;, yyyy&quot;)%&gt;

&lt;% } %&gt;

&lt;% if (options.ShowTime)
   { %&gt;

    &lt;%: DateTime.Now.ToShortTimeString() %&gt;

&lt;% } %&gt;
</code></pre>
<p>Now passing in a null view model will display the year but not the time. However, this only gets us part of the way there. When using the <a href="http://msdn.microsoft.com/en-us/library/dd492503.aspx">RenderPartial</a> method, not explicitly supplying a model to the partial will automatically send the model of the calling page. Obviously that will cause type casting problems when the calling page has a view model that is not DateDisplayOptions, so this is where the dynamic keyword comes to the rescue. We can change the partial to use the dynamic type, and then check for the type ourselves when casting:</p>
<pre><code class="language-language-aspnet">&lt;%@ Control Language=&quot;C#&quot; Inherits=&quot;System.Web.Mvc.ViewUserControl&lt;dynamic&gt;&quot; %&gt;
&lt;%@ Import Namespace=&quot;DynamicViewSample.Models&quot; %&gt;

&lt;%
    DateDisplayOptions options = (Model as DateDisplayOptions) ?? new DateDisplayOptions();
%&gt;
</code></pre>
<p>With that change, the partial will not care what type of model gets sent to it, but if it is not a DateDisplayOptions it will use a new instance with the default options instead.  Let&#x2019;s throw together a quick view to test everything out:</p>
<pre><code class="language-language-aspnet">&lt;p&gt;
    &lt;% Html.RenderPartial(&quot;ShowToday&quot;); %&gt;
&lt;/p&gt;
&lt;p&gt;
    &lt;% Html.RenderPartial(&quot;ShowToday&quot;, new DateDisplayOptions { ShowTime = false, ShowYear = false }); %&gt;
&lt;/p&gt;
&lt;p&gt;
    &lt;% Html.RenderPartial(&quot;ShowToday&quot;, new DateDisplayOptions { ShowTime = true, ShowYear = true }); %&gt;
&lt;/p&gt;
</code></pre>
<p>That gives us the following output, which behaves exactly like we wanted:</p>
<p><img src="https://gregshackles.com/content/images/2014/12/dynamic-view-results.jpg" alt="dynamic view results" loading="lazy"></p>
<p>There are certainly a lot more uses out there for the dynamic keyword, but this is one example I stumbled upon where it came in very useful.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Templated Helpers and Custom Model Binders in ASP.NET MVC 2]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>One of the really cool new features in ASP .NET MVC 2 is templated helpers. The basic idea is that you can define a template for either displaying or editing a particular data type, and it will be used by default when displaying or editing that type. This allows you</p>]]></description><link>https://gregshackles.com/templated-helpers-and-custom-model-binders-in-asp-net-mvc-2/</link><guid isPermaLink="false">61ce48a0437e8200017d40f8</guid><category><![CDATA[ASP.NET]]></category><category><![CDATA[MVC]]></category><dc:creator><![CDATA[Greg Shackles]]></dc:creator><pubDate>Wed, 24 Mar 2010 13:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>One of the really cool new features in ASP .NET MVC 2 is templated helpers. The basic idea is that you can define a template for either displaying or editing a particular data type, and it will be used by default when displaying or editing that type. This allows you to define the behavior once, and then you don&#x2019;t need to worry about it in every view you write thereafter. In this post I&#x2019;ll go over how to use templated helpers to handle both a built-in type, DateTime, as well as a custom type which will demonstrate using a custom model binder.</p>
<p>If you haven&#x2019;t already done so, I suggest reading through <a href="http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html">Brad Wilson&#x2019;s series on templated helpers</a> to give you a good idea of the basics, which I will briefly touch on but not in much detail.</p>
<h2 id="datetime">DateTime</h2>
<p>First we&#x2019;ll take a look at the simple case. Let&#x2019;s say you have a view model that contains a DateTime property:</p>
<pre><code class="language-language-csharp">public class DateTestViewModel
{
    [DisplayName(&quot;Birth date&quot;)]
    public DateTime DateOfBirth { get; set; }
}
</code></pre>
<p>When we display a form for that view model, by default MVC will give you a text box for editing the date. Obviously this isn&#x2019;t a very user-friendly way to edit a date, so let&#x2019;s use progressive enhancement to spruce it up with a jQuery UI date picker. Since we&#x2019;ll want to do this globally across the site, this is a perfect scenario to use a templated helper. For the sake of this demo I&#x2019;ll keep everything contained in a single view, just to keep things simple. Here is the view code for displaying the editor for the date:</p>
<pre><code class="language-language-aspnet">&lt;% using (Html.BeginForm())
   { %&gt;
    &lt;p&gt;
        &lt;%= Html.LabelFor(model =&gt; model.DateOfBirth) %&gt;:
        &lt;br /&gt;
        &lt;%= Html.EditorFor(model =&gt; model.DateOfBirth) %&gt;
    &lt;/p&gt;
    &lt;p&gt;
        &lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;
    &lt;/p&gt;
&lt;% } %&gt;
</code></pre>
<p>To start, we create a folder under Views/Shared called EditorTemplates. Creating it under Shared allows any view to make use of the templates inside of it. If you want to limit it to a single set of views, you can put the folder inside that view folder. In that folder, let&#x2019;s create a new view user control that looks like this, named DateTime.ascx:</p>
<pre><code class="language-language-aspnet">&lt;%@ Control Language=&quot;C#&quot; Inherits=&quot;System.Web.Mvc.ViewUserControl&lt;System.DateTime?&gt;&quot; %&gt;

&lt;%= Html.TextBox(&quot;&quot;, (Model.HasValue ? Model.Value.ToString(&quot;MMMM d, yyyy&quot;) : string.Empty), new { @class = &quot;date&quot; }) %&gt;
</code></pre>
<p>All we&#x2019;re doing is creating a textbox for the model, which is a nullable DateTime, and assigns it the class of &#x201C;date.&#x201D; Now with jQuery we can quickly attach a date picker to any text input with that class:</p>
<pre><code class="language-language-javascript">$(document).ready(function()
{
    $(&quot;input:text.date&quot;).datepicker(
    {
        dateFormat: &quot;MM d, yy&quot;
    });
});
</code></pre>
<p>And that&#x2019;s it! Now any time you create an editor for a DateTime property, you&#x2019;ll get a slick date picker.</p>
<p><img src="https://gregshackles.com/content/images/2014/12/templated1.png" alt="Date picker" loading="lazy"></p>
<h2 id="simpledate">SimpleDate</h2>
<p>Now let&#x2019;s say you want to do this with some custom types you have. Can you still use templated helpers to define your views and editors? Of course you can! The only difference is that now you also need to tell MVC how to bind the form input to an object. Continuing with the date theme, let&#x2019;s implement a simpler version of the date, where you simply want to select a month and a year, leaving out the day of the month. Here&#x2019;s the class definition for SimpleDate:</p>
<pre><code class="language-language-csharp">public class SimpleDate
{
    [Range(1, 12)]
    public int Month { get; set; }

    [Range(1, 9999)]
    public int Year { get; set; }

    public SimpleDate()
    {
    }

    public SimpleDate(DateTime date)
        : this(date.Year, date.Month)
    {
    }

    public SimpleDate(int year, int month)
    {
        Year = year;
        Month = month;
    }

    public DateTime ToDate()
    {
        return new DateTime(Year, Month, 1);
    }
}
</code></pre>
<p>We&apos;ll also add it to our view model:</p>
<pre><code class="language-language-csharp">[DisplayName(&quot;Billing month&quot;)]
public SimpleDate BillingMonth { get; set; }
</code></pre>
<p>As well as add it to the view:</p>
<pre><code class="language-language-aspnet">&lt;p&gt;
    &lt;%= Html.LabelFor(model =&gt; model.BillingMonth) %&gt;:
    &lt;br /&gt;
    &lt;%= Html.EditorFor(model =&gt; model.BillingMonth) %&gt;
&lt;/p&gt;
</code></pre>
<p>While we&#x2019;re at it, let&#x2019;s define a simple template for it, in the same folder as the last one, called SimpleDate.ascx:</p>
<pre><code class="language-language-aspnet">&lt;%@ Control Language=&quot;C#&quot; Inherits=&quot;System.Web.Mvc.ViewUserControl&lt;TemplatedHelpers.Models.SimpleDate&gt;&quot; %&gt;
&lt;%@ Import Namespace=&quot;TemplatedHelpers.Extensions&quot; %&gt;

&lt;%= Html.MonthDropDownListFor(model =&gt; model.Month, Model.Month) %&gt;

&lt;%= Html.YearDropDownListFor(model =&gt; model.Year, Model.Year) %&gt;
</code></pre>
<p>Astute readers will have noticed that I used a couple custom extension methods in there for creating the drop down lists. I wrote them up as a quick example for this demo, so while they are not perfect, they get the idea across since that isn&#x2019;t the focus of this post. Here is the code I have for those functions:</p>
<pre><code class="language-language-csharp">public static class HtmlHelperExtensions
{
    private static string[] _months =
    {
        &quot;January&quot;, &quot;February&quot;, &quot;March&quot;, &quot;April&quot;, &quot;May&quot;,
        &quot;June&quot;, &quot;July&quot;, &quot;August&quot;, &quot;September&quot;, &quot;October&quot;,
        &quot;November&quot;, &quot;December&quot;
    };

    private static IEnumerable&lt;SelectListItem&gt; getMonthListItems(int? selectedMonth)
    {
        var monthList = new List&lt;SelectListItem&gt;();

        for (int i = 0; i &lt; _months.Length; i++)
        {
            monthList.Add(new SelectListItem
            {
                Text = _months[i],
                Value = (i + 1).ToString(),
                Selected = (selectedMonth == (i + 1))
            });
        }

        return monthList;
    }

    private static IEnumerable&lt;SelectListItem&gt; getYearListItems(int? selectedYear)
    {
        var yearList = new List&lt;SelectListItem&gt;();

        for (int i = 2006; i &lt;= DateTime.Now.Year; i++)
        {
            yearList.Add(new SelectListItem
            {
                Text = i.ToString(),
                Value = i.ToString(),
                Selected = (selectedYear == i)
            });
        }

        return yearList;
    }

    public static MvcHtmlString MonthDropDownListFor&lt;TModel, TProperty&gt;(this HtmlHelper&lt;TModel&gt; htmlHelper, Expression&lt;Func&lt;TModel, TProperty&gt;&gt; expression, int? selectedMonth)
    {
        return htmlHelper.DropDownListFor(expression, getMonthListItems(selectedMonth));
    }

    public static MvcHtmlString YearDropDownListFor&lt;TModel, TProperty&gt;(this HtmlHelper&lt;TModel&gt; htmlHelper, Expression&lt;Func&lt;TModel, TProperty&gt;&gt; expression, int? selectedYear)
    {
        return htmlHelper.DropDownListFor(expression, getYearListItems(selectedYear));
    }
}
</code></pre>
<p>So now we have a custom type and the template for editing it, but if you try to post the form you&#x2019;ll see that you lose any value you have set on it. Why is this? By default, MVC doesn&#x2019;t know how to bind the form data. To fix that, we can create our own model binder class, which extends the System.Web.Mvc.DefaultModelBinder class:</p>
<pre><code class="language-language-csharp">public class SimpleDateModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        int month = getValue&lt;int&gt;(bindingContext, &quot;Month&quot;).Value;
        int year = getValue&lt;int&gt;(bindingContext, &quot;Year&quot;).Value;

        return new SimpleDate(year, month);
    }

    private Nullable&lt;T&gt; getValue&lt;T&gt;(ModelBindingContext bindingContext, string key) where T : struct
    {
        if (string.IsNullOrEmpty(key))
        {
            return null;
        }

        ValueProviderResult result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + &quot;.&quot; + key);

        if (result == null &amp;&amp; bindingContext.FallbackToEmptyPrefix)
        {
            result = bindingContext.ValueProvider.GetValue(key);
        }

        if (result == null)
        {
            return null;
        }

        return (Nullable&lt;T&gt;)result.ConvertTo(typeof(T));
    }
}
</code></pre>
<p>There are a lot of extension points you can tie into with model binders, but here we&#x2019;ll just keep things as simple as possible. Luckily, that&#x2019;s all we really need. The getValue() function is inspired by a <a href="http://www.hanselman.com/blog/SplittingDateTimeUnitTestingASPNETMVCCustomModelBinders.aspx">similar post by Scott Hanselman</a>, and looks through the binding context for the provided key and type, and returns the value if it finds it. Since the keys here are coming from form data, they will be in the form of PropertyName.Month and PropertyName.Year. The BindModel() function grabs these values for the current model being bound, and returns a new SimpleDate based on it.</p>
<p>One last thing to do here, and that is to tell MVC to use that model binder when it encounters SimpleDate.  Open up global.asax, and add this into the Application_Start handler:</p>
<pre><code class="language-language-csharp">ModelBinders.Binders.Add(typeof(SimpleDate), new SimpleDateModelBinder());
</code></pre>
<p>Need some proof that it works? Of course you do. Let&#x2019;s add a little bit of code to the view and controller to stuff the values into ViewData when it POSTs, and then display them in the view. Here is our controller action:</p>
<pre><code class="language-language-csharp">[HttpPost]
public ActionResult Index(DateTestViewModel viewModel)
{
    ViewData[&quot;DateOfBirth&quot;] = viewModel.DateOfBirth;
    ViewData[&quot;BillingMonth&quot;] = viewModel.BillingMonth;

    return View(viewModel);
}
</code></pre>
<p>Then in the view we will display it, when it&#x2019;s there:</p>
<pre><code class="language-language-aspnet">&lt;p&gt;
    &lt;% if (ViewData[&quot;DateOfBirth&quot;] != null)
       { %&gt;

        DOB: &lt;%= ViewData[&quot;DateOfBirth&quot;] %&gt;
        &lt;br /&gt;

    &lt;% } %&gt;

    &lt;% if (ViewData[&quot;BillingMonth&quot;] != null)
       { %&gt;

        Billing Month: &lt;%= ((TemplatedHelpers.Models.SimpleDate)ViewData[&quot;BillingMonth&quot;]).ToDate() %&gt;
        &lt;br /&gt;

    &lt;% } %&gt;
&lt;/p&gt;
</code></pre>
<p>Now when you submit the form, you should see the date values for both date fields on the page displayed at the bottom.</p>
<p><img src="https://gregshackles.com/content/images/2014/12/templated2.png" alt="Date fields displayed" loading="lazy"></p>
<p>Now we have a slick date picker for when we need to choose a specific date, and a nice option for picking a month and year, all thanks to MVC templated helpers.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Validating Hidden Fields in ASP.NET MVC 2]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>One of the many nice things they have added in MVC 2 is model/view model validation on both the client and server side.  I won&#x2019;t go into the basics here since they have been covered extensively by others.  However, recently I was adding validation to require a</p>]]></description><link>https://gregshackles.com/validating-hidden-fields-in-asp-net-mvc-2/</link><guid isPermaLink="false">61ce48a0437e8200017d40f6</guid><category><![CDATA[ASP.NET]]></category><category><![CDATA[MVC]]></category><category><![CDATA[Validation]]></category><dc:creator><![CDATA[Greg Shackles]]></dc:creator><pubDate>Sun, 21 Feb 2010 14:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>One of the many nice things they have added in MVC 2 is model/view model validation on both the client and server side.  I won&#x2019;t go into the basics here since they have been covered extensively by others.  However, recently I was adding validation to require a value for a hidden field on a form, and found that the default validation functionality just didn&#x2019;t work on the client side for a hidden field.  Here I will go over how I added some custom validation to allow me to do it.</p>
<p>While it might sound weird to validate a hidden field, something a user will never directly interact with, in this age of complex interfaces built in JavaScript it&#x2019;s easy to imagine a scenario where a series of interactions leads to storing some kind of value in a hidden field.  If that end value is something that is required, it&#x2019;s only natural that that should be enforced by the model.</p>
<p>First, let&#x2019;s start by defining a very simple view model for the form:</p>
<pre><code class="language-language-csharp">public class DemoForm
{
    [Required(ErrorMessage = &quot;You must enter a name&quot;)]
    public string Name { get; set; }
}
</code></pre>
<p>It just defines a single property for storing a name.  Now we can define a very basic view that is strictly typed to that view model.  Here is the code for setting up the form:</p>
<pre><code class="language-language-aspnet">&lt;% using (Html.BeginForm())
{ %&gt;

    &lt;%= Html.HiddenFor(model =&gt; model.Name) %&gt;

    &lt;p&gt;
        &lt;%= Html.ValidationMessageFor(model =&gt; model.Name) %&gt;
    &lt;/p&gt;

    &lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;

&lt;% } %&gt;
</code></pre>
<p><img src="https://gregshackles.com/content/images/2014/12/validation1.png" alt="Page output" loading="lazy"></p>
<p>If you run the page now, you will get correct server-side validation, but nothing on the client.  To get client validation in MVC, we need to tell the page to enable client validation.  To do that, call this before starting the form:</p>
<pre><code class="language-language-aspnet">&lt;% Html.EnableClientValidation(); %&gt;
</code></pre>
<p>You will also need some JavaScript references to these files, which are included by default in any new MVC project:</p>
<pre><code class="language-language-aspnet">&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;%= ResolveUrl(&quot;~/Scripts/MicrosoftAjax.js&quot;) %&gt;&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;%= ResolveUrl(&quot;~/Scripts/MicrosoftMvcAjax.js&quot;) %&gt;&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;%= ResolveUrl(&quot;~/Scripts/MicrosoftMvcValidation.js&quot;) %&gt;&quot;&gt;&lt;/script&gt;
</code></pre>
<p>Now if you reload the page, client validation still isn&#x2019;t working.  Why not?  After digging through the Microsoft validation scripts a bit, I found that the Required validator ignores hidden fields altogether in JavaScript.  We could change it from being a hidden field to a text field and the same code would work as expected, but that&#x2019;s not what we want to do.</p>
<p>As it turns out, they made it rather simple to extend the built-in validation with your own custom rules.  First, we&#x2019;ll define the attribute class, so that it can be added as a decorator to a property the same way the other validators work.  In this case, since the Required attribute actually works fine on the server side, our class will extend that and do nothing else.  This way we can provide the client side functionality and rely on the existing server validation.</p>
<pre><code class="language-language-csharp">public class HiddenRequiredAttribute : RequiredAttribute
{
}
</code></pre>
<p>Now that we have the attribute, we need a validator that uses it.  To do that, we extend the DataAnnotationsModelValidator class, and tell it to use the attribute we just defined:</p>
<pre><code class="language-language-csharp">public class HiddenRequiredValidator : DataAnnotationsModelValidator&lt;HiddenRequiredAttribute&gt;
{
    private string _errorMessage;

    public HiddenRequiredValidator(ModelMetadata metaData, ControllerContext context, HiddenRequiredAttribute attribute)
        : base(metaData, context, attribute)
    {
        _errorMessage = attribute.ErrorMessage;
    }

    public override IEnumerable&lt;ModelClientValidationRule&gt; GetClientValidationRules()
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = _errorMessage,
            ValidationType = &quot;hiddenRequired&quot;
        };

        return new[] { rule };
    }
}
</code></pre>
<p>The important part to notice here is where we set the ValidationType to &#x201C;hiddenRequired.&#x201D;  This is the unique identifier we define for referencing our validator in JavaScript.  Remember it, because you&#x2019;re going to need it later.</p>
<p>So now we have an attribute, and a validator for it.  Next up, we need to register our validator in the application&#x2019;s Application_Start function:</p>
<pre><code class="language-language-csharp">DataAnnotationsModelValidatorProvider
    .RegisterAdapter(typeof(HiddenRequiredAttribute), typeof(HiddenRequiredValidator));
</code></pre>
<p>Now let&#x2019;s switch the view model&#x2019;s Name property to use the new HiddenRequired attribute instead of the Required one we had before:</p>
<pre><code class="language-language-csharp">public class DemoForm
{
    [HiddenRequired(ErrorMessage = &quot;You must enter a name&quot;)]
    public string Name { get; set; }
}
</code></pre>
<p>All that remains is to put in some JavaScript code to handle the validation.  I&#x2019;ll show the code here, and then discuss it.  Since this is a contained demo, I will add the code directly to the view.</p>
<pre><code class="language-language-javascript">Sys.Mvc.ValidatorRegistry.validators[&quot;hiddenRequired&quot;] = function(rule)
{
    return function(value, context)
    {
        if (value)
        {
            return true;
        }

        return rule.ErrorMessage;
    }
};
</code></pre>
<p>If that code looks simple, that&#x2019;s because it is.  Since we&#x2019;re only validating that the field has some kind of value, that is all we need to check for.  The reason that the return function is wrapped in another function is to allow for adding more complex logic before the return function if needed.  For this example, it isn&#x2019;t needed.</p>
<p><img src="https://gregshackles.com/content/images/2014/12/validation2.png" alt="Updated page output" loading="lazy"></p>
<p>Now if you reload the page you will get the client-side validation we were aiming for, triggered by the submit button.  Always remember that client-side validation is just there for improving the user experience, and is no substitute for server validation.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>