Asp.net核心模型不能从表单绑定
本文关键字:表单 绑定 不能 模型 net 核心 Asp | 更新日期: 2023-09-27 18:14:04
我捕获来自第三方静态页面(由Adobe Muse生成)的post请求,并使用MVC动作处理它。
<form method="post" enctype="multipart/form-data">
<input type="text" name="Name">
...
</form>
空表单动作路由:
app.UseMvc(routes => routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}"));
但是在
中,我有每个属性都为空的模型行动:
[HttpPost]
public void Index(EmailModel email)
{
Debug.WriteLine("Sending email");
}
模型:
public class EmailModel
{
public string Name { get; set; }
public string Email { get; set; }
public string Company { get; set; }
public string Phone { get; set; }
public string Additional { get; set; }
}
Request.Form
具有form中的所有值,但model为空
[0] {[Name, Example]}
[1] {[Email, Example@example.com]}
[2] {[Company, Hello]}
[3] {[Phone, Hello]}
[4] {[Additional, Hello]}
注意不要给动作参数取与模型属性相同的名字,否则绑定器会尝试绑定该参数而失败。
public async Task<IActionResult> Index( EmailModel email ){ ... }
public class EmailModel{ public string Email { get; set; } }
将actions参数'email'更改为另一个名称,它将按预期绑定。
public async Task<IActionResult> Index( EmailModel uniqueName ){ ... }
我不确定它是相同的情况,但我有同样的问题,没有什么看起来真的为我工作。
在我的情况下的问题是,我有一个名为模型的属性在我的视图模型类
public string Model { get; set; }
当我将属性重命名为ModelName时,即使没有FromForm属性,一切都工作得很好。
看起来一些特殊的属性名可能会对asp.net mvc模型绑定造成一点问题。
所以,我的建议是检查你的模型属性,也许尝试逐个重命名它们,以检查问题是否存在。
Net Core 3.1
在我的例子中,我使用Ajax发布的复杂模型(包含其他模型的模型,如共享模型),因此视图中的输入被自动命名为"ChildModel"。PropertyName"(见代码)
[HttpPost]
[ValidateAntiForgeryToken] // ("AUVM.PropertyName")
public async Task<JsonResult> AddUser([FromForm]AUVM aUVM) //Parameter name must match the first part of the input name in order to bind
{
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<JsonResult> AddUser([FromForm]AUVM someUniqueName) //This is wrong and won't bind
{
}
我也有同样的问题这个文档帮助我理解模型绑定https://docs.asp.net/en/latest/mvc/models/model-binding.html
我通过确保属性名称与表单字段名称完全匹配来解决问题我还添加了[FromForm]属性来指定绑定源。
我今天遇到了这个问题,虽然事后看来很明显,但我认为我应该补充一点,您需要确保您要绑定的模型上的属性的访问修饰符是正确的。我在一些上面涂了public MyProperty { get; internal set; }
,它们不能结合。删除internal
,他们工作得很好
将void更改为ActionResult。
[HttpPost]
public ActionResult Index(EmailModel email)
不要忘记从视图和操作中验证AntiForgeryToken。
// to your form in view
@Html.AntiForgeryToken()
// ------------
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(EmailModel email)
如果请求模型中的一个或多个属性未能绑定到请求模型上的可接受属性,也可能发生此问题。
在我的情况下,我应该传递一个List<string>
类型的属性,但意外地传递了一个string
。这导致整个请求模型变为null
在我的情况下,我使用MVC 4.0约定命名您发布的对象。例如,
js:
$http.post("SaveAnswer", { answer: answerValues })
c#:
public ActionResult SaveAnswer([FromBody] AnswerVM answer) {...}
当我将js更改为$http.post("SaveAnswer", answerValues)
时,一切正常
我遇到了这个问题,当我在底层模型上有多个构造函数时,模型不绑定,如:
public class EmailModel
{
public EmailModel()
{}
public EmailModel(string _name, string _company)
{
Name = _name;
Company = _company;
}
public string Name { get; set; }
public string Email { get; set; }
public string Company { get; set; }
public string Phone { get; set; }
public string Additional { get; set; }
}
通过删除除一个构造函数以外的所有构造函数修复:
public class EmailModel
{
public EmailModel()
{}
public string Name { get; set; }
public string Email { get; set; }
public string Company { get; set; }
public string Phone { get; set; }
public string Additional { get; set; }
}
我也有同样的问题,我想分享一下我的情况以及我是如何得到解决方案的。也许,有人会觉得知道这件事很有用。
我的上下文是ASP。. NET Core 3.1 Razor页面。我有一个处理程序
public async Task<JsonResult> OnPostLogin([FromForm] LoginInput loginData)
{
}
在我的ViewModel中还有一个属性
public LoginInput LoginInput { get; set; }
在我的Razor页面中,我使用了这样的表单:
<form asp-page-handler="Login" method="post">
<input asp-for="LoginData.UserNameOrEmail">
.....
注意,在我的表单中,我使用了属性LoginInput。UserNameOrEmail,但是在处理程序的参数中,我使用了参数名loginData。ASP将如何?. NET Core知道,这个LoginInput。UserNameOrEmail实际上是loginData.UserNameOrEmail。它不能,对吧?因此,它没有绑定我的表单数据。
然后,当我重命名我的ViewModel属性"LoginInput"与处理程序参数同名,如下所示:
public LoginInput LoginData { get; set; }
ASP。然后,NET Core发现表单数据与参数名称匹配,然后它开始正确绑定。我的问题解决了