ASP.NET 核心 - 尝试使用局部视图布局表单控件时未绑定数据值

ASP.NET Core - Data values not bound when trying to use a partial view to lay out form controls

我正在尝试创建局部视图以节省创建表单时所需的样板代码量。我所拥有的一个简单版本如下...

@model FormRowViewModel

<div class="form-group row">
  <label for="@Model.PropertyName" class="col-lg-2 col-form-label">@Model.Label</label>
  <div class="col-lg-10 input-group">
    <input type="text" asp-for="@Model.PropertyName" class="form-control">
  </div>
</div>

...其中 FormRowViewModel 看起来像这样...

public class FormRowViewModel {
  public FormRowViewModel(string propertyName, string label) {
    PropertyName = propertyName;
    Label = label;
  }

  public string PropertyName { get; set; }
  public string Label { get; set; }
}

想法是在这样的视图中使用它...

@model ContactViewModel

<form method="post" asp-controller="Home" asp-action="Index">
  <div asp-validation-summary="All" class="text-danger"></div>
  @await Html.PartialAsync("_FormRow", new FormRowViewModel("UserName", "Your name"))
  @await Html.PartialAsync("_FormRow", new FormRowViewModel("Email", "Email"))
  @await Html.PartialAsync("_FormRow", new FormRowViewModel("Telephone", "Telephone"))
  <div class="form-group row">
    <div class="offset-sm-2 col-lg-10">
      <button type="submit" class="btn btn-primarySubmit</button>
    </div>
  </div>
</form>

这有效,因为它按预期创建了 HTML(几乎),但有两个问题...

1) 生成的 HTML 包含 value 属性,这些属性将文本框的内容设置为 属性 名称...

<input type="text" class="form-control" id="PropertyName"
   name="PropertyName" value="UserName">

2) 无论我在文本框中输入什么,当表单回发到服务器时,视图模型属性都是空字符串。甚至添加的 属性 个名称也没有通过。

如果有帮助,这里是处理视图的控制器操作...

public IActionResult Index() => 
  View();

[HttpPost]
public IActionResult Index(ContactViewModel vm) {
  if (!ModelState.IsValid) {
    return View(vm);
  }
  // Next line added so I can see when it worked
  return RedirectToAction(nameof(Privacy));
}

有人知道我做错了什么吗?谢谢

你这里的整个方法都是不正确的。看来您正在寻找的是编辑器模板。本质上,您需要在 Views\Shared\EditorTemplates 中创建与 DataType 枚举的类型或成员相对应的部分视图,并在其中添加您的自定义 HTML。例如,您可以创建一个 String.cshtml 视图:

@model string
<div class="form-group row">
    <label asp-for="@Model" class="col-lg-2 col-form-label"></label>
    <div class="col-lg-10 input-group">
        <input asp-for="@Model" class="form-control">
    </div>
</div>

然后,对于任何字符串 属性:

@Html.EditorFor(x => x.MyStringProp)

并且将使用您的自定义模板,并绑定正确的名称。

或者,您可以创建自定义 taghelper,但方法有点复杂,因为您需要在代码中处理 HTML 生成。不过,如果您对这种方法感兴趣,请查看 source for the built-in tag helpers 并以此为基础创建您自己的方法。