title: Handling CORS Preflight requests to ASP.NET MVC actions
body: <p>I'm trying to perform a cross-domain POST request to an ASP.NET MVC controller action. This controller action accepts &amp; uses various parameters. The problem is that when the preflight request happens, the controller action actually attempts to execute &amp; because the OPTIONS request doesn't pass any data, the controller action throws out a 500 HTTP error. If I remove the code that uses the parameter, or the parameter itself, the entire request chain is completed successfully.</p>
  
  <p>An example of how this is implemented:</p>
  
  <p><strong>Controller Action</strong></p>
  
  <pre><code>public ActionResult GetData(string data)
  {
      return new JsonResult
      {
          Data = data.ToUpper(),
          JsonRequestBehavior = JsonRequestBehavior.AllowGet
      };
  }
  </code></pre>
  
  <p><strong>Client-side code</strong></p>
  
  <pre><code>&lt;script type="text/javascript"&gt;
          $(function () {
              $("#button-request").click(function () {
                  var ajaxConfig = {
                      dataType: "json",
                      url: "http://localhost:8100/host/getdata",
                      contentType: 'application/json',
                      data: JSON.stringify({ data: "A string of data" }),
                      type: "POST",
                      success: function (result) {
                          alert(result);
                      },
                      error: function (jqXHR, textStatus, errorThrown) {
                          alert('Error: Status: ' + textStatus + ', Message: ' + errorThrown);
                      }
                  };
  
                  $.ajax(ajaxConfig);
              });
          });
      &lt;/script&gt;
  </code></pre>
  
  <p>Now, whenever the preflight request happens, it returns a 500 HTTP code, because the "data"  parameter is null, seeing as the OPTIONS request doesn't pass any values.</p>
  
  <p>The server application has been set up in my local IIS on port 8100 &amp; the page running the client-side code is set up on port 8200 to mimic the cross-domain calls.</p>
  
  <p>I have also configured the host (on 8100) with the following headers:</p>
  
  <pre><code>Access-Control-Allow-Headers: Content-Type
  Access-Control-Allow-Methods: POST, GET
  Access-Control-Allow-Origin: http://localhost:8200
  </code></pre>
  
  <p>One workaround I had found, was to check the HTTP method that executes the action &amp; if it's a OPTIONS request to just return blank content, otherwise execute the action code. Like so:</p>
  
  <pre><code>public ActionResult GetData(string data)
  {
      if (Request.HttpMethod == "OPTIONS") {
          return new ContentResult();
      } else {
          return new JsonResult
          {
              Data = data.ToUpper(),
              JsonRequestBehavior = JsonRequestBehavior.AllowGet
          };
      }
  }
  </code></pre>
  
  <p>But this approach feels very clunky to me. I considered adding this sort of logic to an <code>Attribute</code>, but even this would mean decorating every action that will get called using CORS with it.</p>
  
  <p>Is there a more elegant solution to getting this functionality to work?</p>