C# ASP.NET Core:Display属性(DataAnnotations)中的ShortName
在ASP.NET Core 1.1项目(VS 2017)中,我尝试使用C# ASP.NET Core:Display属性(DataAnnotations)中的ShortName,c#,asp.net-core,data-annotations,html-helper,asp.net-core-1.1,C#,Asp.net Core,Data Annotations,Html Helper,Asp.net Core 1.1,在ASP.NET Core 1.1项目(VS 2017)中,我尝试使用Display属性的ShortName属性,以便使用DisplayForHTML帮助程序: [Display(Name="Project Name", ShortName="Name", Description="The name of the project")] public string Name { get; set; } 我读到了这篇文章的描述。不幸的是,由于我不明白的原因,这对短名称不起作用 这是我尝试过的代码,
Display
属性的ShortName
属性,以便使用DisplayFor
HTML帮助程序:
[Display(Name="Project Name", ShortName="Name", Description="The name of the project")]
public string Name { get; set; }
我读到了这篇文章的描述
。不幸的是,由于我不明白的原因,这对短名称不起作用
这是我尝试过的代码,第一种方法似乎可以,但第二种方法无法编译,因此我想修复它:
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);
}
}
}
要使用此方法获取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;
var defaultMetadata=m as
Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata;
if(defaultMetadata!=null)
{
var displayAttribute=defaultMetadata.Attributes.Attributes
第()类
.FirstOrDefault();
if(displayAttribute!=null)
{
返回displayAttribute.ShortName;
}
}
返回m.DisplayName;
为了将其插入到您的助手中,我将稍微抽象出该方法,因为其中有一些重复的代码,因此您将得到一个私有方法,如下所示:
public static string DisplayShortNameFor<TModelItem, TResult>(
this IHtmlHelper<IEnumerable<TModelItem>> htmlHelper,
Expression<Func<TModelItem, TResult>> expression)
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;
});
}
private static IHtmlContent MetaDataFor(此IHtmlHelper html,
表情表情,
Func属性)
{
如果(html==null)抛出新的ArgumentNullException(nameof(html));
if(expression==null)抛出新的ArgumentNullException(nameof(expression));
var modeleexplorer=ExpressionMetadataProvider.FromLambdaExpression(expression,html.ViewData,html.MetadataProvider);
如果(modelExplorer==null)抛出新的InvalidOperationException($”未能为{ExpressionHelper.GetExpressionText(expression)}获取模型资源管理器);
返回新的HtmlString(属性(modelExplorer.Metadata));
}
您的两种公开方法如下:
public static string DisplayShortNameFor<TModelItem, TResult>(
this IHtmlHelper<IEnumerable<TModelItem>> htmlHelper,
Expression<Func<TModelItem, TResult>> expression)
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;
});
}
public static IHtmlContent description for(此IHtmlHelper html,表达式)
{
返回html.MetaDataFor(表达式,m=>m.Description);
}
公共静态IHtmlContent缩写(此IHtmlHelper html,
表达式(表达式)
{
返回html.MetaDataFor(表达式,m=>
{
var defaultMetadata=m as
Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata;
if(defaultMetadata!=null)
{
var displayAttribute=defaultMetadata.Attributes.Attributes
第()类
.FirstOrDefault();
if(displayAttribute!=null)
{
返回displayAttribute.ShortName;
}
}
//如果属性没有DisplayAttribute,则返回默认值
返回m.DisplayName;
});
}
要使用此方法获取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;
var defaultMetadata=m as
Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata;
if(defaultMetadata!=null)
{
var displayAttribute=defaultMetadata.Attributes.Attributes
第()类
.FirstOrDefault();
if(displayAttribute!=null)
{
返回displayAttribute.ShortName;
}
}
返回m.DisplayName;
为了将其插入到您的助手中,我将稍微抽象出该方法,因为其中有一些重复的代码,因此您将得到一个私有方法,如下所示:
public static string DisplayShortNameFor<TModelItem, TResult>(
this IHtmlHelper<IEnumerable<TModelItem>> htmlHelper,
Expression<Func<TModelItem, TResult>> expression)
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;
});
}
private static IHtmlContent MetaDataFor(此IHtmlHelper html,
表情表情,
Func属性)
{
如果(html==null)抛出新的ArgumentNullException(nameof(html));
if(expression==null)抛出新的ArgumentNullException(nameof(expression));
var modeleexplorer=ExpressionMetadataProvider.FromLambdaExpression(expression,html.ViewData,html.MetadataProvider);
如果(modelExplorer==null)抛出新的InvalidOperationException($”未能为{ExpressionHelper.GetExpressionText(expression)}获取模型资源管理器);
返回新的HtmlString(属性(modelExplorer.Metadata));
}
您的两种公开方法如下:
public static string DisplayShortNameFor<TModelItem, TResult>(
this IHtmlHelper<IEnumerable<TModelItem>> htmlHelper,
Expression<Func<TModelItem, TResult>> expression)
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;
});
}
public static IHtmlContent description for(此IHtmlHelper html,表达式)
{
返回html.MetaDataFor(表达式,m=>m.Description);
}
公共静态IHtmlContent缩写(此IHtmlHelper html,
表达式(表达式)
{
返回html.MetaDataFor(表达式,m=>
{
var defaultMetadata=m as
Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata;
if(defaultMetadata!=null)
{
var displayAttribute=defaultMetadata.Attributes.Attributes
第()类
.FirstOrDefault();
if(displayAttribute!=null)
{
返回displayAttribute.ShortName;
}
}
//如果属性没有DisplayAttribute,则返回默认值
返回m.DisplayName;
});
}
是否可以更新签名以使其与收藏一起使用?像公共静态字符串DisplayShortNameFor(这个IHtmlHelper-htmlHelper,Expression-Expression)
,因为如OP中所述,视图不会消化集合您不需要它,您可以在视图中这样调用它:@Html.ShortNameFor(m=>m.First().SomeProperty)
是,但如果没有项目,我将得到错误。。。这是对集合的又一次调用,我的意思是,实际的ASP.NET代码中包含集合,而不是成员。对于IEnumerable
的情况,这样做要复杂得多,我将把它作为一个练习留给您,因为上面的选项工作得非常好