DisplayAttribute.Description 특성 값을 어떻게 표시합니까?
다음과 같은 속성이있는 모델 클래스가 있습니다.
[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 } )
나는 받아 들인 대답 을 사용 하려고했지만 ModelMetadata.FromLambdaExpression더 이상 존재하지 않고 이동 했기 때문에 ASP.NET Core 1/2 (일명 MVC 6)에서 작동하지 않았습니다 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 Core 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)
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 : Bootstrap 4에서는 블록 수준 도움말 텍스트에 대한 클래스 form-text및 text-mutedv3 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 <span> elements with an <c>asp-description-for</c> attribute.
/// Adds an <c>id</c> attribute and sets the content of the <span> 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;
}
}
}
그리고 모든 Razor 뷰에서 태그 도우미를 사용할 수 있습니다. addTagHelper 지시문을 Views/_ViewImports.cshtml파일에 추가 합니다.
@addTagHelper "*, YourAssemblyName"
참고 1 : YourAssemblyName프로젝트의 어셈블리 이름으로 바꿉니다 .
참고 2 : 모든 태그 도우미에 대해이 작업을 한 번만 수행하면됩니다!
태그 도우미에 대한 자세한 내용은 https://docs.asp.net/en/latest/mvc/views/tag-helpers/intro.html을 참조하세요.
그게 다야! 새로운 태그 도우미로 재미있게 보내세요!
수락 된 답변 을 사용하는 방법을 궁금한 사람이 있다면
1- 솔루션 탐색기에서> 새 폴더 추가> 이름을 "Helpers"로 지정합니다 (예 :
2-) 새 클래스를 추가하고 이름을 "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- 모델 또는 viewModel에서 다음을 사용하십시오.
[Display(Name = "User Name", Description = "Enter your User Name")]
public string FullName { get; set; }
5- Razor보기에서 @model 뒤에 다음 줄을 입력합니다.
@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()
Description 속성 값을 제공하기 위해 모델을 반영하는 사용자 지정 도우미를 작성해야합니다.
@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>
Jakob Gade'a에 더해 훌륭한 답변 :
당신이 지원해야하는 경우 DescriptionAttribute대신의를 DisplayAttribute, 그의 위대한 솔루션은 우리가 MetadataProvider을 무시할 경우 여전히 작동합니다 :
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();
... 그리고 양식 레이블에 도구 설명으로 설명을 포함하려면 다음과 같이 태그 도우미를 추가하십시오.
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 <label> elements with an <c>asp-for</c> attribute.
/// Adds a <c>title</c> attribute to the <label> 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.
The beautiful part is that you don't need to touch your generated scaffolded views! Because this Tag Helper is targeting the asp-for attribute of the label element that is already there!
HANDL's answer, updated for ASP.NET Core 2.0
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);
}
}
You can always create your own custom extension like this:
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());
}
and can get it in view like this:
@HtmlExtension.ToolTipLabel(" "," ",true," "," "," ")
'IT TIP' 카테고리의 다른 글
| Windows 7 : DLL을 등록 할 수 없음-오류 코드 : 0X80004005 (0) | 2020.11.03 |
|---|---|
| AlarmManager에서 활성 PendingIntents 목록 가져 오기 (0) | 2020.11.03 |
| ArrayList 인쇄 (0) | 2020.11.03 |
| PHP에서 비트 마스크를 구현하는 방법은 무엇입니까? (0) | 2020.11.03 |
| ActionBar 위쪽 탐색은 onResume 대신 부모 활동을 다시 만듭니다. (0) | 2020.11.03 |