Search code examples
ajaxasp.net-mvc-3http-options-method

how to handle "OPTIONS Method" in ASP.NET MVC


My Sencha Touch app is posting a form to my WebService, but instead of sending POST it's sending OPTIONS.

I'm reading a similar thread here, but I just don't know how to handle the OPTIONS method in my code.

I did try adding the [AllowAjax] attribute to my Action, however it doesn't seem to exist in MVC3.

OPTIONS /GetInTouch/CommunicateCard HTTP/1.1
Host: webservice.example.com
Referer: http://192.168.5.206/ Access-Control-Request-Method: POST
Origin: http://192.168.5.206
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.71 Safari/534.24
Access-Control-Request-Headers: X-Requested-With, Content-Type
Accept: /
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

In my ActionMethod, I'm using the following code.

    public JsonpResult CommunicateCard(CommunicateCard communicateCard)
    {

        // Instantiate a new instance of MailMessage
        MailMessage mMailMessage = new MailMessage();

        // removed for security/brevity

        // Set the body of the mail message
        mMailMessage.Body = communicateCard.name; // THIS IS CURRENTLY BLANK :-(

        // removed for security/brevity
        mSmtpClient.Send(mMailMessage);

        // do server side validation on form input
        // if it's valid return true
        // else return false
        // currently returning NULL cuz I don't care at this point.
        return this.Jsonp(null);
    }

Solution

  • Turns out I had to create an ActionFilterAttribute

    namespace WebService.Attributes
    {
        public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
        {
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
                HttpContext.Current.Response.Cache.SetNoStore();
    
                filterContext.RequestContext.HttpContext.Response.AppendHeader("Access-Control-Allow-Origin", "*");
    
                string rqstMethod = HttpContext.Current.Request.Headers["Access-Control-Request-Method"];
                if (rqstMethod == "OPTIONS" || rqstMethod == "POST")
                {
                    filterContext.RequestContext.HttpContext.Response.AppendHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                    filterContext.RequestContext.HttpContext.Response.AppendHeader("Access-Control-Allow-Headers", "X-Requested-With, Accept, Access-Control-Allow-Origin, Content-Type");
                }
                base.OnActionExecuting(filterContext);
            }
        }
    }