<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Playing on the frontier &#187; aspnetmvc</title>
	<atom:link href="http://siphon9.net/loune/tag/aspnetmvc/feed/" rel="self" type="application/rss+xml" />
	<link>http://siphon9.net/loune</link>
	<description></description>
	<lastBuildDate>Thu, 15 Jul 2010 12:58:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Verifying Anti-Forgery Token for Form POST only</title>
		<link>http://siphon9.net/loune/2010/02/verifying-anti-forgery-token-for-form-post-only/</link>
		<comments>http://siphon9.net/loune/2010/02/verifying-anti-forgery-token-for-form-post-only/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 01:03:37 +0000</pubDate>
		<dc:creator>Loune</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[aspnetmvc]]></category>
		<category><![CDATA[csrf]]></category>

		<guid isPermaLink="false">http://siphon9.net/loune/?p=151</guid>
		<description><![CDATA[As many of you know, the ASP.NET MVC Anti-Forgery token helps thwart Cross Site Request Forgery attacks. Any site that uses authenticated sessions (99% of web apps) should use similar mechanisms so these attacks cannot occur. Very often, I would write GET and POST actions in the same method. This allows fall through to that [...]]]></description>
			<content:encoded><![CDATA[<p>As many of you know, the ASP.NET MVC Anti-Forgery token helps thwart <a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery">Cross Site Request Forgery</a> attacks. Any site that uses authenticated sessions (99% of web apps) should use similar mechanisms so these attacks cannot occur.</p>
<p>Very often, I would write GET and POST actions in the same method. This allows fall through to that same code we used for GET request if POST validation fails, ensuring consistency.</p>
<pre class="brush: csharp;">
public ActionResult EditPerson(Person person)
{
	if (Request.HttpMethod == &quot;POST&quot; &amp;&amp; ModelState.IsValid)
	{
		// do edit person...

		return RedirectToAction(&quot;Index&quot;);
	}

	// do get person

	return View(person);
}
</pre>
<p>If I use that sort of paradigm, then the [VerifyAntiForgeryToken] attribute would block both GET and POST requests when the token is not supplied. I want the token to be only verified when I POST. Since ASP.NET MVC is extensible, the normal way to go about that would be modify the behaviour of [VerifyAntiForgeryToken] by subclassing. Unfortuantely, VerifyAntiForgeryTokenAttribute is sealed which means it can&#8217;t be inherited from. Luckily, borrowing from the same trick that Http*Base classes use to combat sealed Http* classes, we can just create a new attribute that wraps the old attribute, implementing the same members and proxying the calls back to the wrapped base class. That&#8217;s exactly what I did and it works quite well. The result is [ValidateAntiForgeryTokenOnPost] which will only verify the form anti-forgery token on a POST request:</p>
<pre class="brush: csharp;">
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class ValidateAntiForgeryTokenOnPostAttribute : FilterAttribute, IAuthorizationFilter
{
	private ValidateAntiForgeryTokenAttribute _wrapped;
	public ValidateAntiForgeryTokenOnPostAttribute()
	{
		_wrapped = new ValidateAntiForgeryTokenAttribute();
	}

	public string Salt { get { return _wrapped.Salt; } set { _wrapped.Salt = value; } }

	public void OnAuthorization(AuthorizationContext filterContext)
	{
		if (filterContext.HttpContext.Request.HttpMethod == &quot;POST&quot;)
		{
			_wrapped.OnAuthorization(filterContext);
		}
	}
}
</pre>
<p>This will teach those sealed classes!</p>
]]></content:encoded>
			<wfw:commentRss>http://siphon9.net/loune/2010/02/verifying-anti-forgery-token-for-form-post-only/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An intuitive Dictionary Model Binder for ASP.NET MVC</title>
		<link>http://siphon9.net/loune/2009/12/a-intuitive-dictionary-model-binder-for-asp-net-mvc/</link>
		<comments>http://siphon9.net/loune/2009/12/a-intuitive-dictionary-model-binder-for-asp-net-mvc/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 23:28:24 +0000</pubDate>
		<dc:creator>Loune</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[aspnetmvc]]></category>
		<category><![CDATA[dotnet]]></category>

		<guid isPermaLink="false">http://siphon9.net/loune/?p=122</guid>
		<description><![CDATA[The other day I was working on an ASP.NET MVC website and came across a need to post an array from the browser into the web app. The framework comes with something called a Model Binder that automagically converts submitted form data into action parameters of the controller. For example, if we have form submitted [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I was working on an <a href="http://www.asp.net/mvc/">ASP.NET MVC</a> website and came across a need to post an array from the browser into the web app. The framework comes with something called a Model Binder that automagically converts submitted form data into action parameters of the controller. For example, if we have form submitted data such as<br />
<code>person.FirstName=John&#038;person.LastName=smith</code><br />
for a theoretical model class &#8216;Person&#8217;, and</p>
<pre class="brush: csharp;">public ActionResult SavePerson(Person person)</pre>
<p>as the action method signature, SavePerson will be executed with the parameter equivalent to</p>
<pre class="brush: csharp;">new Person() { FirstName = &quot;John&quot;, LastName = &quot;Smith&quot; }</pre>
<p>The default model binder is pretty powerful, using reflection to dig out and assign all the fields. It also <a href="http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx">supports arrays and dictionaries</a>, but with big limitations. The array must start at 0 and be unbroken. That is understandable for arrays, but what if you had a dictionary? Surely it can start at any position? Not so. The dictionary has even more obscure requirements, with the need to specify explicit .Key and .Value parameters in your form submission. For example:<br />
<code>dict[0].Key=mykey&#038;dict[0].Value=myvalue</code><br />
This represented extra work to generate the form on the client side. I just want to input something more intuitive like:<br />
<code>dict[mykey]=myvalue</code><br />
The ASP.NET MVC framework is highly extensible. It allows you to define your own custom model binder so that&#8217;s exactly what I did. Inheriting off DefaultModelBinder, I created DefaultDictionaryBinder that overrode the BindModel method and intercepts when a IDictionary<,> class is being bound.</p>
<pre class="brush: csharp;">
public class DefaultDictionaryBinder : DefaultModelBinder
{
	public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
	{
		Type modelType = bindingContext.ModelType;
		Type idictType = modelType.GetInterface(&quot;System.Collections.Generic.IDictionary`2&quot;);
		if (idictType != null)
		{
			object result = null;

			Type[] ga = idictType.GetGenericArguments();
			IModelBinder valueBinder = Binders.GetBinder(ga[1]);

			foreach (string key in bindingContext.ValueProvider.Keys)
			{
				if (key.StartsWith(bindingContext.ModelName + &quot;[&quot;, StringComparison.InvariantCultureIgnoreCase))
				{
					int endbracket = key.IndexOf(&quot;]&quot;, bindingContext.ModelName.Length + 1);
					if (endbracket == -1)
						continue;

					object dictKey;
					try
					{
						dictKey = Convert.ChangeType(key.Substring(bindingContext.ModelName.Length + 1, endbracket - bindingContext.ModelName.Length - 1), ga[0]);
					}
					catch (FormatException)
					{
						continue;
					}

					ModelBindingContext innerBindingContext = new ModelBindingContext()
					{
						Model = null,
						ModelName = key.Substring(0, endbracket + 1),
						ModelState = bindingContext.ModelState,
						ModelType = ga[1],
						ValueProvider = bindingContext.ValueProvider
					};
					object newPropertyValue = valueBinder.BindModel(controllerContext, innerBindingContext);

					if (result == null)
						result = CreateModel(controllerContext, bindingContext, modelType);

					if (!(bool)idictType.GetMethod(&quot;ContainsKey&quot;).Invoke(result, new object[] { dictKey }))
						idictType.GetProperty(&quot;Item&quot;).SetValue(result, newPropertyValue, new object[] { dictKey });
				}
			}

			return result;
		}
		return base.BindModel(controllerContext, bindingContext);
	}
}
</pre>
<p>To use, you have to override the default model binder. In global.asax.cs in Application_Start(), add the line:</p>
<pre class="brush: csharp;">
ModelBinders.Binders.DefaultBinder = new DefaultDictionaryBinder();
</pre>
<p>The code is very flexible, only requiring the dictionary key to be of a basic type convertible from string, ie. Dictionary<int,...> or Dictionary<string,...>. The value can be any object that is able to be bound by the default model binder.<br />
An example follows:<br />
If your form input is<br />
<code>persons[3].FirstName=John&#038;persons[3].LastName=Smith&#038;persons[4].FirstName=Jane&#038;persons[4].LastName=Doe&#038;</code><br />
and our action signature</p>
<pre class="brush: csharp;">public ActionResult SavePersons(Dictionary&lt;int, Person&gt; persons)</pre>
<p>the persons parameter would be</p>
<pre class="brush: csharp;">
new Dictionary&lt;int, Person&gt;() {
{ 3, new Person() {&quot;John&quot;, &quot;Smith&quot;} },
{ 4, new Person() {&quot;Jane&quot;, &quot;Doe&quot;} },
}
</pre>
<p>Simple and intuitve.</p>
]]></content:encoded>
			<wfw:commentRss>http://siphon9.net/loune/2009/12/a-intuitive-dictionary-model-binder-for-asp-net-mvc/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
