![](/img/trans.png)
[英]ASP .Net Core 3.0 ShortName in the Display Attribute (DataAnnotations)
[英]ASP.NET Core: ShortName in the Display attribute (DataAnnotations)
在ASP .NET Core 1.1項目(VS 2017)中,我嘗試使用Display
屬性的ShortName
attrubute以使用DisplayFor
HTML Helper:
[Display(Name="Project Name", ShortName="Name", Description="The name of the project")]
public string Name { get; set; }
我閱讀了以下答案 ,它為Description
了技巧。 不幸的是,由於某種原因我不明白,這對ShortName
不起作用。
有我試過的代碼,第一種方法似乎沒問題,但第二種方法沒有編譯,所以我想修復它:
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using System;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using System.Linq.Expressions;
using System.Reflection;
namespace MyProject.Helpers
{
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)}");
//////// Description is OK
return new HtmlString(modelExplorer.Metadata.Description);
}
public static IHtmlContent ShortNameFor<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., html.MetadataProvider);
if (modelExplorer == null) throw new InvalidOperationException($"Failed to get model explorer for {ExpressionHelper.GetExpressionText(expression)}");
//////// ShortName DOES NOT EXIST !!!!!!!!!!!!!!!!
return new HtmlString(modelExplorer.Metadata.ShortName);
}
}
}
更重要的是,查看DisplayNameFor的MS代碼
方法的簽名應該改變為這樣的:
public static string DisplayShortNameFor<TModelItem, TResult>(
this IHtmlHelper<IEnumerable<TModelItem>> htmlHelper,
Expression<Func<TModelItem, TResult>> expression)
並不是
public static IHtmlContent ShortNameFor<TModel, TValue>(
this IHtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression)
更新
對於我試過的舊簽名
public static string DisplayShortNameFor<TModel, TValue>(this IHtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
string shortNameValue = string.Empty;
var prop = expression.Body as MemberExpression;
if (prop != null)
{
var DisplayAttrib = prop.Member.GetCustomAttributes<DisplayAttribute>(false).FirstOrDefault();
if (DisplayAttrib != null)
shortNameValue = DisplayAttrib.ShortName;
}
return shortNameValue;
}
但實際上我無法運行它因為不在View中編譯,因為它是一個IEnumerable
@using MyProject.Helpers
@model IEnumerable<MyProject.Models.Record> <!--<<< IEnumerable to display a collection -->
@Html.DisplayShortNameFor(model => model.Name)
所以我需要這樣做
// for my method shortname I need to use FirstOfDefault...
@Html.DisplayShortNameFor(model => model.FirstOrDefault().Name)
// but for ASP.NET DisplayName works
@Html.DisplayNameFor(model => model.Date)
要使用此方法獲取ShortName
屬性,您需要手動提取Display
屬性,因為它不是默認元數據的一部分。 例如,像這樣的東西將起作用:
var defaultMetadata = m as
Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata;
if(defaultMetadata != null)
{
var displayAttribute = defaultMetadata.Attributes.Attributes
.OfType<DisplayAttribute>()
.FirstOrDefault();
if(displayAttribute != null)
{
return displayAttribute.ShortName;
}
}
return m.DisplayName;
為了將它插入你的幫助器,我會略微抽象掉這個方法,因為那里有一些重復的代碼,所以你最終會得到一個像這樣的私有方法:
private static IHtmlContent MetaDataFor<TModel, TValue>(this IHtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression,
Func<ModelMetadata, string> property)
{
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(property(modelExplorer.Metadata));
}
你的兩個公共方法是這樣的:
public static IHtmlContent DescriptionFor<TModel, TValue>(this IHtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
return html.MetaDataFor(expression, m => m.Description);
}
public static IHtmlContent ShortNameFor<TModel, TValue>(this IHtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression)
{
return html.MetaDataFor(expression, m =>
{
var defaultMetadata = m as
Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata;
if(defaultMetadata != null)
{
var displayAttribute = defaultMetadata.Attributes.Attributes
.OfType<DisplayAttribute>()
.FirstOrDefault();
if(displayAttribute != null)
{
return displayAttribute.ShortName;
}
}
//Return a default value if the property doesn't have a DisplayAttribute
return m.DisplayName;
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.