My Sencha Touch app is posting a form to my asp.net-mvc-3 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);
}
Just to answer the question why "OPTIONS" and not "POST", that is because the browser is implementing CORS (Cross-origin resource sharing ). This is a two part process of sending the OPTIONS request first, then if the server replies with acceptable conditions the browser then POSTS the actual request with data / content in.
Turns out I had to create an
ActionFilterAttribute
I added the following to my
<system.webServer>
config section:I solved this in a different way in MVC, and IIS. The reason I found this problem was because I wanted to POST data from client side javascript (which JSONP does not work for), and on top of that wanted to allow JSON data which sits inside the Content of the POST request.
In reality your code wants to ignore the first CORS OPTIONS request, as this is likely to be a "site wide setting", and not on a per API call setting.
First I configured IIS to send the CORS response, this can be done through IIS manager (or through web.config updates), if you use IIS then go to the site you want to add these two values:
Then I created a custom ActionFilter, which has to be applied for each controller that you want to accept POST data, which could trigger a CORS request. The custom action filter was:
Then at the start of each controller you need to apply this for add in an attribute, e.g.:
Now I am sure there is a way to do this across your whole MVC solution (solutions welcome), but need to make a BBQ and the solution above works!
I tried all the answers here and none worked. I eventually realized that browsers will treat the pre-flight check as failed if it returns non 200. In my case, IIS was returning 404, even with the headers. This is because I had 2 attributes on my controller method - [HttpPost] and [HttpOptions]. Apparently, this is not a valid mechanism for expressing multiple verbs. I had to use this attribute instead: [AcceptVerbs(HttpVerbs.Options | HttpVerbs.Post)]