huo*_*345 7 c# asp.net asp.net-mvc razor tag-helpers
我想为具有许多属性的实体编写Edit.cshtml文件,因此我必须多次编写以下代码:
<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>
Run Code Online (Sandbox Code Playgroud)
实际上,有很多实体,所以我必须编写许多Edit.cshtml文件.我想做一些简化
我想在控制器中选择实体的一些属性,并使用循环来显示视图中的属性.例如:在控制器文件中:
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);
}
Run Code Online (Sandbox Code Playgroud)
在视图文件中:
@{
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>
}
}
Run Code Online (Sandbox Code Playgroud)
但它无法工作,因为它会产生错误的代码.似乎我无法为"asp-for"标签助手传递字符串值.
例如,如果我将top的代码更改为:
@{
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>
}
Run Code Online (Sandbox Code Playgroud)
上面的代码将生成:
<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>
Run Code Online (Sandbox Code Playgroud)
预期的代码是:
<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>
Run Code Online (Sandbox Code Playgroud)
我应该怎么做?
剃须刀有可能吗?
好的,我设法让这个工作.免责声明:这是超级hacky,我不知道我是否以最好的方式做到了.我所知道的是,它做了你想做的事,它可能会指向你正确的方向.
首先,我创建了一个模型:
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; }
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我制作了一个自定义标签助手.这是"神奇"发生的可怕部分.特别是Process方法的第一部分......
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:要使自定义TagHelper工作,您需要在_ViewImports.cshtml文件中添加一行,如下所示(替换WebApplication1为您的命名空间):
@addTagHelper "*, WebApplication1"
Run Code Online (Sandbox Code Playgroud)
我把我的动作更改为了这个,以便与你匹配(也许你可以使用反射来获取你的模型属性名称?):
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);
}
Run Code Online (Sandbox Code Playgroud)
最后,在视图中,您可以执行以下操作:
<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>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16128 次 |
| 最近记录: |