【问题标题】:Problems Serializing a Form and Converting It to a Complex Class in Asp.net Core MVC to Post a Whole Model Using Ajax在 Asp.net Core MVC 中序列化表单并将其转换为复杂类以使用 Ajax 发布整个模型的问题
【发布时间】:2020-03-19 02:59:06
【问题描述】:

我正在序列化我的 ASP.NET 表单,以便根据我的 PessoaViewModel 复杂类对其进行转换。显然,序列化发生正确,但是当我使用 ajax 发布时,98% 的字段都加载了空值。下面我贴出一段序列化类:

ExibirTelaPesquisaCpfCnpjAntesCadastrarPessoa =假&PessoaViewModel.Id = 2 PessoaViewModel.PessoaNatureza&= Juridica&PessoaViewModel.PessoaFisicaViewModel.PessoaId = 2&PessoaViewModel.PessoaFisicaViewModel.NomeCompleto = JALBER%20ROMANO&PessoaViewModel.PessoaFisicaViewModel.Apelido = BIM&PessoaViewModel.PessoaFisicaViewModel.DataNascimento = 2019年11月18日PessoaViewModel.PessoaFisicaViewModel.Sexo = Masculino&PessoaViewModel& .PessoaFisicaViewModel.EstadoCivil = Solteiro&PessoaViewModel.PessoaFisicaViewModel.PessoaFisicaOrigem =巴西陆军&PessoaViewModel.PessoasEnderecosViewModel%5B0%5D.Id = 3&PessoaViewModel.PessoasEnderecosViewModel%5B0%5D.PessoaId = 2&PessoaViewModel.PessoasEnderecosViewModel%5B0%5D.EnderecoTipoDescricao = COBRAN%C3%87A&PessoaViewModel.PessoasEnderecosViewModel%5B0 %5D.RotuloEnderecoTipo=Endere%C3%A7o%20de%20cobran%C3%A7a%20%C3%A9%20utilizado%20para%20definir%20o%20local%20de%20cobran%C3%A7a%20de%20mercadorias%20adquiridas%20pelos %20clientes.&PessoaViewModel.PessoasEnderecosViewModel%5B0%5D。 EnderecoTipoId=3&PessoaViewModel.PessoasEnderecosViewModel%5B0%5D.PaisId=1&PessoaViewModel.PessoasEnderecosViewModel%5B0%5D.CodigoPostal=29780-000&......

JS:

var pessoaViewModel = $('form').serialize();

$.ajax({
    url: "/pessoa-gerenciar/change-pessoa-natureza",
    type: "POST",
    data: JSON.stringify({ pessoaViewModel: pessoaViewModel}),
    contentType: "application/json",
    success: function (data) {

    },
    error: function () {
        stopLoadModalInside();
        alert("Oops! Algo deu errado.");
    }
});

Asp.Net Core MVC ( (控制器、PessoaViewModel 类和子类)):

public class PessoaViewModel
{
    [Key]
    public int Id { get; set; }

    [DisplayName("Natureza")]
    [Required(ErrorMessage = "Escolha uma Natureza")]
    public PessoaNatureza PessoaNatureza { get; set; }
    [DisplayName("Natureza")]
    public string PessoaNaturezaDescricao { get; set; }
    [DisplayName("Naturezas")]
    public IEnumerable<SelectListItem> PessoasNaturezas { get; set; }

    public PessoaFisicaViewModel PessoaFisicaViewModel { get; set; }
    public PessoaJuridicaViewModel PessoaJuridicaViewModel { get; set; }

    public List<PessoaGenericoViewModel> PessoasGenericosViewModel { get; set; }
    public List<PessoaContatoViewModel> PessoasContatosViewModel { get; set; }
    public List<PessoaDocumentoViewModel> PessoasDocumentosViewModel { get; set; }
    public List<PessoaEnderecoViewModel> PessoasEnderecosViewModel { get; set; }

    //Configuracoes
    //public bool AtivarBloqueioRedundanciaCpfCnpj { get; set; }
    public bool ExibirTelaPesquisaCpfCnpjAntesCadastrarPessoa { get; set; }

    //DropDownList Novo Contato
    public IEnumerable<SelectListItem> FormasContato { get; set; }

    //DropDownList Novo Endereco
    public IEnumerable<SelectListItem> EnderecosTipos { get; set; }

    //DropDownList
    public IEnumerable<SelectListItem> DocumentosTipos { get; set; }

    // public IEnumerable<SelectListItem> DocumentosOrgaosEmissores { get; set; }

    public IEnumerable<SelectListItem> Paises { get; set; }

    public PessoaViewModel()
    {
        PessoasNaturezas = ExtensaoDeEnumerador.EnumParaSelectListGenerico<PessoaNatureza>("U", PessoaNatureza.ToString()).OrderBy(x => x.Text);
        PessoaFisicaViewModel = null;
        PessoaJuridicaViewModel = null;
    }
}


 public class PessoaDocumentoViewModel
{
    [Key]
    public int Id { get; set; }

    [DisplayName("Pessoa")]
    [Required(ErrorMessage = "Escolha uma Pessoa")]
    public int PessoaId { get; set; }

    [DisplayName("Tipo de Documento")]
    [Required(ErrorMessage = "Escolha um Tipo de Documento")]
    public int DocumentoTipoId { get; set; }

    public string DocumentoTipoDescricao { get; set; }
    public string RotuloDocumentoTipo { get; set; }
    public string DocumentoTipoSigla { get; set; }

    [DisplayName("Documento")]
    [Required(ErrorMessage = "O campo Número do Documento é obrigatório")]
    [MaxLength(30, ErrorMessage = "O campo {0} deve ter no máximo {1} caracteres")]
    public string Documento { get; set; }

    public PessoaDocumentoDataEmissaoViewModel PessoaDocumentoDataEmissaoViewModel { get; set; }
    public PessoaDocumentoDataPrimeiraEmissaoViewModel PessoaDocumentoDataPrimeiraEmissaoViewModel { get; set; }
    public PessoaDocumentoDataVencimentoViewModel PessoaDocumentoDataVencimentoViewModel { get; set; }
    public PessoaDocumentoDataExpedicaoViewModel PessoaDocumentoDataExpedicaoViewModel { get; set; }
    public PessoaDocumentoOrgaoEmissorViewModel PessoaDocumentoOrgaoEmissorViewModel { get; set; }
    public PessoaDocumentoZonaViewModel PessoaDocumentoZonaViewModel { get; set; }
    public PessoaDocumentoSecaoViewModel PessoaDocumentoSecaoViewModel { get; set; }
    public PessoaDocumentoCategoriaViewModel PessoaDocumentoCategoriaViewModel { get; set; }
    public PessoaDocumentoSerieViewModel PessoaDocumentoSerieViewModel { get; set; }
    public PessoaDocumentoPaisViewModel PessoaDocumentoPaisViewModel { get; set; }
    public PessoaDocumentoUFViewModel PessoaDocumentoUFViewModel { get; set; }

    public IEnumerable<SelectListItem> DocumentosTipos { get; set; }
    public IEnumerable<SelectListItem> DocumentosOrgaosEmissores { get; set; }
    public IEnumerable<SelectListItem> Paises { get; set; }

}


[HttpPost]
[Route("pessoa-gerenciar/change-pessoa-natureza")]
public PartialViewResult ChangePessoaNatureza([FromBody] PessoaViewModel pessoaViewModel)
{

    return null;
}

据我研究,序列化只使用既不为空也不为空的字段。为什么它不起作用?字段名称中是否存在无效字符,因为它们中的许多都在列表中? 有谁知道如何帮助我? 谢谢!

【问题讨论】:

  • 为什么要将表单序列化为 url 编码的字符串,然后将该字符串序列化为 Json?也许您可以将表单发布到您的控制器并使用 FromForm 属性 (docs.microsoft.com/en-gb/dotnet/api/…) 装饰 viewmodel 参数和控制器操作方法
  • 我必须发布的原因是因为我需要滚动一些字段信息,因为用户在选择中选择了一些选项。这不是提交,而是交换一些信息的帖子。
  • 您的意思是这样的:用户填写表格的一部分,然后您将其发布,然后用户会看到更多选项并继续填写表格的其余部分?
  • 或多或少。例如,用户从 select 中选择一个选项,一些字段将不需要,而其他字段将需要显示。然后应该发布一个帖子,将 ViewModel 发送到服务器并进行更新。然后返回给客户端。

标签: javascript ajax asp.net-core serialization asp.net-ajax


【解决方案1】:

当您使用 .serialize() 时,它会生成“查询字符串”格式的数据,这些数据需要使用默认的 contentType application/x-www-form-urlencoded; charset=UTF-8 发送,而不是 JSON。

要么删除contentType 选项,要么指定contentType:application/x-www-form-urlencoded; charset=UTF-8

@model PessoaViewModel
<form>
    <input asp-for="PessoaNaturezaDescricao" />
    <input asp-for="ExibirTelaPesquisaCpfCnpjAntesCadastrarPessoa" />
    ...
    <input asp-for="PessoasDocumentosViewModel[0].PessoaId" />
    <input asp-for="PessoasDocumentosViewModel[0].Documento" />
    <input type="button" onclick="test()"/>
</form>
@section Scripts
{
<script>
    function test()
    {
        var pessoaViewModel = $('form').serialize();
        $.ajax({
            url: "/pessoa-gerenciar/change-pessoa-natureza",
            type: "POST",
            data: pessoaViewModel,
            success: function (data) {
            },
            error: function () {
                stopLoadModalInside();
                alert("Oops! Algo deu errado.");
            }
        });
            }

</script>
}

另外,您需要将FromBody 更改为FromForm,如下所示:

[HttpPost]
[Route("pessoa-gerenciar/change-pessoa-natureza")]
public PartialViewResult ChangePessoaNatureza([FromForm] PessoaViewModel pessoaViewModel)
{

    return null;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多