为什么我的表单在对象的属性与控制器中的参数名称匹配时使用null对象发布

时间:2018-01-10 18:49:59

标签: c# asp.net-mvc

我有一个问题我已经解决了,但我不明白为什么我已经解决了。

我正在使用MVC,并使用剃须刀在表单中发布。

我的电子邮件模型包含许多属性,但需要注意的重要事项是

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

控制器签名是

    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";

        return View();
    }

    [HttpPost]
    public ActionResult Contact(MyEmail Email)
    {
        ViewBag.Message = $"Email is null : {Email == null}";

        return View();
    }

请注意,MyEmail的属性均为EmailController中的参数也被命名为Email

当我在CSHTML(视图)中发帖时,控制器的参数email始终为null

我玩过这个并且知道问题是参数名称(email)与我对象中属性的名称相匹配。

为什么不允许这样做?任何人都知道MVC在幕后做什么会让人感到困惑吗?

通过将属性从Email更改为EmailAddress ,将参数名称从Email更改为MySendObject可解决此问题。我不明白为什么。

视图是

@model WebApplication1.Models.MyEmail

@{
    ViewBag.Title = "Contact";
}

@using (Html.BeginForm())
{
    @Html.TextBoxFor(a => a.Email);
    <input type="submit" value="Send" />
}

1 个答案:

答案 0 :(得分:0)

我没看过..这只是基于我对ASP.NET MVC理解的一些评论。 MVC为open source,因此您可以轻松地验证(或反驳)我的观察结果。

我的猜测是模型绑定器正在查看HTML表单字段&#34; Email&#34;然后查看Action方法参数&#34; Email&#34;并且对自己说,这个字符串看起来并不像一个复杂的对象(MyEmail),所以它会抛出它并返回一个空值。

可能会看到表单字段和参数名称相同并运行SimpleTypeModelBinder而不是ComplexTypeModelBinder

我们公司为所有POST Action方法参数使用参数名model来避免这些冲突。

与我们的大多数GET参数命名为id完全相同的原因,我们的所有域模型都没有ID属性。

这里有一个interesting Gist详细介绍了一种调试默认模型装订器的方法 - 如果这是你要走的道路。