ASP.NET vNext。总编辑模板

时间:2015-11-20 17:46:04

标签: asp.net razor asp.net-core asp.net-core-mvc

在MVC 5中,我可以通过创建自定义Object.cshtml来自定义通用编辑器模板。

但我在MVC 6 beta8中找不到这样的行为。

问题:如何在MVC 6中自定义通用编辑器模板?

更新:

似乎此功能已被编码。 DefaultEditorTemplates.cs

2 个答案:

答案 0 :(得分:2)

基于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>

答案 1 :(得分:0)

Asp.Net-5带来了一项名为“TagHelpers”的新功能。

您可以在默认的MVC6共享_Layout.cshtml页面中看到它们与“环境”标记一起工作,这些标记根据运行时环境产生不同的输出 - 开发,分段,生产等。

您将在解决方案资源管理器的“参考”部分的DNX 4.5.1和DNX Core 5.0框架部分中看到“Microsoft.AspNet.MVC.TagHelpers ...”包。

看起来TagHelpers被设计为“模板”的替代品。

此处快速概述:Wildermuth

更深入的两篇文章:MSDNMSDN Mag - 2篇文章

希望能帮到你。