Razor foreach 在 id 中放置 property/variable 名称,在呈现的 HTML 中放置 *for 属性
Razor foreach placing property/variable name in id,name and *for attributes in rendered HTML
工具与平台:ASP.NET Core MVC 3.1,Visual Studio 2019,Win 10
更新:这是一个 Upsert 视图。
我正在尝试遍历 Razor 页面中模型的属性以生成标签并在表单标记内输入 HTML 元素,但呈现的 HTML 具有 "Item" (名称foreach 中的变量)作为 id、name 和 *for HTML 属性的值。
在浏览器中呈现 HTML
<div class="form-group row">
<div class="col-3">
<label for="item">item</label>
</div>
<div class="col-6">
<input class="form-control" type="text" id="item" name="item" value="Author">
<span class="text-danger field-validation-valid" data-valmsg-for="item" data-valmsg-replace="true"></span>
</div>
</div>
HTML在浏览器中显示
Razor foreach 循环产生 HTML
@{ var propList = new string[] { "Name", "Author", "ISBN" };}
@foreach (var item in propList)
{
<div class="form-group row">
<div class="col-3">
<label asp-for="@item"></label>
</div>
<div class="col-6">
<input asp-for="@item" class="form-control" />
<span asp-validation-for="@item" class="text-danger"></span>
</div>
</div>
}
有人可以解释为什么会这样吗?
更新:
根据“@Ben Sampica”的建议,我进行了这些更改,
我的视图会是什么样子,我的意思是我记得使用模型列表作为 table 类视图(几年前我使用过 ASP.NET MVC,现在跳转到 .net 核心),这里是更改我做了,
查看:
@foreach (var book in Model.Books)
{
<div class="form-group row">
<div class="col-3">
<label asp-for="@book.Name"></label>
</div>
<div class="col-6">
<input asp-for="@book.Name" class="form-control" />
<span asp-validation-for="@book.Name" class="text-danger"></span>
</div>
</div>
}
我正在使用您描述的确切视图模型"BooksViewModel"
我之前没有在问题中说明,但要明确我正在创建一个 Upsert 视图,所以现在 ViewModel 是一个列表,尽管我一次只关心一个记录,视图创建操作时模型为空,因为列表中没有数据。
如果您查看 Microsoft Docs on ASP.NET Core Tag Helpers,您会发现 <label>
上的 asp-for
会从 属性 中获取 [Display]
属性(如果当前的)。作为备份,它将使用 属性 名称。在您的例子中,您传递的是一个字符串集合,所以让我们深入了解 Razor 看到的内容
PropList[]
{
string item = "Name"
string item = "Author"
string item = "ISBN"
}
迭代时,没有 Display
属性,那么根据我们上面的规则,约定是什么?使用 属性 名称(您在迭代器中将其命名为 item
)。
我认为您尝试做的事情在专用模型class中可能会更好地完成,例如:
public class BookViewModel
{
public string Name { get; set; }
public string Author { get; set; }
public string ISBN { get; set; }
}
那么在你看来
@using BookViewModel
<form>
<div class="form-group row">
<div class="col-3">
<label asp-for="@Model.Name"></label>
</div>
<div class="col-6">
<input asp-for="@Model.Name" class="form-control" />
<span asp-validation-for="@Model.Name" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-3">
<label asp-for="@Model.Author"></label>
</div>
<div class="col-6">
<input asp-for="@Model.Author" class="form-control" />
<span asp-validation-for="@Model.Author" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-3">
<label asp-for="@Model.ISBN"></label>
</div>
<div class="col-6">
<input asp-for="@Model.ISBN" class="form-control" />
<span asp-validation-for="@Model.ISBN" class="text-danger"></span>
</div>
</div>
<button type="submit">Submit</button>
</form>
更新响应:
以下回复来自 chat conversation b/w op 和 Answer poster
如果我正在做这个,我只会做两个动作(添加和编辑)并共享表单输入的部分视图,以便尽可能多地重用代码 - 而不是对这个 upsert 的解决方案太聪明了。这只是我的意见。我认为这就是为什么我无法理解您要查找的内容的部分原因。
我也不会用反射之类的东西来写HTML。如果你想重用一种输入类型(如文本框)的总体布局,我最多会制作一个视图组件并传递 属性。我不会 @foreach 整个模型 - 你如何确定下拉列表是什么?复选框呢?使用无法维护的巧妙解决方案,您很快就会陷入非常糟糕的境地。
最后,
- 如果您仍然想继续 - 最初通过反射走在正确的轨道上 - 请参阅以下 dotnet fiddle。忽略编译器警告并将@foreach 块复制到您自己的项目中。
工具与平台:ASP.NET Core MVC 3.1,Visual Studio 2019,Win 10
更新:这是一个 Upsert 视图。 我正在尝试遍历 Razor 页面中模型的属性以生成标签并在表单标记内输入 HTML 元素,但呈现的 HTML 具有 "Item" (名称foreach 中的变量)作为 id、name 和 *for HTML 属性的值。
在浏览器中呈现 HTML
<div class="form-group row">
<div class="col-3">
<label for="item">item</label>
</div>
<div class="col-6">
<input class="form-control" type="text" id="item" name="item" value="Author">
<span class="text-danger field-validation-valid" data-valmsg-for="item" data-valmsg-replace="true"></span>
</div>
</div>
HTML在浏览器中显示
Razor foreach 循环产生 HTML
@{ var propList = new string[] { "Name", "Author", "ISBN" };}
@foreach (var item in propList)
{
<div class="form-group row">
<div class="col-3">
<label asp-for="@item"></label>
</div>
<div class="col-6">
<input asp-for="@item" class="form-control" />
<span asp-validation-for="@item" class="text-danger"></span>
</div>
</div>
}
有人可以解释为什么会这样吗?
更新:
根据“@Ben Sampica”的建议,我进行了这些更改,
我的视图会是什么样子,我的意思是我记得使用模型列表作为 table 类视图(几年前我使用过 ASP.NET MVC,现在跳转到 .net 核心),这里是更改我做了,
查看:
@foreach (var book in Model.Books)
{
<div class="form-group row">
<div class="col-3">
<label asp-for="@book.Name"></label>
</div>
<div class="col-6">
<input asp-for="@book.Name" class="form-control" />
<span asp-validation-for="@book.Name" class="text-danger"></span>
</div>
</div>
}
我正在使用您描述的确切视图模型"BooksViewModel"
我之前没有在问题中说明,但要明确我正在创建一个 Upsert 视图,所以现在 ViewModel 是一个列表,尽管我一次只关心一个记录,视图创建操作时模型为空,因为列表中没有数据。
如果您查看 Microsoft Docs on ASP.NET Core Tag Helpers,您会发现 <label>
上的 asp-for
会从 属性 中获取 [Display]
属性(如果当前的)。作为备份,它将使用 属性 名称。在您的例子中,您传递的是一个字符串集合,所以让我们深入了解 Razor 看到的内容
PropList[]
{
string item = "Name"
string item = "Author"
string item = "ISBN"
}
迭代时,没有 Display
属性,那么根据我们上面的规则,约定是什么?使用 属性 名称(您在迭代器中将其命名为 item
)。
我认为您尝试做的事情在专用模型class中可能会更好地完成,例如:
public class BookViewModel
{
public string Name { get; set; }
public string Author { get; set; }
public string ISBN { get; set; }
}
那么在你看来
@using BookViewModel
<form>
<div class="form-group row">
<div class="col-3">
<label asp-for="@Model.Name"></label>
</div>
<div class="col-6">
<input asp-for="@Model.Name" class="form-control" />
<span asp-validation-for="@Model.Name" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-3">
<label asp-for="@Model.Author"></label>
</div>
<div class="col-6">
<input asp-for="@Model.Author" class="form-control" />
<span asp-validation-for="@Model.Author" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-3">
<label asp-for="@Model.ISBN"></label>
</div>
<div class="col-6">
<input asp-for="@Model.ISBN" class="form-control" />
<span asp-validation-for="@Model.ISBN" class="text-danger"></span>
</div>
</div>
<button type="submit">Submit</button>
</form>
更新响应:
以下回复来自 chat conversation b/w op 和 Answer poster
如果我正在做这个,我只会做两个动作(添加和编辑)并共享表单输入的部分视图,以便尽可能多地重用代码 - 而不是对这个 upsert 的解决方案太聪明了。这只是我的意见。我认为这就是为什么我无法理解您要查找的内容的部分原因。
我也不会用反射之类的东西来写HTML。如果你想重用一种输入类型(如文本框)的总体布局,我最多会制作一个视图组件并传递 属性。我不会 @foreach 整个模型 - 你如何确定下拉列表是什么?复选框呢?使用无法维护的巧妙解决方案,您很快就会陷入非常糟糕的境地。
最后,
- 如果您仍然想继续 - 最初通过反射走在正确的轨道上 - 请参阅以下 dotnet fiddle。忽略编译器警告并将@foreach 块复制到您自己的项目中。