gpt4 book ai didi

asp.net-mvc - 如何在 MVC 运行时自定义 Display 和 Required 属性

转载 作者:行者123 更新时间:2023-12-05 01:20:56 25 4
gpt4 key购买 nike

我想在 Razor View 中有一个带有动态标签的模型,该模型在运行时设置,但基于使用字符串格式的资源文件中的字符串。

假设我有一个具有单个属性的简单模型

public class Simple
{
[Display(ResourceType = (typeof(Global)), Name = "UI_Property1")]
[Required(ErrorMessageResourceType = (typeof(Global)), ErrorMessageResourceName = "ERROR_Required")]
[StringLength(40, ErrorMessageResourceType = (typeof(Global)), ErrorMessageResourceName = "ERROR_MaxLength")]
public string Property1{ get; set; }
}

并且资源文件有以下字符串
UI_Property1       {0}
ERROR_Required Field {0} is required.
ERROR_MaxLength Maximum length of {0} is {1}

我想在 Razor View 中做这样的事情
@Html.LabelFor(m => m.Property1, "xyz", new { @class = "control-label col-sm-4" })

结果 View 会将字段标签显示为“xyz”,并且值“xyz”也将显示在从服务器模型验证返回的验证消息中。

我一直在寻找各种方法来做到这一点,但没有运气。我已经调查过重写 DisplayAttribute 但这是一个密封类。

我还查看了覆盖 DisplayName 属性,但这并没有通过所需的验证消息正确获取。另外,我不确定如何将动态文本注入(inject)到我认为需要在属性构造函数中完成的属性中。

我还看过编写自定义 DataAnnotationsModelMetadataProvider 但看不到使用它来实现我想要的方法。这可能是由于我缺乏编码技能。

'xyz' 字符串将来自 web.config 文件中的设置,不需要在 LabelFor 命令中注入(inject),但如果更有意义,可以在其他地方注入(inject)。

如果有人能告诉我如何实现这一目标,那就太好了。

最佳答案

我找到了这篇文章

Is it valid to replace DataAnnotationsModelMetadataProvider and manipulate the returned ModelMetadata

这使我找到了如下解决方案:

我在我的网络配置中添加了一个自定义部分

  <configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="labelTranslations" type="AttributeTesting.Config.LabelTranslatorSection" />
... other sections here
</configSections>

<labelTranslations>
<labels>
<add label=":Customer:" translateTo="Customer Name" />
<add label=":Portfolio:" translateTo="Portfolio Name" />
<add label=":Site:" translateTo="Site Name" />
</labels>
</labelTranslations>

处理自定义部分的类加载要翻译的标签
public class LabelElement : ConfigurationElement
{
private const string LABEL = "label";
private const string TRANSLATE_TO = "translateTo";

[ConfigurationProperty(LABEL, IsKey = true, IsRequired = true)]
public string Label
{
get { return (string)this[LABEL]; }
set { this[LABEL] = value; }
}

[ConfigurationProperty(TRANSLATE_TO, IsRequired = true)]
public string TranslateTo
{
get { return (string)this[TRANSLATE_TO]; }
set { this[TRANSLATE_TO] = value; }
}

}

[ConfigurationCollection(typeof(LabelElement))]
public class LabelElementCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new LabelElement();
}

protected override object GetElementKey(ConfigurationElement element)
{
return ((LabelElement)element).Label;
}

public LabelElement this[string key]
{
get
{
return this.OfType<LabelElement>().FirstOrDefault(item => item.Label == key);
}
}
}

public class LabelTranslatorSection : ConfigurationSection
{
private const string LABELS = "labels";

[ConfigurationProperty(LABELS, IsDefaultCollection = true)]
public LabelElementCollection Labels
{
get { return (LabelElementCollection)this[LABELS]; }
set { this[LABELS] = value; }
}
}

然后,翻译器使用自定义部分将给定标签翻译为翻译版本(如果存在),否则返回标签
public static class Translator
{
private readonly static LabelTranslatorSection config =
ConfigurationManager.GetSection("labelTranslations") as LabelTranslatorSection;

public static string Translate(string label)
{
return config.Labels[label] != null ? config.Labels[label].TranslateTo : label;
}
}

然后我编写了一个自定义元数据提供程序,它根据翻译版本修改显示名称
public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName)
{

// Call the base method and obtain a metadata object.
var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);

if (containerType != null)
{
// Obtain informations to query the translator.
//var objectName = containerType.FullName;
var displayName = metadata.GetDisplayName();

// Update the metadata from the translator
metadata.DisplayName = Translator.Translate(displayName);
}

return metadata;
}
}

之后一切正常,标签和验证消息都使用了翻译版本。我使用了标准的 LabelFor 助手,没有做任何修改。

资源文件看起来像这样
ERROR_MaxLength   {0} can be no more than {1} characters long   
ERROR_Required {0} is a required field
UI_CustomerName :Customer:
UI_PortfolioName :Portfolio:
UI_SiteName :Site:

关于asp.net-mvc - 如何在 MVC 运行时自定义 Display 和 Required 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33129382/

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