gpt4 book ai didi

c# - ASP.NET 核心 : ShortName in the Display attribute (DataAnnotations)

转载 作者:太空宇宙 更新时间:2023-11-03 22:56:16 24 4
gpt4 key购买 nike

在 ASP .NET Core 1.1 项目(VS 2017)中,我尝试使用 Display 属性的 ShortName 属性,以便使用 DisplayFor HTML Helper:

[Display(Name="Project Name", ShortName="Name", Description="The name of the project")]
public string Name { get; set; }

我读了the following answer这对 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);
}
}
}

不仅如此,回顾 MS code of the DisplayNameFor

方法的签名应该像这样改变:

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)方法:

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)方法是这样的:

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

关于c# - ASP.NET 核心 : ShortName in the Display attribute (DataAnnotations),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45234670/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com