C# 更改模型后未显示ModelState错误

C# 更改模型后未显示ModelState错误,c#,asp.net,asp.net-mvc,visual-studio,nerddinner,C#,Asp.net,Asp.net Mvc,Visual Studio,Nerddinner,我正在遵循专业ASP.NET MVC 1.0上的NerdDinner示例(我使用的是VisualStudio 2015附带的ASP.NET MVC版本),到目前为止,我能够解决一些小问题,但这一个让我很失望 我有一个名为Dinner的模型,它被传递给一个名为Create()的操作的视图。与Create相对应的视图基本上是一个请求一些信息的表单,当提交时,页面会显示错误(如果有)。错误通过ModelState对象传递给视图 public ActionResult Create()

我正在遵循专业ASP.NET MVC 1.0上的NerdDinner示例(我使用的是VisualStudio 2015附带的ASP.NET MVC版本),到目前为止,我能够解决一些小问题,但这一个让我很失望

我有一个名为Dinner的模型,它被传递给一个名为Create()的操作的视图。与Create相对应的视图基本上是一个请求一些信息的表单,当提交时,页面会显示错误(如果有)。错误通过ModelState对象传递给视图

    public ActionResult Create()
    {
        Dinner dinner = new Dinner();
        return View(dinner);
    }

    [HttpPost]
    public ActionResult Create(Dinner d)
    {
        TryUpdateModel(d);
        if (d.isValid)
        {
            ...
        }
        else
        {
            foreach (var violation in d.GetRuleViolations())
                ModelState.AddModelError(violation.PropertyName, violation.ErrorMessage);
            return View(d);
        }
    }
创建视图看起来像这样

@model NerdDinner.Models.Dinner

...

            @Html.ValidationMessageFor(Model => Model.Title, "", new { @class = "text-danger" })

...
在我创建了一个名为ViewModel的新模型以传递其他对象来创建视图之前,这一切都很顺利

public class DinnerFormViewModel
{
    public Dinner Dinner
    {
        get;
        private set;
    }

    public DinnerFormViewModel() : this(new Dinner()) { }

    public DinnerFormViewModel(Dinner d)
    {
        Dinner = d;
    }

    ... stuff ...
}
我更新了Create()方法,以确保将正确的模型传递给相应的视图

    public ActionResult Create()
    {
        Dinner dinner = new Dinner();
        return View(new DinnerFormViewModel(dinner));   // Updated line.
    }

    [HttpPost]
    public ActionResult Create(DinnerFormViewModel d)   // Updated line.
    {
        TryUpdateModel(d);
        if (d.Dinner.isValid)   // Updated line.
        {
            ...
        }
        else
        {
            foreach (var violation in d.Dinner.GetRuleViolations())   // Updated line.
                ModelState.AddModelError(violation.PropertyName, violation.ErrorMessage);
            return View(new DinnerFormViewModel(d.Dinner));   // Updated line.
        }
    }
还更新了视图

@model NerdDinner.Models.DinnerFormViewModel

...

            @Html.ValidationMessageFor(Model => Model.Dinner.Title, "", new { @class = "text-danger" })

...

页面正常工作(正确保存有效的表单数据),但当提交无效信息时,错误不再显示在页面上。在视图文件中,我检查了存储在ModelState中的错误,它们都在那里。ModelState和表单字段之间似乎存在断开连接。我认为问题在于我提供给ModelState.AddModelError()方法的属性名,但我对此不确定。非常感谢您的帮助。

首先,当您的模型中有一个类实例属性时,如果该属性为null,则不会对其任何属性运行验证。其次,类实例属性有一个私有setter,因此modelbinder将无法实际将其设置为任何值,这意味着它将始终为null


长话短说,问题在于私有setter。

我应该首先为ViewModel添加构造函数。(我更新了上面的代码。)在DinnerPerformViewMode类中,我确保无论何时实例化它,都会传递一个Dinner对象或创建一个新对象。实际上,在DinnerPerformViewModel(晚餐d)中,我没有检查d是否为null,但我认为我总是向它传递一个非null的晚餐对象。我还是要加一张支票,看看有没有这种情况发生。所以,私人二传不应该是问题所在(我试着把它公之于众以防万一,但没用。)好吧,这仍然是一个问题。modelbinder将只使用无参数构造函数,因此它只能使用公共的post数据设置属性。