Thursday, April 15, 2010

MVC 2: JsonRequestBehavior DenyGet

We migrated one of our projects to MVC 2 today, and one of the first things I noticed is that all my ajaxified jsony sweetness had stopped working! A quick look at the XHR revealed the following server error.
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
What the heck?

A quick Google turned up a couple articles about MVC 2's new JsonRequestBehavior, and specifically the MSDN article (the link to Haack is dead, so here's a good one). Ok, good to know. I wasn't aware of that vulnerability, but in the mean time I need this project working.

I could modify the actions to call a Json overload which accepts the JsonRequestBehavior.
  return Json(myjson, JsonRequestBehavior.AllowGet);
But since I have somewhere between 50-80 Json actions in this app, that would be a lot of find-replace. Plus, when I finish modifying my client library to use POST requests, I would have to do it all over again. A one stop solution would be much preferable.

If your project already uses a base controller class, you can do one simple override:
protected override JsonResult Json(object data, string contentType,
Encoding contentEncoding, JsonRequestBehavior behavior)
{
// TODO: change all my GET Json request into POST
return base.Json(data, contentType, contentEncoding,
JsonRequestBehavior.AllowGet);
}
Keep in mind this should be a temporary crutch only!

IIS 7 (7.5): Hosting Multiple SSL Sites On One IP

Since I continually find myself Googling this information whenever I add a new site on our wildcard cert, I figured I'd document it here.

Adding a New Binding:

Requirements:
  1. A wild card SSL certificate (of the form *.domain.com). I assume the cert is already installed on your server.
  2. An IP you wish to use on multiple IIS sites.
  3. Two or more IIS sites with no SSL binding (I'll touch on changing a binding at the end).
With these in place, adding an SSL cert is quite simple:
  1. In an elevated command prompt navigate to
    C:\Windows\System32\inetsrv
  2. Enter the following command (replace {SITENAME}, {IP}, and {HOSTHEADER} with the appropriate values).
    appcmd set site /site.name:{SITENAME} /+bindings.[protocol='https',bindingInformation='{IP}:443:{HOSTHEADER}']
  3. Check the selected cert in IIS via the bindings window. You can change the cert here, but you cannot change the host header.
That's it.

Changing an Existing Binding:

Changing a binding is similar to the adding binding with a few alterations to the command
appcmd set site /site.name:{SITENAME} /bindings.[protocol='https',bindingInformation='{IP}:443:{HOSTHEADER}'].bindingInformation:{NEWIP}:443:{NEWHOSTHEADER}