programing

DisplayAttribute를 표시하려면 어떻게 해야 합니다.설명 특성 값?

firstcheck 2023. 6. 22. 23:52
반응형

DisplayAttribute를 표시하려면 어떻게 해야 합니다.설명 특성 값?

다음과 같은 속성을 가진 모델 클래스가 있습니다.

[Display(Name = "Phone", Description="Hello World!")]
public string Phone1 { get; set; }

레이블을 표시하고 내 보기에 입력할 텍스트 상자를 렌더링하는 것은 매우 쉽습니다.

@Html.LabelFor(model => model.Organization.Phone1)
@Html.EditorFor(model => model.Organization.Phone1)
@Html.ValidationMessageFor(model => model.Organization.Phone1)

그러나 설명 주석 속성(즉, "Hello World!")의 값을 렌더링하려면 어떻게 해야 합니까?

저는 결국 이런 도우미를 만나게 되었습니다.

using System;
using System.Linq.Expressions;
using System.Web.Mvc;

public static class MvcHtmlHelpers
{
    public static MvcHtmlString DescriptionFor<TModel, TValue>(this HtmlHelper<TModel> self, Expression<Func<TModel, TValue>> expression)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, self.ViewData);
        var description = metadata.Description;

        return MvcHtmlString.Create(string.Format(@"<span>{0}</span>", description));
    }
}

저를 올바른 방향으로 이끌어주신 분들께 감사드립니다.:)

양식의 필드에 대한 시각적 힌트를 표시하는 방법에 대한 이 문서의 기술을 사용하여 다음을 통해 값에 액세스할 수 있습니다.

@Html.TextBoxFor( 
        model => model.Email , 
        new { title = ModelMetadata.FromLambdaExpression<RegisterModel , string>( 
            model => model.Email , ViewData ).Description } )  

ASP.NET MVC Core에서 새로운 태그 도우미를 사용할 수 있습니다. 그러면 HTML이...HTML :)

다음과 같이:

<div class="form-group row">
    <label asp-for="Name" class="col-md-2 form-control-label"></label>
    <div class="col-md-10">
        <input asp-for="Name" class="form-control" aria-describedby="Name-description" />
        <span asp-description-for="Name" class="form-text text-muted" />
        <span asp-validation-for="Name" class="text-danger" />
    </div>
</div>

참고 1: 다음을 사용할 수 있습니다.aria-describedby입력 요소에서 해당 ID의 속성은 스팬 요소에서 자동으로 생성됩니다.asp-description-for기여하다.

2:4에서 는 2: 부트에랩 4서는클입니다.form-text그리고.text-muted합니다.help-block블록 수준 도움말 텍스트에 대한 클래스입니다.

이 마법을 사용하려면 새 태그 도우미를 만들기만 하면 됩니다.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;

/// <summary>
/// <see cref="ITagHelper"/> implementation targeting &lt;span&gt; elements with an <c>asp-description-for</c> attribute.
/// Adds an <c>id</c> attribute and sets the content of the &lt;span&gt; with the Description property from the model data annotation DisplayAttribute.
/// </summary>
[HtmlTargetElement("span", Attributes = DescriptionForAttributeName)]
public class SpanDescriptionTagHelper : TagHelper
{
    private const string DescriptionForAttributeName = "asp-description-for";

    /// <summary>
    /// Creates a new <see cref="SpanDescriptionTagHelper"/>.
    /// </summary>
    /// <param name="generator">The <see cref="IHtmlGenerator"/>.</param>
    public SpanDescriptionTagHelper(IHtmlGenerator generator)
    {
        Generator = generator;
    }

    /// <inheritdoc />
    public override int Order
    {
        get
        {
            return -1000;
        }
    }

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

    protected IHtmlGenerator Generator { get; }

    /// <summary>
    /// An expression to be evaluated against the current model.
    /// </summary>
    [HtmlAttributeName(DescriptionForAttributeName)]
    public ModelExpression DescriptionFor { get; set; }

    /// <inheritdoc />
    /// <remarks>Does nothing if <see cref="DescriptionFor"/> is <c>null</c>.</remarks>
    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

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

        var metadata = DescriptionFor.Metadata;

        if (metadata == null)
        {
            throw new InvalidOperationException(string.Format("No provided metadata ({0})", DescriptionForAttributeName));
        }

        output.Attributes.SetAttribute("id", metadata.PropertyName + "-description");

        if( !string.IsNullOrWhiteSpace( metadata.Description))
        {
            output.Content.SetContent(metadata.Description);
            output.TagMode = TagMode.StartTagAndEndTag;
        }
    }
}

또한 모든 레이저 뷰에서 태그 도우미를 사용할 수 있습니다.를 addTagHelper 명령어에 합니다.Views/_ViewImports.cshtml파일 이름:

@addTagHelper "*, YourAssemblyName"

1: 1: 교체YourAssemblyName프로젝트의 어셈블리 이름을 사용합니다.

참고 2: 모든 태그 도우미를 위해 이 작업을 한 번만 수행하면 됩니다!

태그 도우미에 대한 자세한 내용은 여기에서 확인하십시오. https://docs.asp.net/en/latest/mvc/views/tag-helpers/intro.html

다 됐다! 더 이상 어쩔 수 없다!새로운 태그 도우미와 함께 즐거운 시간 보내세요!

수락된 답변을 사용하려고 했지만 ASP.NET Core 1/2(MVC 6)에 대해 작동하지 않았습니다.ModelMetadata.FromLambdaExpression 더이존재이않습니다었으로 되었습니다.ExpressionMetadataProvider(사용법도 약간 변경되었습니다.)

ASP.NET Core 1.1 2에서 사용할 수 있는 업데이트된 확장 방법입니다.

using System;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;

public static class HtmlExtensions
{
    public static IHtmlContent DescriptionFor<TModel, TValue>(this IHtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        if (html == null) throw new ArgumentNullException(nameof(html));
        if (expression == null) throw new ArgumentNullException(nameof(expression));

        var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider);
        if (modelExplorer == null) throw new InvalidOperationException($"Failed to get model explorer for {ExpressionHelper.GetExpressionText(expression)}");

        return new HtmlString(modelExplorer.Metadata.Description);
    }
}

ASP.NET 코어 1

1의 작동하지만 네임스페이스 ASP.NET Core 1이 합니다.usings:

using System;
using System.Linq.Expressions;
using Microsoft.AspNet.Html.Abstractions;
using Microsoft.AspNet.Mvc.ViewFeatures;

사용.

@Html.DescriptionFor(model => model.Phone1)

승인된 답변을 사용하는 방법을 궁금해하는 사람이 있을 경우

의 솔루션> 새 >이름 지정"1 - 탐에서색기추가미우도새지더폴정이름어>예를솔션루helpers" "Helperers" 를 들어, "Helpers"
클래스를 합니다. 를 들어, "을 지정합니다. 2 - " 새클를추가다니합스래다추▁2니가▁-합새,를래▁2"▁for▁examplecustom스클" 예를 들어 "CustomHtmlHelpers"로 이름 지정합니다.
3 - 코드를 붙여넣습니다.

public static class MvcHtmlHelpers
{
    public static string DescriptionFor<TModel, TValue>(this HtmlHelper<TModel> self, Expression<Func<TModel, TValue>> expression)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, self.ViewData);
        var description = metadata.Description;

        return string.IsNullOrWhiteSpace(description) ? "" : description;
    }
}

뷰 4- 모델또 모사용는경우하을델뷰는::

[Display(Name = "User Name", Description = "Enter your User Name")]
public string FullName { get; set; }

5 - 레이저 보기에서 @ 모델 뒤에 이 라인을 입력합니다.

@using YOUR_PROJECT.Helpers 

같이 합니다. 6 - 설명은 다음과 같습니다.

@Html.DescriptionFor(m => m.FullName) 

7- 설명을 사용하여 입력 자리 표시자에 텍스트를 표시할 수 있습니다.

@Html.DisplayNameFor(m => m.FullName)
@Html.TextBoxFor(m => m.FullName, new { @class = "form-control", placeholder = Html.DescriptionFor(m => m.FullName) })

감사해요.

var attrib = (DisplayAttribute)Attribute.GetCustomAttribute(
             member, typeof(DisplayAttribute));
var desc = attrib == null ? "" : attrib.GetDescription()

다음은 ASP.NET Core 3.1 및 5의 업데이트된 버전입니다.

public static class HtmlExtensions
{
    public static IHtmlContent DescriptionFor<TModel, TValue>(this IHtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        if (html == null) throw new ArgumentNullException(nameof(html));
        if (expression == null) throw new ArgumentNullException(nameof(expression));

        var expressionProvider = html.ViewContext?.HttpContext?.RequestServices?.GetService<ModelExpressionProvider>()
            ?? new ModelExpressionProvider(html.MetadataProvider);
        var modelExpression = expressionProvider.CreateModelExpression(html.ViewData, expression);

        return new HtmlString(modelExpression.Metadata.Description);
    }
}

우리는 경유해야 합니다.ModelExpressionProvider이제는ExpressionMetadataProvider내부로 표시됩니다.

ModelExpressionProvider.CreateModelExpression()호출들ExpressionMetadataProvider.FromLambdaExpression()어쨌든 내부적으로는:

https://github.com/aspnet/Mvc/blob/04ce6cae44fb0cb11470c21769d41e3f8088e8aa/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ModelExpressionProvider.cs#L42

@ViewData.ModelMetadata.Properties
   .Where(m => m.PropertyName == "Phone1").FirstOrDefault().Description

그래서, 만약 당신이 부트스트랩을 사용한다면, 다음과 같은 것.

<div class="form-group col-sm-6">
   @Html.LabelFor(m => m.Organization.Phone1)
   @Html.EditorFor(m => m.Organization.Phone1)
   <p class="help-block">
      @ViewData.ModelMetadata.Properties
         .Where(m => m.PropertyName == "DayCount").FirstOrDefault().Description
   </p>
</div>

모델에 반영되는 사용자 지정 도우미를 작성하여 Description 특성 값을 제공해야 합니다.

...양식 레이블에 도구 설명으로 설명을 추가하려면 다음과 같은 태그 도우미를 추가합니다.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;

/// <summary>
/// <see cref="ITagHelper"/> implementation targeting &lt;label&gt; elements with an <c>asp-for</c> attribute.
/// Adds a <c>title</c> attribute to the &lt;label&gt; with the Description property from the model data annotation DisplayAttribute.
/// </summary>
[HtmlTargetElement("label", Attributes = ForAttributeName)]
public class LabelTitleTagHelper : TagHelper
{
    private const string ForAttributeName = "asp-for";

    /// <summary>
    /// Creates a new <see cref="LabelTitleTagHelper"/>.
    /// </summary>
    /// <param name="generator">The <see cref="IHtmlGenerator"/>.</param>
    public LabelTitleTagHelper(IHtmlGenerator generator)
    {
        Generator = generator;
    }

    /// <inheritdoc />
    public override int Order
    {
        get
        {
            return -1000;
        }
    }

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

    protected IHtmlGenerator Generator { get; }

    /// <summary>
    /// An expression to be evaluated against the current model.
    /// </summary>
    [HtmlAttributeName(ForAttributeName)]
    public ModelExpression TitleFor { get; set; }

    /// <inheritdoc />
    /// <remarks>Does nothing if <see cref="TitleFor"/> is <c>null</c>.</remarks>
    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

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

        var metadata = TitleFor.Metadata;

        if (metadata == null)
        {
            throw new InvalidOperationException(string.Format("No provided metadata ({0})", ForAttributeName));
        }

        if (!string.IsNullOrWhiteSpace(metadata.Description))
            output.Attributes.SetAttribute("title", metadata.Description);
    }
}

그러면 새로운 데이터가 생성됩니다.title의 속성Description모델의 데이터 주석 속성DisplayAttribute.

아름다운 부분은 생성된 비계 뷰를 터치할 필요가 없다는 것입니다!이 태그 도우미는 다음을 대상으로 하기 때문입니다.asp-for의 속성label이미 존재하는 요소!

Jakob Gade' 이외에도 훌륭한 답변이 있습니다.

지원이 필요한 경우DescriptionAttribute대신에DisplayAttributeMetadataProvider를 오버라이드해도 그의 훌륭한 솔루션은 여전히 작동합니다.

public class ExtendedModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(IEnumerable<System.Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
    {
        //Possible Multiple Enumerations on IEnumerable fix
        var attributeList = attributes as IList<System.Attribute> ?? attributes.ToList();

        //Default behavior
        var data = base.CreateMetadata(attributeList, containerType, modelAccessor, modelType, propertyName);

        //Bind DescriptionAttribute
        var description = attributeList.SingleOrDefault(a => typeof(DescriptionAttribute) == a.GetType());
        if (description != null)
        {
            data.Description = ((DescriptionAttribute)description).Description;
        }

        return data;
    }
}

이것은 에 등록해야 합니다.Application_Start메소드 인Global.asax.cs:

ModelMetadataProviders.Current = new ExtendedModelMetadataProvider();

ASP.NET Core 2.0용으로 업데이트된 HANDL의 답변

using System;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;

public static class HtmlExtensions
{
    public static IHtmlContent DescriptionFor<TModel, TValue>(this IHtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        if (html == null) throw new ArgumentNullException(nameof(html));
        if (expression == null) throw new ArgumentNullException(nameof(expression));

        var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider);
        if (modelExplorer == null) throw new InvalidOperationException($"Failed to get model explorer for {ExpressionHelper.GetExpressionText(expression)}");

        return new HtmlString(modelExplorer.Metadata.Description);
    }
}

항상 다음과 같은 사용자 정의 확장을 생성할 수 있습니다.

    public static MvcHtmlString ToolTipLabel (string resourceKey, string text, bool isRequired, string labelFor = "", string labelId = "",string className="")
    {
        string tooltip = string.Empty;

        StringBuilder sb = new StringBuilder();

        if (!string.IsNullOrEmpty(resourceKey))
        {
            var resources = GetAllResourceValues();

            if (resources.ContainsKey(resourceKey))
            {
                tooltip = resources[resourceKey].Value;
            }
        }

        sb.Append("<label");

        if (!string.IsNullOrEmpty(labelFor))
        {
            sb.AppendFormat(" for=\"{0}\"", labelFor);
        }

        if (!string.IsNullOrEmpty(labelId))
        {
            sb.AppendFormat(" Id=\"{0}\"", labelId);
        }

        if (!string.IsNullOrEmpty(className))
        {
            sb.AppendFormat(" class=\"{0}\"", className);
        }

        if (!string.IsNullOrEmpty(tooltip))
        {

            sb.AppendFormat(" data-toggle='tooltip' data-placement='auto left' title=\"{0}\"",tooltip);

        }
        if (isRequired)
        {
            sb.AppendFormat("><em class='required'>*</em> {0} </label></br>", text);
        }
        else
        {
            sb.AppendFormat(">{0}</label></br>", text);
        }
        return MvcHtmlString.Create(sb.ToString());
    }

다음과 같이 표시할 수 있습니다.

@HtmlExtension.ToolTipLabel(" "," ",true," "," "," ")

언급URL : https://stackoverflow.com/questions/6578495/how-do-i-display-the-displayattribute-description-attribute-value

반응형