Подтвердить что ты не робот

Альтернатива MVC6 для @Html.DisplayFor

MVC6 вводит тегов-помощников, которые лучше всего подходят для использования @Html.EditorFor и т.д. Однако я не нашел тегов-помощников, которые были бы альтернативой @Html.DisplayFor.

Конечно, я могу использовать переменную непосредственно на странице Razor, например @Model.BookingCode. Но это не позволяет контролировать форматирование.

С MVC6, какой концептуально правильный способ отображения значения свойства модели?

4b9b3361

Ответ 1

Вы можете создать свой собственный тег

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);
        }
    }
}

Добавьте его в поле зрения:

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

Ответ 2

@Html.DisplayFor все еще существует и может использоваться.

Различие между HtmlHelpers и TagHelpers заключается в том, что HtmlHelpers выбирает, какие html-элементы должны отображать для вас, тогда как TagHelpers работают с тегами html, которые вы добавляете, чтобы у вас был более полный контроль над тем, какой элемент html используется. У вас есть некоторый контроль над разметкой с использованием шаблонов с помощью HtmlHelpers, но у вас больше контроля с TagHelpers.

Итак, вы должны подумать с точки зрения того, что html-разметка я хочу обернуть этим свойством модели и добавить эту разметку вокруг самого свойства, используя @Model.Property с некоторой разметкой вокруг нее или продолжить использование DisplayFor, если вы предпочитаете хелпер.

Ответ 3

Я использую это как помощник тега отображения.

[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);
    }
}

Ответ 4

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
}