如何为“asp-for"传递字符串值?在 asp 网络 5 中
[英] How can I pass string value for "asp-for" in asp net 5
本文介绍了如何为“asp-for"传递字符串值?在 asp 网络 5 中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想为一个实体写一个Edit.cshtml文件,要编辑的属性很多,所以要写很多次如下代码:
<label asp-for="Email" class="col-md-2 control-label"></label><div class="col-md-10"><input asp-for="Email" class="form-control"/><span asp-validation-for="Email" class="text-danger"></span>
其实实体很多,所以我得写很多Edit.cshtml文件.我想做一些简化
我想在控制器中选择实体的一些属性并使用循环在视图中显示这些属性.例如:在控制器文件中:
public IActionResult Edit(string id){var 模型 = GetModel(id);var propertyNames= new List(){名称",电子邮件"//添加实体的一些其他属性名称};ViewData["PropertyList"] = propertyNames;返回视图(模型);}
在视图文件中:
@{var propertyNames = (List)ViewData["PropertyList"];foreach(propertyNames 中的字符串项){<div class="form-group"><label asp-for="@(item)" class="col-md-2 control-label"></label><div class="col-md-3"><input asp-for="@(item)" class="form-control"/><span asp-validation-for="@(item)" class="text-danger"></span>
}}
但它不能工作,因为它生成了错误的代码.似乎我无法为asp-for"标签助手传递字符串值.
比如我把top的代码改成这样:
@{字符串 e = "电子邮件";<div class="form-group"><label asp-for="@e" class="col-md-2 control-label"></label><div class="col-md-10"><input asp-for="@e" class="form-control"/><span asp-validation-for="@e" class="text-danger"></span>
}
上面的代码将生成:
<label class="col-md-2 control-label" for="e">e</label><div class="col-md-10"><input class="form-control" type="text" id="e" name="e" value="Email"/><span class="text-danger field-validation-valid" data-valmsg-for="e" data-valmsg-replace="true"></span>
预期的代码是:
<label class="col-md-2 control-label" for="Email">Email</label><div class="col-md-10"><input class="form-control" type="email" data-val="true" data-val-email="Email 字段不是有效的电子邮件地址。"data-val-required="电子邮件 字段是必需的。"id="Email" name="Email" value=""/><span class="text-danger field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
我该怎么办?
可以用剃刀吗?
解决方案
好的,我设法让它工作了.免责声明:这太难了,我不知道我是否以最好的方式完成了它.我所知道的是,它可以满足您的需求,并且可能会为您指明正确的方向.
首先,我创建了一个模型:
使用 System.ComponentModel.DataAnnotations;命名空间 WebApplication1.Models{公共类测试模型{[必需的]公共字符串名称 { 获取;放;}[必需的][电子邮件地址][显示(姓名=电子邮件地址")]公共字符串电子邮件{获取;放;}}}
然后,我制作了一个自定义标签助手.这是魔法"发生的可怕之处.特别是Process
方法的第一部分...
使用 Microsoft.AspNet.Mvc.Rendering;使用 Microsoft.AspNet.Mvc.ViewFeatures;使用 Microsoft.AspNet.Razor.TagHelpers;使用 System.Linq;命名空间 WebApplication1.TagHelpers{[HtmlTargetElement("edit")]公共类 EditTagHelper : TagHelper{[HtmlAttributeName("asp-for")]公共模型表达式 aspFor { 获取;放;}[视图上下文][HtmlAttributeNotBound]公共 ViewContext ViewContext { 获取;放;}受保护的 IHtmlGenerator _generator { 获取;放;}公共 EditTagHelper(IHtmlGenerator 生成器){_generator = 发电机;}公共覆盖无效流程(TagHelperContext 上下文,TagHelperOutput 输出){var propName = aspFor.ModelExplorer.Model.ToString();var modelExProp = aspFor.ModelExplorer.Container.Properties.Single(x => x.Metadata.PropertyName.Equals(propName));var propValue = modelExProp.Model;var propEditFormatString = modelExProp.Metadata.EditFormatString;var label = _generator.GenerateLabel(ViewContext, aspFor.ModelExplorer,propName, propName, new { @class = "col-md-2 control-label", @type = "email" });var input = _generator.GenerateTextBox(ViewContext, aspFor.ModelExplorer,propName, propValue, propEditFormatString, new { @class = "form-control" });var 验证 = _generator.GenerateValidationMessage(ViewContext, aspFor.ModelExplorer,propName, string.Empty, string.Empty, new { @class = "text-danger" });var inputParent = new TagBuilder("div");inputParent.AddCssClass("col-md-10");inputParent.InnerHtml.Append(输入);inputParent.InnerHtml.Append(验证);var parent = new TagBuilder("div");parent.AddCssClass("form-group");parent.InnerHtml.Append(label);parent.InnerHtml.Append(inputParent);output.Content.SetContent(parent);base.Process(上下文,输出);}}}
注意:要使自定义 TagHelper 工作,您需要在 _ViewImports.cshtml
文件中添加一行,如下所示(替换 WebApplication1
使用您的命名空间):
@addTagHelper "*, WebApplication1"
我将我的操作更改为此,以与您的操作相匹配(也许您可以在此处使用反射来获取模型属性名称?):
public IActionResult Index(){var propertyNames = new List(){名称",电子邮件"};ViewData["PropertyList"] = propertyNames;var m = new TestModel(){Name = "huoshan12345",电子邮件 = "test@test.net"};返回视图(m);}
最后,在视图中,您可以执行以下操作:
@using (Html.BeginForm()){var propertyNames = (List)ViewData["PropertyList"];foreach(propertyNames 中的字符串项){<edit asp-for="@item"></edit>}<input type="submit" value="Submit"/>}
I want to write a Edit.cshtml file for an entity with many properties to edit, so I have to write the following codes many times:
<div class="form-group">
<label asp-for="Email" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
Actually, there are many entities so that I have to write many Edit.cshtml files. I want to make some simplifications
I want to select some properties of the entity in the controller and use loop to show the properties in the view. For example:
In the controller file:
public IActionResult Edit(string id)
{
var model = GetModel(id);
var propertyNames= new List<string>()
{
"Name",
"Email"
// add some other property names of the entity
};
ViewData["PropertyList"] = propertyNames;
return View(model);
}
In the view file:
@{
var propertyNames = (List<string>)ViewData["PropertyList"];
foreach (string item in propertyNames)
{
<div class="form-group">
<label asp-for="@(item)" class="col-md-2 control-label"></label>
<div class="col-md-3">
<input asp-for="@(item)" class="form-control" />
<span asp-validation-for="@(item)" class="text-danger"></span>
</div>
</div>
}
}
but it cannot work, since it generates wrong codes. It seems that I cannot pass a string value for "asp-for" tag helper.
For example, if I change the code of top to this:
@{
string e = "Email";
<div class="form-group">
<label asp-for="@e" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="@e" class="form-control" />
<span asp-validation-for="@e" class="text-danger"></span>
</div>
</div>
}
The code above will generate this:
<div class="form-group">
<label class="col-md-2 control-label" for="e">e</label>
<div class="col-md-10">
<input class="form-control" type="text" id="e" name="e" value="Email" />
<span class="text-danger field-validation-valid" data-valmsg-for="e" data-valmsg-replace="true"></span>
</div>
</div>
The expected code is:
<div class="form-group">
<label class="col-md-2 control-label" for="Email">Email</label>
<div class="col-md-10">
<input class="form-control" type="email" data-val="true" data-val-email="Email 字段不是有效的电子邮件地址。" data-val-required="Email 字段是必需的。" id="Email" name="Email" value="" />
<span class="text-danger field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
</div>
How should I do?
Is it possible in razor?
解决方案
Ok, I managed to get this working. DISCLAIMER: It is super hacky and I have no idea if I've done it in the best way possible. All I know is that it does what you want and it might point you in the right direction.
Firstly, I created a model:
using System.ComponentModel.DataAnnotations;
namespace WebApplication1.Models
{
public class TestModel
{
[Required]
public string Name { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email Address")]
public string Email { get; set; }
}
}
Then, I made a custom tag helper. This is the horrible bit where the "magic" happens. Specifically the first section of the Process
method...
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Razor.TagHelpers;
using System.Linq;
namespace WebApplication1.TagHelpers
{
[HtmlTargetElement("edit")]
public class EditTagHelper : TagHelper
{
[HtmlAttributeName("asp-for")]
public ModelExpression aspFor { get; set; }
[ViewContext]
[HtmlAttributeNotBound]
public ViewContext ViewContext { get; set; }
protected IHtmlGenerator _generator { get; set; }
public EditTagHelper(IHtmlGenerator generator)
{
_generator = generator;
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
var propName = aspFor.ModelExplorer.Model.ToString();
var modelExProp = aspFor.ModelExplorer.Container.Properties.Single(x => x.Metadata.PropertyName.Equals(propName));
var propValue = modelExProp.Model;
var propEditFormatString = modelExProp.Metadata.EditFormatString;
var label = _generator.GenerateLabel(ViewContext, aspFor.ModelExplorer,
propName, propName, new { @class = "col-md-2 control-label", @type = "email" });
var input = _generator.GenerateTextBox(ViewContext, aspFor.ModelExplorer,
propName, propValue, propEditFormatString, new { @class = "form-control" });
var validation = _generator.GenerateValidationMessage(ViewContext, aspFor.ModelExplorer,
propName, string.Empty, string.Empty, new { @class = "text-danger" });
var inputParent = new TagBuilder("div");
inputParent.AddCssClass("col-md-10");
inputParent.InnerHtml.Append(input);
inputParent.InnerHtml.Append(validation);
var parent = new TagBuilder("div");
parent.AddCssClass("form-group");
parent.InnerHtml.Append(label);
parent.InnerHtml.Append(inputParent);
output.Content.SetContent(parent);
base.Process(context, output);
}
}
}
NB: To make the custom TagHelper work, you need to add a line into the _ViewImports.cshtml
file, like this (replace WebApplication1
with your namespace):
@addTagHelper "*, WebApplication1"
I changed my action to this, to sort of match yours (maybe you can use reflection to get your model property names here?):
public IActionResult Index()
{
var propertyNames = new List<string>()
{
"Name",
"Email"
};
ViewData["PropertyList"] = propertyNames;
var m = new TestModel()
{
Name = "huoshan12345",
Email = "test@test.net"
};
return View(m);
}
Then finally, in the view, you can do something like this:
<div class="row">
@using (Html.BeginForm())
{
var propertyNames = (List<string>)ViewData["PropertyList"];
foreach (string item in propertyNames)
{
<edit asp-for="@item"></edit>
}
<input type="submit" value="Submit" />
}
</div>
这篇关于如何为“asp-for"传递字符串值?在 asp 网络 5 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文