为什么我的控制器被调用两次?
这可能很简单,但我就是看不到。
我有我的 sencha-touch 应用程序将数据发布到我的 WebService (asp.net-mvc-3)。 Sencha Touch js 代码如下所示。
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
}
});
};
由于我需要“阻止”跨站点脚本问题,因此我必须编写一个添加适当标头的 ActionFilter
。
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");
}
}
}
}
在我的控制器中,我从我的应用程序接收数据,如下所示。
[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);
}
}
您会发现我必须输入 if (rqstMethod != "POST") 因为“POST”中的模型是空白的,但“OPTIONS”中的模型不是。
这是正在传递的原始标头...(注意:这两个标头是成对传递的...即:控制器被调用两次。)
首次调用
选项 /GetInTouch/CommunicateCard HTTP/1.1
主机:webservice.example.com
引用者:http://192.168.3.138/
访问控制请求方法:POST
来源:http://192.168.3.138
用户代理:Mozilla/5.0(Macintosh;Intel Mac OS X 10_7_0)AppleWebKit/534.24(KHTML,如 Gecko)Chrome/11.0.696.71 Safari/534.24
访问控制请求标头:X-Requested-With、内容类型
接受:/
接受编码:gzip、deflate、sdch
接受语言:en-US,en;q=0.8
接受字符集:ISO-8859-1,utf-8;q=0.7,*;q=0.3
SECOND CALL (注意包含发布数据的最底行(不是包含在第一个调用中)callback=foo&name=Chester&city=Toronto
)
POST /GetInTouch/CommunicateCard HTTP/1.1
主机:webservice.example.com
引用者:http://192.168.3.138/
内容长度:38
来源:http://192.168.3.138
X-Requested-With:XMLHttpRequest
用户代理:Mozilla/5.0(Macintosh;Intel Mac OS X 10_7_0)AppleWebKit/534.24(KHTML,如 Gecko)Chrome/11.0.696.71 Safari/534.24
内容类型:application/x-www-form-urlencoded;字符集=UTF-8
接受:/
接受编码:gzip、deflate、sdch
接受语言:en-US,en;q=0.8
接受字符集:ISO-8859-1,utf-8;q=0.7,*;q=0.3callback=foo&name=切斯特&city=多伦多
有什么办法可以防止多次调用我的控制器吗? (或者为什么我的控制器被调用两次?)
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?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,它是通过从我的 Sencha Touch 应用程序进行 JSONP 调用来修复的。
Ext.util.JSONP.request
// 这是错误的,不要使用此代码进行 JSONP 调用
// 这是正确的
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