我从第三方静态页面(由Adobe Muse生成)捕获发布请求,并使用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
包含表单中的所有值,但模型为空
[0] {[Name, Example]}
[1] {[Email, Example@example.com]}
[2] {[Company, Hello]}
[3] {[Phone, Hello]}
[4] {[Additional, Hello]}
答案 0 :(得分:33)
注意不要为action参数指定一个与model属性相同的名称,否则binder将尝试绑定到参数并失败。
public async Task<IActionResult> Index( EmailModel email ){ ... }
public class EmailModel{ public string Email { get; set; } }
更改操作参数&#39; email&#39;使用不同的名称,它将按预期绑定。
public async Task<IActionResult> Index( EmailModel uniqueName ){ ... }
答案 1 :(得分:1)
我不确定是不是同样的情况,但是我遇到了同样的问题,没有什么能真正为我工作 我的问题是我的视图模型类中有一个名为Model的属性
public string Model { get; set; }
当我将属性重命名为ModelName时,即使没有FromForm属性,一切都恢复正常。
看起来某些特殊的属性名称对于asp.net mvc模型绑定可能有点问题。
所以,我的建议是检查您的模型属性,并尝试逐个重命名,以检查问题是否存在。
希望这有帮助。
答案 2 :(得分:1)
ASP.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
{
}
答案 3 :(得分:0)
将 void 更改为 ActionResult 。
[HttpPost]
public ActionResult Index(EmailModel email)
不要忘记从您的视图和操作中验证AntiForgeryToken。
// to your form in view
@Html.AntiForgeryToken()
// ------------
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(EmailModel email)
答案 4 :(得分:0)
我遇到了同样的问题 这个文档帮助我理解模型绑定 https://docs.asp.net/en/latest/mvc/models/model-binding.html
我通过确保属性名称在表单字段名称中完全匹配来解决我的问题 我还添加[FromForm]属性来准确指定绑定源。
答案 5 :(得分:0)
我今天遇到了这个问题,尽管事后看来似乎很明显,只是以为我要补充一下,您需要确保要绑定的模型上Properties的访问修饰符正确。我在某些物品上装有public MyProperty { get; internal set; }
,它们将不会束缚。删除了internal
,它们工作正常。
答案 6 :(得分:0)
就我而言,我使用的是MVC 4.0约定来命名要发布的对象。例如,
js:
$http.post("SaveAnswer", { answer: answerValues })
C#:
public ActionResult SaveAnswer([FromBody] AnswerVM answer) {...}
当我将js更改为$http.post("SaveAnswer", answerValues)
时,一切正常。
答案 7 :(得分:0)
我遇到了以下问题:当我在基础模型上有多个构造器时,模型不绑定:
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; }
}
答案 8 :(得分:0)
我遇到了同样的问题,我想分享我的案子发生的情况以及如何获得解决方案。也许,有人可能会觉得有用。
我的上下文是 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发现表单数据与参数名称匹配,然后开始正确绑定。我的问题解决了。