如何使用 JSONP 将复杂数组发送到 asp.net mvc 控制器

Posted

技术标签:

【中文标题】如何使用 JSONP 将复杂数组发送到 asp.net mvc 控制器【英文标题】:How to send complex array to asp.net mvc controller with JSONP 【发布时间】:2012-07-12 19:44:41 【问题描述】:

我如何使用 JSONP发送复杂类型的对象,其中包含数组

 var product= categories:[ id:1,text:"cat 1",id:2,text:"cat 2"],id:43,price:3535;
 $.getJSON(url ,product, function (data) 

 //i can get the data from the server but i cant pass the complex array to the server
 );

在 asp.net mvc 服务器上:

    public JsonpResult Create(Product product)
    
        string thisisok = product.id;
        string needthis = product.categories[0].text;           
        return new JsonpResult  Data = true ;
    

我应该如何使用“getjson”方法传递复杂的 json, 我不能使用 ajax 请求,因为它需要跨域

【问题讨论】:

进行跨域 AJAX 调用的最佳方式是使用代理。 【参考方案1】:

我也有类似的问题;我想使用 jsonp 将一组对象传递给控制器​​,但我总是将它作为空值接收! (我的意思是,通过 GET 方法和带有回调功能的跨域)

假设我有一个复杂的类:SearchCriteria

public class SearchCriteria

    public string destination get; set;
    public string destinationTitle  get; set;         
    public string departure  get; set; 
    public string month  get; set; 
    public string nights  get; set; 
    public string cruiseline  get; set; 

我想将一个 SearchCriteria 数组传递给我的控制器。

我找到了创建属性的解决方案:

public class JsonpFilter : ActionFilterAttribute

    public string Param  get; set; 
    public Type JsonDataType  get; set; 
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    
        if (filterContext.HttpContext.Request.ContentType.Contains("application/json"))
        
            string inputContent = filterContext.HttpContext.Request.Params[Param];                
            javascriptSerializer serializer = new JavaScriptSerializer();
            var result = serializer.Deserialize(inputContent, JsonDataType);
            filterContext.ActionParameters[Param] = result;
        
    

在控制器中:

 [JsonpFilter(Param = "criterias", JsonDataType = typeof(SearchCriteria[]))]
 public JsonpResult getResultSet(SearchCriteria[] criterias)
             
     foreach (SearchCriteria sc in criterias)
     
         // TODO (normalize criteria, etc..)
     
     return Jsonp(new  content = RenderPartialViewToString("getResults", criterias));
 

在我调用方法时的客户端脚本中:

// Populate the Array of objects

var criteria = new Array();
for (var i = 0; i < 4; i++) 
    criteria.push( "destination": $("#DestinationValue" + i).val(),
                    "departure": $("#PortValue" + i).val(),
                    "month": $("#Month" + i).val(),
                    "nights": $("#Nights" + i).val(),
                    "cruiseline": $("#CruiselineValue" + i).val());                


// Call the controller; note i do not specify POST method and I specify "callback" in order to enable jsonp that cross the domain.

$.ajax( 
  url: "getResultSet?callback=?", 
  dataType: 'json', 
  data: "criterias" : JSON.stringify(criteria), 
  contentType: 'application/json; charset=utf-8',
  success: function (data) 
              // call return from the controller
           
);                 

我希望这可以帮助某人。

【讨论】:

谢谢你 - 几乎把我整理出来,除了 filterContext.HttpContext.Request.ContentType 总是 "" - 有什么想法吗?使用与您完全相同的 ajax 调用(不同的数据除外)【参考方案2】:

如果您需要从服务器返回 JSONP,为什么要从控制器操作返回 JSON?这就是说,jQuery 的 JSONP 实现依赖于将 &lt;script&gt; 标签添加到 DOM,并且如您所知,&lt;script&gt; 标签发送 GET 请求以获取资源。这是 jQuery 的 JSONP 实现的限制。

但首先你需要让你的服务器返回 JSONP。您可以编写一个返回 JSONP 的自定义 ActionResult:

public class JsonpResult : ActionResult

    private readonly object _obj;

    public JsonpResult(object obj)
    
        _obj = obj;
    

    public override void ExecuteResult(ControllerContext context)
    
        var serializer = new JavaScriptSerializer();
        var callbackname = context.HttpContext.Request["callback"];
        var jsonp = string.Format("0(1)", callbackname, serializer.Serialize(_obj));
        var response = context.HttpContext.Response;
        response.ContentType = "application/json";
        response.Write(jsonp);
    

然后在你的控制器动作中返回这个结果:

public ActionResult Create(Product product)

    ...
    return new JsonpResult(new  success = true );

然后客户端可以使用此操作,但使用 GET 请求(以及所有限制,例如发送您显示的复杂对象):

$.getJSON('http://example.com/products/create', product, function(result) 
    alert(result.success);
);

如果您需要发送复杂的对象,我认为最好在您的域上设置一个服务器端脚本,作为您的域和远程域之间的桥梁,然后向您的脚本发送 $.ajax 请求.

【讨论】:

问题是没有从服务器获取jsonp 嗯,你给我们看的代码肯定有问题。如果您说这不是问题,那么为什么您的控制器操作会返回 Json? JSON 与 JSONP 不同。但正如我所说,JSONP 的 jQuery 实现仅适用于 GET 请求,因此即使您设法从控制器操作中返回正确的 JSONP(如我的回答所示),您也可能会遇到此限制。您可能会使用服务器端代理。

以上是关于如何使用 JSONP 将复杂数组发送到 asp.net mvc 控制器的主要内容,如果未能解决你的问题,请参考以下文章

使用 POST 向 JSONP 请求发送数据

如何在 RESTEasy 中启用 JSONP?

如何使用 JSONP 下载客户端 javascript 对象?

通过 Fetch API 将复杂的表单数据发送到 PHP 端点 [重复]

使用 jQuery 1.5 将请求作为 jsonp 发送,将响应解释为文本

Vue中如何使用axios发送jsonp跨域验证