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 并以此为基础创建您自己的方法。
我正在尝试创建局部视图以节省创建表单时所需的样板代码量。我所拥有的一个简单版本如下...
@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 并以此为基础创建您自己的方法。