将剃须刀视图字段绑定到 MVC 3 中的模型

本文关键字:模型 MVC 剃须刀 视图 字段 绑定 | 更新日期: 2023-09-27 18:31:43

我在将视图中的字段(文本框和复选框)提交到我的模型时遇到问题,不确定如何继续。每次我点击应该提交给模型的按钮时,控制器都会检查应该由视图设置的字段,但一直返回 false。因此,要么它们没有首先被设置,要么控制器读错了它们。无论哪种方式,我都不知所措。请帮忙:X

视图(略有简化):

@model Model
@Html.ValidationSummary()
@{ Html.BeginForm("PrintReport", "Controller", FormMethod.Get, new {     @class = "form_ll" }); }
<h1>@ViewBag.Title</h1>
<div class="group">
    @Html.ValidTextBoxFor(Model => Model.ToDate) 
    @Html.ValidTextBoxFor(Model => Model.FromDate)
    @Html.CheckBoxFor(Model => Model.Geplakt)
    @Html.CheckBoxFor(Model => Model.Geparafeerd)
    @Html.CheckBoxFor(Model => Model.Verschreven)
    @Html.CheckBoxFor(Model => Model.Geannuleerd)
    @Html.CheckBoxFor(Model => Model.Vermist)
    @Html.CheckBoxFor(Model => Model.Vernietigd)
    @Html.CheckBoxFor(Model => Model.Onbruikbaar)
    @Html.CheckBoxFor(Model => Model.Misdruk)
    @Html.CheckBoxFor(Model => Model.Teruggevonden)
    @Html.CheckBoxFor(Model => Model.InOnderzoek)
</div>
<div class="button">
    @Html.Button("Print")
</div>
@{ Html.EndForm(); }

型:

[Serializable]
public class Model : DomainObject
{
    [DataType(DataType.Date)]
    public DateTime? FromDate { get; set; }
    [DataType(DataType.Date)]
    public DateTime? ToDate { get; set; }
    public bool Geplakt { get; set; }
    public bool Geparafeerd { get; set; }
    public bool Verschreven { get; set; }
    public bool Geannuleerd  { get; set; }
    public bool Vermist  { get; set; }
    public bool Vernietigd { get; set; }
    public bool Onbruikbaar { get; set; }
    public bool Misdruk { get; set; }
    public bool Teruggevonden { get; set; }
    public bool InOnderzoek { get; set; }
    public Model()
    {
        // Constructor
    }               
}

控制器:

public class Controller : ModelController<Model>
{
    [HttpGet]
    public ActionResult Index()
    {
        Model = new Model();
        return InternalIndex();
    }
    [HttpGet]
    public ActionResult InternalIndex()
    {
        return View("Index", Model);
    }
    [HttpGet]
    public ActionResult PrintReport()
    {
        if (!Model.FromDate.HasValue || !Model.ToDate.HasValue)
            ModelState.AddModelError("Date", "At leaste one date is null");
        else {
            if (Model.FromDate.Value.CompareTo(Model.ToDate.Value) >= 0)
                ModelState.AddModelError("Date", "First date is later then the second one");
        }
        if(Model.IsAnythingChecked())
            ModelState.AddModelError("Checkboxes", "You haven't checked any checkboxes");
        if (ModelState.IsValid)
        {
            return View("PrintReport", Model);
        }
        else
        {
            return InternalIndex();
        }
    }            

将剃须刀视图字段绑定到 MVC 3 中的模型

您使用的是 GET 而不是 POST。您正在将模型发送到控制器,但未收到信息。一行应为:

@{ Html.BeginForm("PrintReport", "Controller", FormMethod.Post, new {     @class = "form_ll" }); }

您还需要将模型发送到控制器,并将控制器中的方法设置为 HttpPost:

    [HttpPost]
public ActionResult PrintReport(Model m)
{
    if (!Model.FromDate.HasValue || !Model.ToDate.HasValue)
        ModelState.AddModelError("Date", "At leaste one date is null");
    else {
        if (Model.FromDate.Value.CompareTo(Model.ToDate.Value) >= 0)
            ModelState.AddModelError("Date", "First date is later then the second one");
    }
    if(Model.IsAnythingChecked())
        ModelState.AddModelError("Checkboxes", "You haven't checked any checkboxes");
    if (ModelState.IsValid)
    {
        return View("PrintReport", Model);
    }
    else
    {
        return InternalIndex();
    }
}   

试一试。

看起来您正在将表单数据发布到仅 GET 控制器。此外,您尚未告诉控制器期望模型。试试这个(注意删除[HTTPGet装饰器]:

public ActionResult PrintReport(Model m)
{
    if (!m.FromDate.HasValue || !m.ToDate.HasValue)
        ModelState.AddModelError("Date", "At leaste one date is null");
    else {
        if (m.FromDate.Value.CompareTo(m.ToDate.Value) >= 0)
            ModelState.AddModelError("Date", "First date is later then the second one");
    }
    if(m.IsAnythingChecked())
        ModelState.AddModelError("Checkboxes", "You haven't checked any checkboxes");
    if (ModelState.IsValid)
    {
        return View("PrintReport", Model);
    }
    else
    {
        return InternalIndex();
    }
}   

我目前没有可用于测试的设置,但这应该可以工作

您需要

有两个重载的PrintReport操作方法。

  • 一个具有[HttpGet]属性。这用于返回您的网页
  • 一个具有 [HttpPost] 属性的参数,它采用类型 Model 的参数(您的模型类,实际上应该更新以具有描述其模型的名称)。当您的表单将值提交回 Web 服务器时,将使用此方法。

您的表单应该更新为POST(将FormMethod.Get更改为FormMethod.Post)。

然后,MVC 模型绑定应为您整理其余部分,为 PrintReport 操作方法的第二次重载创建模型类型的实例。

您需要将模型作为控制器操作的参数传递回去,以查看视图中反映的更改,即

public ActionResult PrintReport(Model model) {

你的ModelController<Model>课的内容是什么? 我怀疑你在那个类中创建了一个新模型,这就是你的代码在编写if (!Model.FromDate.HasValue和类似内容时所指的。

但是,控制器无法知道视图正在回发的模型。 为了改变这一点,你需要做三件事:

  1. PrintReport 方法添加一个参数来表示正在处理的模型,并在代码中使用该参数而不是Model
  2. [HttpPost] 标记PrintReport方法,以便可以将模型传递给该方法。
  3. 将表单更改为使用"发布"而不是"获取"。