为什么我的控制器被调用两次?

时间:2011-08-10 20:50:52

标签: asp.net-mvc-3 http-post sencha-touch

这可能很简单,但我看不到它。

我的应用程序将数据发布到我的WebService()。 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”中的模型不是。

以下是传递的原始标题...(注意:这两个标题是成对传递的...即:控制器被调用两次。)

第一次致电

  

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,Content-Type
  接受: /
  Accept-Encoding:gzip,deflate,sdch
  接受语言:en-US,en; q = 0.8
  Accept-Charset: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
  接受: /
  Accept-Encoding:gzip,deflate,sdch
  接受语言:en-US,en; q = 0.8
  Accept-Charset:ISO-8859-1,utf-8; q = 0.7,*; q = 0.3

     

回调= FOO&安培;名称=切斯特&安培;城市=多伦多

有没有办法防止多次调用我的控制器? (或者为什么我的控制器被调用两次?)

1 个答案:

答案 0 :(得分:1)

原来通过我的Sencha Touch应用程序进行JSONP调用来修复它 Ext.util.JSONP.request

//这是错误的,请勿使用此代码进行JSONP调用

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
        }
    });

//这是正确的

var submitCommunicateCard = function () {
    console.log("Outbound Data Object:");
    console.log(rpc.views.Contact.CommunicateCard.getValues());
    Ext.util.JSONP.request({
        url: WebService('GetInTouch', 'CommunicateCard'),
        method: 'post',
        callbackKey: 'callback',

        params: {
            name: rpc.views.Contact.CommunicateCard.getValues().name,
            city: rpc.views.Contact.CommunicateCard.getValues().city
        },
        callback: function (result) {
            console.log("Inbound Data Object:");
            console.log(result);
            // Handle error logic
            if (result.success === true) {
                Ext.Msg.alert("Sent!", "Thank you, your message has been sent!", Ext.emptyFn);
                rpc.views.Contact.CommunicateCard.reset();
            } else {
                Ext.Msg.alert("Oops!", "looks like something went wrong, please try again.", Ext.emptyFn);
            }
        }
    });
};