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

39

我正在尝试使用JQuery AJAX调用包含复杂对象参数的控制器动作方法。

我已经阅读了很多博客并尝试了从中学到的几种技术。 我构建的最佳尝试代码(如下)的关键帖子是stackoverflow帖子here

我想触发异步发布,当用户在一个字段上切换时调用它[不是表单保存发布 - 如其他示例所示]。

我的意图是:

  • 在客户端上实例化一个对象[而不是为视图提供类型的ViewModel];
  • 从视图中的几个字段中填充对象;
  • 将此对象转换为JSON;
  • 使用jQuery.Ajax方法调用控制器操作方法,传递JSON对象。

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

问题是:

  • 如果操作方法带有HttpPost属性,则不会调用控制器Action方法(即使将AJAX调用类型设置为“POST”)。
  • 如果操作方法带有HttpGet,则参数的属性值为null。
  • ReadObject方法会抛出错误:“Expecting element 'root' from namespace''.. Encountered 'None' with name 'namespace'”。

希望有人可以帮忙。 以下是代码:

客户端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)
  });


操作过滤器和与操作方法参数相关联的类型的类

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

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

控制器上的操作方法

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

42

以下是我如何使它工作的。

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

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

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

用于调用此操作方法的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
      });

2
值得注意的是,您在JavaScript代码中进行的更改之一是参数名称不在引号中。而是使用了 {InvoiceNumber: 而不是 {"Invoice Number":,我猜这是问题的一部分。 - Mattygabe
@Mattygabe 那真的不应该有影响。 - DCShannon
你什么时候会使用JSON.stringify和JSON.Encode?我似乎只有在MVC4的模型绑定器中使用JSON.Encode才能成功。 - eaglei22
这是如何工作的?在您的示例中,'myController'只出现了一次。 - Paul McCarthy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接