在 Asp.net 核心 MVC 中序列化表单并将其转换为复杂的 Class 到 Post 使用 Ajax 的整个模型时出现问题
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 表单,以便它将根据我的 PessoaViewModel 复合体 class 进行转换。显然,序列化是正确发生的,但是当我 post 使用 ajax 时,通常 98% 的字段都加载了空值。下面我 post 编辑了一段序列化 class:
ExibirTelaPesquisaCpfCnpjAntesCadastrarPessoa=False&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=Brasileiro&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 核心 MVC (
(控制器、PessoaViewModel Class 和子 classes)):
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;
}
据我研究,序列化仅使用既非空也非空的字段。为什么它不起作用?字段名称中是否存在无效字符,因为它们中的许多都在列表中?
有谁知道如何帮助我?
谢谢!
当您使用 .serialize() 时,它会生成 'query string' 格式的数据,需要使用默认的内容类型 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;
}
我正在序列化我的 ASP.NET 表单,以便它将根据我的 PessoaViewModel 复合体 class 进行转换。显然,序列化是正确发生的,但是当我 post 使用 ajax 时,通常 98% 的字段都加载了空值。下面我 post 编辑了一段序列化 class:
ExibirTelaPesquisaCpfCnpjAntesCadastrarPessoa=False&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=Brasileiro&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 核心 MVC ( (控制器、PessoaViewModel Class 和子 classes)):
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;
}
据我研究,序列化仅使用既非空也非空的字段。为什么它不起作用?字段名称中是否存在无效字符,因为它们中的许多都在列表中? 有谁知道如何帮助我? 谢谢!
当您使用 .serialize() 时,它会生成 'query string' 格式的数据,需要使用默认的内容类型 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;
}