MVC6 alternative to @Html.DisplayFor

回眸只為那壹抹淺笑 提交于 2019-12-03 04:53:59

You can create your own tag helper

namespace MyDemo.TagHelpers
{
    [HtmlTargetElement("p", Attributes = ForAttributeName)]
    public class DisplayForTagHelper : TagHelper
    {
        private const string ForAttributeName = "asp-for";

        [HtmlAttributeName(ForAttributeName)]
        public ModelExpression For { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            var text = For.ModelExplorer.GetSimpleDisplayText();

            output.Content.SetContent(text);
        }
    }
}

Add use it in view:

<p asp-for="MyProperty" class="form-control-static"></p>

@Html.DisplayFor still exists and can still be used.

The difference between HtmlHelpers and TagHelpers is that HtmlHelpers choose which html elements to render for you whereas TagHelpers work with html tags that you add yourself so you have more full control over what html element is used. You do have some control over the markup using templates with HtmlHelpers but you have more control with TagHelpers.

So you should think in terms of what html markup do I want to wrap this model property in and add that markup around the property itself using @Model.Property with some markup around it or continue using DisplayFor if you prefer to let the helper decide.

I have been using this as a display tag helper.

[HtmlTargetElement("*", Attributes = ForAttributeName)]
public class DisplayForTagHelper : TagHelper
{
    private const string ForAttributeName = "asp-display-for";
    private readonly IHtmlHelper _html;

    public DisplayForTagHelper(IHtmlHelper html)
    {
        _html = html;
    }

    [HtmlAttributeName(ForAttributeName)]
    public ModelExpression Expression { get; set; }

    public IHtmlHelper Html
    {
        get
        {
            (_html as IViewContextAware)?.Contextualize(ViewContext);
            return _html;
        }
    }

    [HtmlAttributeNotBound]
    [ViewContext]
    public ViewContext ViewContext { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        if (context == null)
            throw new ArgumentNullException(nameof(context));
        if (output == null)
            throw new ArgumentNullException(nameof(output));

        var type = Expression.Metadata.UnderlyingOrModelType;
        if (type.IsPrimitive)
        {
            output.Content.SetContent(Expression.ModelExplorer.GetSimpleDisplayText());
        }
        // Special Case for Personal Use
        else if (typeof(Dictionary<string, string>).IsAssignableFrom(type))
        {
            output.Content.SetHtmlContent(Html?.Partial("Dictionary", Expression.ModelExplorer.Model));
        }
        else
        {
            var htmlContent = Html.GetHtmlContent(Expression);
            output.Content.SetHtmlContent(htmlContent);
        }
    }
}

public static class ModelExpressionExtensions
{
    public static IHtmlContent GetHtmlContent(this IHtmlHelper html, ModelExpression expression)
    {
        var ViewEngine = html.ViewContext.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
        var BufferScope = html.GetFieldValue<IViewBufferScope>();
        var htmlContent = new TemplateBuilder(ViewEngine, BufferScope, html.ViewContext, html.ViewContext.ViewData, expression.ModelExplorer, expression.Name, null, true, null).Build();
        return htmlContent;
    }

    public static TValue GetFieldValue<TValue>(this object instance)
    {
        var type = instance.GetType(); 
        var field = type.GetFields(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.FieldType));
        return (TValue)field?.GetValue(instance);
    }
}
try below code

public class movie
{
    public int ID { get; set; }
    [DisplayName("Movie Title")]
    public string Title { get; set; }
}
///////////////////////////////////////////////////

@model IEnumerable<MvcMovie.Models.Movie>

<h1>Show List Movies</h1>
<label asp-for="ToList()[0].Title">< /label>
@foreach (var movie in Model)
{
    @movie.Title
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!