Asp.net 核心模型不从表单绑定

Asp.net core model doesn't bind from form

我从第 3 端静态页面(由 Adob​​e 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 具有来自表单的所有值,但模型为空

[0] {[Name, Example]}
[1] {[Email, Example@example.com]}
[2] {[Company, Hello]}
[3] {[Phone, Hello]}
[4] {[Additional, Hello]}

void更改为A​​ctionResult

[HttpPost]
public ActionResult Index(EmailModel email)

并且不要忘记从您的视图和操作中验证 AntiForgeryToken。

// to your form in view 
@Html.AntiForgeryToken()
// ------------

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(EmailModel email)

我遇到了同样的问题 这个文档帮助我理解模型绑定 https://docs.asp.net/en/latest/mvc/models/model-binding.html

我通过确保 属性 名称与表单字段名称完全匹配来解决我的问题 并且我还添加了 [FromForm] 属性以准确指定绑定源。

我不确定是不是同一种情况,但我遇到了同样的问题,但看起来没有什么适合我的。
我的问题是我的视图模型 class

中有一个名为 Model 的 属性
public string Model { get; set; }

当我将 属性 重命名为 ModelName 时,即使没有 FromForm 属性,一切都再次正常工作。

看起来一些特殊的 属性 名称对于 asp.net mvc 模型绑定来说可能有点问题。

因此,我的建议是检查您的模型属性,也许尝试将它们一一重命名,以检查是否存在问题。

希望对您有所帮助。

注意不要给动作参数一个与模型相同的名称属性,否则绑定器将尝试绑定到参数并失败。

public async Task<IActionResult> Index( EmailModel email ){ ... }

public class EmailModel{ public string Email { get; set; } }

将操作参数 'email' 更改为不同的名称,它将按预期进行绑定。

public async Task<IActionResult> Index( EmailModel uniqueName ){ ... }

如果请求模型中的一个或多个属性无法绑定到请求模型上可接受的属性,也会发生此问题。

在我的例子中,我应该将 List<string> 类型传递给 属性,但不小心传递了 string。这导致整个请求模型变成 null

我 运行 今天对此进行了研究,虽然事后看来这似乎很明显,但我只是想补充一点,您需要确保您绑定的模型上的属性的访问修饰符是正确的.我有一些 public MyProperty { get; internal set; } 但它们不会绑定。删除了 internal,它们工作得很好。

就我而言,我使用 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 核心 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
   {

   }

我遇到了同样的问题,我想分享一下我的情况以及我是如何得到解决方案的。也许,有人会觉得知道有用。

我的上下文是 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,但在我的处理程序参数中,我使用了参数名称 登录数据。 ASP.NET核心怎么会知道,这个LoginInput.UserNameOrEmail其实就是loginData.UserNameOrEmail。它不能,对吧?因此,它没有绑定我的表单数据。

然后,当我将 ViewModel 属性“LoginInput”重命名为与处理程序参数相同的名称时,如下所示:

public LoginInput LoginData { get; set; }

ASP.NET 核心随后发现表单数据与参数名称匹配,然后开始正确绑定。我的问题解决了。