【发布时间】:2015-11-20 17:46:04
【问题描述】:
在 MVC 5 中,我可以通过创建自定义 Object.cshtml 来自定义通用编辑器模板。
但我在 MVC 6 beta8 中找不到这种行为。
问题:如何在 MVC 6 中自定义通用编辑器模板?
更新:
似乎这个功能是硬编码的。 DefaultEditorTemplates.cs
【问题讨论】:
标签: asp.net razor asp.net-core asp.net-core-mvc
在 MVC 5 中,我可以通过创建自定义 Object.cshtml 来自定义通用编辑器模板。
但我在 MVC 6 beta8 中找不到这种行为。
问题:如何在 MVC 6 中自定义通用编辑器模板?
更新:
似乎这个功能是硬编码的。 DefaultEditorTemplates.cs
【问题讨论】:
标签: asp.net razor asp.net-core asp.net-core-mvc
基于 DefaultEditorTemplates 类,我制作了我的 TagHelper。
也许对某人有用。
ModelTagHelper.cs
[HtmlTargetElement("div", Attributes = ForAttributeName)]
public class ModelTagHelper : TagHelper
{
protected const string ForAttributeName = "asp-for";
protected const string ObjectViewPath = "~/Views/Shared/Object.cshtml";
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
[HtmlAttributeName(ForAttributeName)]
public ModelExpression For { get; set; }
public override int Order => -1000;
protected object Model => For.Model;
protected IHtmlGenerator HtmlGenerator { get; }
protected IViewEngine ViewEngine { get; }
protected ITempDataProvider TempDataProvider { get; }
protected IHttpContextAccessor HttpContextAccessor { get; }
public ModelTagHelper(
ICompositeViewEngine viewEngine,
ITempDataProvider tempDataProvider,
IHttpContextAccessor httpContextAccessor,
IHtmlGenerator generator)
{
HtmlGenerator = generator;
ViewEngine = viewEngine;
TempDataProvider = tempDataProvider;
HttpContextAccessor = httpContextAccessor;
}
protected virtual ActionContext CreateActionContext() => new ActionContext(HttpContextAccessor.HttpContext, new RouteData(), new ActionDescriptor());
protected virtual ViewDataDictionary CreateViewDataDictionary() => new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
using (var sw = new StringWriter())
{
var viewDataDictionary = CreateViewDataDictionary();
viewDataDictionary.Model = Model;
var actionContext = CreateActionContext();
var viewResult = ViewEngine.FindPartialView(actionContext, ObjectViewPath);
if (!viewResult.Success)
{
throw new FileNotFoundException("Cannot find the file", ObjectViewPath);
}
var viewContext = new ViewContext(
actionContext,
viewResult.View,
viewDataDictionary,
new TempDataDictionary(HttpContextAccessor, TempDataProvider),
sw, new HtmlHelperOptions { ClientValidationEnabled = true });
viewResult.View.RenderAsync(viewContext).Wait();
sw.Flush();
output.Content.SetContent(new HtmlString(sw.ToString()));
}
}
}
Object.cshmtl
@using Microsoft.AspNet.Mvc.ViewFeatures
@{
var tplInfo = ViewContext.ViewData.TemplateInfo;
Func<ModelExplorer, TemplateInfo, bool> ShouldShow =
(modelExplorer, templateInfo) =>
modelExplorer.Metadata.ShowForEdit &&
!modelExplorer.Metadata.IsComplexType &&
!templateInfo.Visited(modelExplorer);
var properties = from property in ViewData.ModelExplorer.Properties
let propertyMetadata = property.Metadata
where ShouldShow(property, tplInfo)
select propertyMetadata;
}
@foreach (var propertyMetadata in properties)
{
if (propertyMetadata.HideSurroundingHtml)
{
@Html.Editor(propertyMetadata.PropertyName)
}
else
{
var label = Html.Label(propertyMetadata.PropertyName, labelText: null, htmlAttributes: null);
if (!string.IsNullOrEmpty(label.ToString()))
{
<div class="editor-label">
@label
</div>
}
<div class="editor-field">
@Html.Editor(propertyMetadata.PropertyName)
@Html.ValidationMessage(propertyMetadata.PropertyName)
</div>
}
}
MyView.cshtml
<div asp-for="@Model"></div>
【讨论】:
Asp.Net-5 带来了一个名为“TagHelpers”的新功能。
您可以在默认的 MVC6 共享 _Layout.cshtml 页面中看到它们的工作,其中的“环境”标签会根据运行时环境(开发、登台、生产等)产生不同的输出。
您将看到“Microsoft.AspNet.MVC.TagHelpers...”包加载到解决方案资源管理器的“参考”部分中的 DNX 4.5.1 和 DNX Core 5.0 框架部分中。
看起来 TagHelpers 的设计目的是替代“模板”。
在这里快速概览:Wildermuth
还有两篇更深入的文章:MSDN 和 MSDN Mag - 两篇文章
希望对你有所帮助。
【讨论】:
@Htmlhelpers 和 co。在 HTML 中。支持作为真正 XML 的 HTML。