为什么我的模型正在填充但文本框没有?

Why is my model populating but the text box isn't?

我正在通过两个值搜索数据库:

public class SearchProjectModel : ISearchProject
    {
        public int ProjectID { get; set; }
        [Display(Name = "Project Number")]
        public string JobNumber { get; set; }
        [Display(Name = "Project Name")]
        public string JobName { get; set; }
    }

索引视图:

@model SearchProjectModel

@using (@Html.BeginForm("ManipulateProject", "Project", FormMethod.Post))
{

    <div>
        @Html.HiddenFor(x => x.ProjectID)
        <div class="col-md-3">
            @Html.LabelFor(x => x.JobNumber)
            @Html.TextBoxFor(x => x.JobNumber, new { @class = "form-control", id = "jobNumber" })
            @Html.ValidationMessageFor(x => x.JobNumber)
        </div>
        <div class="col-md-6">
            @Html.LabelFor(x => x.JobName)
            @Html.TextBoxFor(x => x.JobName, new { @class = "form-control " })
            @Html.ValidationMessageFor(x => x.JobName)
        </div>
    </div>

    <div class="col-md-12 text-center" style="margin-top: 1%">
        <button type="submit" class="btn btn-primary">Submit</button>
    </div>
}

然后我在控制器上根据发现的内容创建一个新模型:

public ActionResult ManipulateProject(SearchProjectRequest request)
{
    var project = _projectService.GetBy(request);
    if (project != null)
    {
        //When this method is complete the data is in the new model!!!!
        return View("Project", Assemble(project));
    }
    return View("Project", Assemble(new ManipulateProjectModel()));
}

型号:

 public class ManipulateProjectModel : IProject
{
    public int ProjectID { get; set; }
    [Display(Name = "Project Number"), Required(ErrorMessage = "Required!")]
    public string JobNumber { get; set; }
    [Display(Name = "Project Name"), Required(ErrorMessage = "Required!")]
    public string JobName { get; set; }
    //Lots of stuff that is being populated
}

项目视图:

@model ManipulateProjectModel

<div>
@using (@Html.BeginForm("Save", "Project", FormMethod.Post))
{
    @Html.HiddenFor(x => x.ProjectID)
    <div class="col-md-12" style="border: 1px dotted black; padding: 1%; margin-top: 1%">
        <h3 class="col-md-12 text-center">Project Info</h3>
        <div class="col-md-3">
            @Html.LabelFor(x => x.JobNumber)
            @Html.TextBoxFor(x => x.JobNumber, new { @class = "form-control", id = "jobNumber"})
            @Html.ValidationMessageFor(x => x.JobNumber)
        </div>
        <div class="col-md-6">
            @Html.LabelFor(x => x.JobName)
            @Html.TextBoxFor(x => x.JobName, new { @class = "form-control "})
            @Html.ValidationMessageFor(x => x.JobName)
        </div>

        //stuff that is populated just fine
    </div>
}
</div>

找到项目并调用 Assemble 后,新模型将填充所有数据!!!但是,如果我只搜索两个参数之一,那么我没有填写的框会填充到模型上,但文本框不会显示数据。

为什么填充了模型但视图没有填充文本框。它不应该知道或关心是否填充了先前的视图。

这是因为 html 助手使用来自 ModelState 的值,而不是来自您的模型的值。当你从 post 到 public ActionResult ManipulateProject(SearchProjectModel request) 时(注意我假设它真的是 SearchProjectModel,而不是 SearchProjectRequest),一个 SearchProjectModel 的实例被创建并且它的属性被绑定。这些值也添加到 ModelState.

当您 return 具有 ManipulateProjectModel 实例的视图时,您的 @Html.TextBoxFor(x => x.JobName) 通过首先查找 ModelState 值来设置值。因为第一个表单中的值是(比如说)null,那么文本框将在 post 之后显示一个空字符串,因为 JobNameModelState 值是 null,尽管您的 Assemble() 方法可能已将其设置为。 this answer.

中解释了此行为的原因

一种选择是为您的 SearchProjectModel 属性指定与 ManipulateProjectModel 中的属性不同的名称。另一个选项是在重新分配新值和 return 视图

之前清除 ModelState
ModelState.Clear(); // clears all values
// or clear one property
if (ModelState.ContainsKey("JobName"))
{
  ModelState["JobName"].Errors.Clear();
}

注意清除模型状态也会删除验证错误,因此请谨慎使用。