Ron*_*n C 5 html asp.net-core-mvc tag-helpers
如果我有这样的视图模型:
public class MyModel{
public DateTime? StartDate {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
在视图上,输入标记与asp-for标记助手一起使用,如下所示:
<input asp-for="StartDate" />
Run Code Online (Sandbox Code Playgroud)
由此生成的默认html是
<input type="datetime" id="StartDate" name="StartDate" value="" />
Run Code Online (Sandbox Code Playgroud)
但我希望它生成的是html,如下所示:
<input type="datetime" id="startDate" name="startDate" value="" />
Run Code Online (Sandbox Code Playgroud)
如何让asp-for输入标签帮助器生成像上面这样的驼峰案例名称,而不必使我的模型属性为camelCase?
在研究了@Bebben发布的代码及其提供的链接后,我继续深入研究Asp.Net Core源代码.我发现Asp.Net Core的设计者提供了一些可扩展性点,可用于实现更低的camelCase id和name值.
要做到这一点,我们需要IHtmlGenerator 通过创建一个继承自定义的类来实现我们自己的功能DefaultHtmlGenerator.然后在那个类上我们需要覆盖GenerateTextBox修复外壳的方法.或者我们可以覆盖GenerateInput方法来修复所有输入字段的外壳name和id属性值(不仅仅是输入文本字段),这是我选择做的.作为奖励,我还覆盖了GenerateLabel方法,因此标签的for属性也使用自定义套管指定值.
这是班级:
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Text.Encodings.Web;
namespace App.Web {
public class CustomHtmlGenerator : DefaultHtmlGenerator {
public CustomHtmlGenerator(
IAntiforgery antiforgery,
IOptions<MvcViewOptions> optionsAccessor,
IModelMetadataProvider metadataProvider,
IUrlHelperFactory urlHelperFactory,
HtmlEncoder htmlEncoder,
ClientValidatorCache clientValidatorCache) : base
(antiforgery, optionsAccessor, metadataProvider, urlHelperFactory,
htmlEncoder, clientValidatorCache) {
//Nothing to do
}
public CustomHtmlGenerator(
IAntiforgery antiforgery,
IOptions<MvcViewOptions> optionsAccessor,
IModelMetadataProvider metadataProvider,
IUrlHelperFactory urlHelperFactory,
HtmlEncoder htmlEncoder,
ClientValidatorCache clientValidatorCache,
ValidationHtmlAttributeProvider validationAttributeProvider) : base
(antiforgery, optionsAccessor, metadataProvider, urlHelperFactory, htmlEncoder,
clientValidatorCache, validationAttributeProvider) {
//Nothing to do
}
protected override TagBuilder GenerateInput(
ViewContext viewContext,
InputType inputType,
ModelExplorer modelExplorer,
string expression,
object value,
bool useViewData,
bool isChecked,
bool setId,
bool isExplicitValue,
string format,
IDictionary<string, object> htmlAttributes) {
expression = GetLowerCamelCase(expression);
return base.GenerateInput(viewContext, inputType, modelExplorer, expression, value, useViewData,
isChecked, setId, isExplicitValue, format, htmlAttributes);
}
public override TagBuilder GenerateLabel(
ViewContext viewContext,
ModelExplorer modelExplorer,
string expression,
string labelText,
object htmlAttributes) {
expression = GetLowerCamelCase(expression);
return base.GenerateLabel(viewContext, modelExplorer, expression, labelText, htmlAttributes);
}
private string GetLowerCamelCase(string text) {
if (!string.IsNullOrEmpty(text)) {
if (char.IsUpper(text[0])) {
return char.ToLower(text[0]) + text.Substring(1);
}
}
return text;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们有了我们的CustomHtmlGenerator类,我们需要在IoC容器中注册它来代替DefaultHtmlGenerator.我们可以ConfigureServices通过以下两行在Startup.cs 的方法中做到这一点:
//Replace DefaultHtmlGenerator with CustomHtmlGenerator
services.Remove<IHtmlGenerator, DefaultHtmlGenerator>();
services.AddTransient<IHtmlGenerator, CustomHtmlGenerator>();
Run Code Online (Sandbox Code Playgroud)
很酷.而且不仅有我们解决了id和name外壳问题上的输入字段,但通过实现自己的自定义IHtmlGenerator,并得到它的注册,我们已经打开了各种HTML定制的,可以做的门.
我开始非常欣赏围绕IoC构建的系统的强大功能,以及使用虚拟方法的默认类.在这种方法下轻松获得的定制水平真的非常惊人.
更新
@ Gup3rSuR4c指出我的services.Remove调用必须是一个未包含在框架中的扩展方法.我检查了,是的,这是真的.所以,这是该扩展方法的代码:
public static class IServiceCollectionExtensions {
public static void Remove<TServiceType, TImplementationType>(this IServiceCollection services) {
var serviceDescriptor = services.First(s => s.ServiceType == typeof(TServiceType) &&
s.ImplementationType == typeof(TImplementationType));
services.Remove(serviceDescriptor);
}
}
Run Code Online (Sandbox Code Playgroud)
最简单的方法是编写
<input asp-for="StartDate" name="startDate" />
Run Code Online (Sandbox Code Playgroud)
还是要在整个应用程序中以骆驼的方式完全自动生成它?
为此,您似乎必须在Microsoft.AspNetCore.Mvc.TagHelpers中实现自己的InputTagHelpers。
这是生成名称的方法:
private TagBuilder GenerateTextBox(ModelExplorer modelExplorer, string inputTypeHint, string inputType)
{
var format = Format;
if (string.IsNullOrEmpty(format))
{
format = GetFormat(modelExplorer, inputTypeHint, inputType);
}
var htmlAttributes = new Dictionary<string, object>
{
{ "type", inputType }
};
if (string.Equals(inputType, "file") && string.Equals(inputTypeHint, TemplateRenderer.IEnumerableOfIFormFileName))
{
htmlAttributes["multiple"] = "multiple";
}
return Generator.GenerateTextBox(
ViewContext,
modelExplorer,
For.Name,
value: modelExplorer.Model,
format: format,
htmlAttributes: htmlAttributes);
}
Run Code Online (Sandbox Code Playgroud)
(以上代码来自https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.TagHelpers/InputTagHelper.cs,Apache许可证,2.0版,.NET Foundation版权所有)
该行是“ For.Name”。该名称将发送到其他一些方法中,最后给出最终名称的方法是在一个静态类(Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.NameAndIdProvider)中,因此我们无法轻松插入任何内容。
| 归档时间: |
|
| 查看次数: |
1512 次 |
| 最近记录: |