MVC ajax json post到控制器动作方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4120212/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:38:34  来源:igfitidea点击:

MVC ajax json post to controller action method

asp.net-mvcajaxjson

提问by Grant Sutcliffe

I am trying to achieve a JQuery AJAX call to a controller action method that contains a complex object as a parameter. I have read plenty blogs and tried several techniques learned from these. The key post on which I have constructed my best attempt code (below) is the stackoverflow post here .

我正在尝试实现对包含复杂对象作为参数的控制器操作方法的 JQuery AJAX 调用。我已经阅读了大量博客并尝试了从这些博客中学到的几种技术。我构建我的最佳尝试代码(如下)的关键帖子是这里的 stackoverflow 帖子。

I want to trigger an asynchronous post, invoked when the user tabs off a field [not a Form save post – as demonstrated in other examples I have found].

我想触发一个异步帖子,当用户关闭一个字段时调用[不是表单保存帖子 - 如我发现的其他示例所示]。

My intention is to:

我的意图是:

  • Instantiate an object on the client [not the ViewModel which provides the type for the View];
  • Populate the object with data from several fields in the view;
  • Convert this object to JSON;
  • Call the controller action method using the jQuery.Ajax method, passing the JSON object.
  • 在客户端实例化一个对象[不是提供视图类型的 ViewModel];
  • 使用来自视图中多个字段的数据填充对象;
  • 将此对象转换为 JSON;
  • 使用 jQuery.Ajax 方法调用控制器操作方法,传递 JSON 对象。

The results will be returned as a JSON result; and data will be loaded into fields in the view depending on results returned.

结果将作为 JSON 结果返回;数据将根据返回的结果加载到视图中的字段中。

The problems are:

问题是:

  • If the action method is attributed with the HttpPost attribute, the controller Action method is not invoked (even though the AJAX call type is set to ‘POST').
  • If the action method isattributed with HttpGet, the values of properties of the parameter are null
  • The ReadObject method throws the error: "Expecting element 'root' from namespace ''.. Encountered 'None' with name 'namespace'".
  • 如果操作方法被赋予 HttpPost 属性,则不会调用控制器 Action 方法(即使 AJAX 调用类型设置为“POST”)。
  • 如果action方法为HttpGet属性,则参数的属性值为null
  • ReadObject 方法抛出错误:“期望元素 'root' 来自命名空间 ''.. 遇到名称为 'namespace' 的 'None'”。

Hopefully someone can help. Thanks. Code below:

希望有人可以提供帮助。谢谢。代码如下:

Client js file

客户端js文件

 var disputeKeyDataObj = {
     "InvoiceNumber": "" + $.trim(this.value) + "",
     "CustomerNumber": "" + $.trim($('#CustomerNumber').val()) + ""
  };

  var disputeKeyDataJSON = JSON.stringify(disputeHeadlineData);      

  $.ajax({
     url: "/cnr/GetDataForInvoiceNumber",
     type: "POST",
     data: disputeKeyDataJSON,
     dataType: 'json',
     contentType: "application/json; charset=utf-8",
     success: EnrichedDisputeKeyData(result)
  });


Action Filter and class for the type associated with the Action method parameter


与 Action 方法参数关联的类型的 Action 过滤器和类

 [DataContract]  
 public class DisputeKeyData  
 {  
    [DataMember(Name = "InvoiceNumber")]  
    public string InvoiceNumber { get; set; }

    [DataMember(Name = "CustomerNumber")]
    public string CustomerNumber { get; set; }
 }  

Action method on the controller

控制器上的操作方法

  //[HttpPost]
  [ObjectFilter(Param = "disputeKeyData", RootType = typeof(DisputeKeyData))]  
  public ActionResult GetDataForInvoiceNumber(DisputeKeyData disputeKeyData)  
  {  
     //Blah!  
     //....  
     return Json(disputeKeyData, JsonRequestBehavior.AllowGet);  
  }  

回答by Grant Sutcliffe

Below is how I got this working.

下面是我如何得到这个工作。

The Key point was: I needed to use the ViewModel associated with the view in order for the runtime to be able to resolve the object in the request.

关键点是:我需要使用与视图关联的 ViewModel,以便运行时能够解析请求中的对象。

[I know that that there is a way to bind an object other than the default ViewModel object but ended up simply populating the necessary properties for my needs as I could not get it to work]

[我知道有一种方法可以绑定默认 ViewModel 对象以外的对象,但最终只是填充了我需要的必要属性,因为我无法让它工作]

[HttpPost]  
  public ActionResult GetDataForInvoiceNumber(MyViewModel myViewModel)  
  {            
     var invoiceNumberQueryResult = _viewModelBuilder.HydrateMyViewModelGivenInvoiceDetail(myViewModel.InvoiceNumber, myViewModel.SelectedCompanyCode);
     return Json(invoiceNumberQueryResult, JsonRequestBehavior.DenyGet);
  }

The JQuery script used to call this action method:

用于调用此操作方法的 JQuery 脚本:

var requestData = {
         InvoiceNumber: $.trim(this.value),
         SelectedCompanyCode: $.trim($('#SelectedCompanyCode').val())
      };


      $.ajax({
         url: '/en/myController/GetDataForInvoiceNumber',
         type: 'POST',
         data: JSON.stringify(requestData),
         dataType: 'json',
         contentType: 'application/json; charset=utf-8',
         error: function (xhr) {
            alert('Error: ' + xhr.statusText);
         },
         success: function (result) {
            CheckIfInvoiceFound(result);
         },
         async: true,
         processData: false
      });