This is probably something simple, but I just can’t see it.
I’ve got my sencha-touch application posting data to my WebService (asp.net-mvc-3). The Sencha Touch js code looks like this.
var submitCommunicateCard = function () {
console.log(rpc.views.Contact.CommunicateCard.getValues());
Ext.Ajax.request({
url: WebService('GetInTouch', 'CommunicateCard'), //http://webservice.example.com/GetInTouch/CommunicateCard
method: 'post',
params: {
callback: 'foo', //temporary until I can better setup the callback.
name: rpc.views.Contact.CommunicateCard.getValues().name,
city: rpc.views.Contact.CommunicateCard.getValues().city
}
});
};
Since I need to “thwart” my Cross Site Scripting problems, I’ve had to write an ActionFilter that adds the appropriate headers.
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();
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", "*");
string rqstMethod = HttpContext.Current.Request.Headers["Access-Control-Request-Method"];
if (rqstMethod == "OPTIONS" || rqstMethod == "POST")
{
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Headers", "X-Requested-With, Accept, Access-Control-Allow-Origin");
}
}
}
}
And in my controller, I’m receiving the data from my app as follows.
[AllowCrossSiteJsonAttribute]
public JsonpResult CommunicateCard(CommunicateCardModel communicateCardModel)
{
CommunicateCardModel cc = null;
string rqstMethod = System.Web.HttpContext.Current.Request.Headers["Access-Control-Request-Method"];
if (rqstMethod != "POST")
{
// Do stuff with the model
return this.Jsonp(true);
}
else {
return this.Jsonp(false);
}
}
You’ll see that I had to put if (rqstMethod != "POST") because the model from the “POST” is blank, but the model from the “OPTIONS” is not.
Here are the raw headers being passed… (note: these two headers are being passed in pairs… ie: the controller is being called twice.)
FIRST CALL
OPTIONS /GetInTouch/CommunicateCard HTTP/1.1
Host: webservice.example.com
Referer: http://192.168.3.138/
Access-Control-Request-Method: POST
Origin: http://192.168.3.138
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
SECOND CALL (notice the very bottom line that contains the posted data (which is not contained within the first call) callback=foo&name=Chester&city=Toronto)
POST /GetInTouch/CommunicateCard HTTP/1.1
Host: webservice.example.com
Referer: http://192.168.3.138/
Content-Length: 38
Origin: http://192.168.3.138
X-Requested-With: XMLHttpRequest
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
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
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.3callback=foo&name=Chester&city=Toronto
Is there any way to prevent multiple calls to my controller? (or why IS my controller being called twice?)
Turns out it was fixed by making a JSONP call from my Sencha Touch app.
Ext.util.JSONP.request// THIS IS WRONG, DON’T USE THIS CODE TO MAKE JSONP CALLS
// THIS IS RIGHT