MVC ajax json post para o método de ação do controlador

Eu estou tentando alcançar uma chamada JQuery AJAX para um método de ação do controlador que contém um object complexo como um parâmetro. Eu li muitos blogs e tentei várias técnicas aprendidas com eles. O post principal no qual construí meu melhor código de tentativa (abaixo) é o post stackoverflow aqui .

Desejo triggersr uma postagem assíncrona, chamada quando o usuário separa um campo [não uma postagem de salvamento de formulário – como demonstrado em outros exemplos que encontrei].

Minha intenção é:

  • Instanciar um object no cliente [não o ViewModel que fornece o tipo para a visualização];
  • Preencha o object com dados de vários campos na exibição;
  • Converta este object para JSON;
  • Chame o método de ação do controlador usando o método jQuery.Ajax, transmitindo o object JSON.

Os resultados serão retornados como um resultado JSON; e os dados serão carregados nos campos da exibição, dependendo dos resultados retornados.

Os problemas são:

  • Se o método de ação for atribuído com o atributo HttpPost, o método de ação do controlador não será chamado (mesmo que o tipo de chamada AJAX esteja configurado como ‘POST’).
  • Se o método de ação for atribuído com HttpGet, os valores das propriedades do parâmetro serão nulos
  • O método ReadObject lança o erro: “Esperando o elemento ‘root’ do namespace ” .. Encontrou ‘None’ com o nome ‘namespace'”.

Espero que alguém possa ajudar. Obrigado. Código abaixo:

Arquivo js do cliente

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

Filtro de ação e class para o tipo associado ao parâmetro do método Action

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

Método de ação no controlador

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

Abaixo está como eu consegui este trabalho.

O ponto-chave era: eu precisava usar o ViewModel associado à visão para que o tempo de execução pudesse resolver o object na solicitação.

[Eu sei que há uma maneira de vincular um object diferente do object ViewModel padrão, mas acabou simplesmente preenchendo as propriedades necessárias para minhas necessidades, pois não consegui fazê-lo funcionar]

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

O script JQuery usado para chamar este método de ação:

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

Esta postagem de blog aborda diretamente seu problema.

Ele usa uma técnica sem a necessidade de bibliotecas de cliente JSON adicionais. Ele introduz um plugin jQuery muito simples que irá ajudá-lo a fazer o truque.

Qual versão do asp.net mvc você está usando? Postando objects json em ações de controladores fortemente tipados foi adicionado ao ASP.NET MVC 3 Beta 1. Este artigo explica uma solução alternativa usando o modelo de fichários para o asp.net mvc 2 e informações sobre como ele funciona no MVC 3.