2

我想在剃刀視圖中有一個動態標籤的模型,該模型在運行時設置,但基於使用字符串格式的資源文件中的字符串。如何在運行時自定義顯示和必需屬性在MVC

可以說,我有一個屬性

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視圖

@Html.LabelFor(m => m.Property1, "xyz", new { @class = "control-label col-sm-4" }) 

並且結果視圖將顯示字段標籤爲'xyz',值' xyz'也將顯示在從服務器模型驗證返回的驗證消息中。

我一直在尋找這樣做的各種方式沒有運氣。我調查覆蓋DisplayAttribute,但這是一個密封的類。

我也看着覆蓋DisplayName屬性,但是這並沒有得到適當的與所需的驗證信息。另外我不知道如何將動態文本插入到我認爲需要在屬性構造函數中完成的屬性中。

我也看過編寫自定義的DataAnnotationsModelMetadataProvider,但無法看到使用它來實現我想要的方式。這可能是由於我缺乏編碼技能。

'xyz'字符串將來自web.config文件中的一個設置,不需要在LabelFor命令中注入,但如果它更有意義,可以注入其他位置。

如果任何人都能給我線索,我該如何實現這一點,這將是偉大的。

回答

0

我發現這個職位

Is it valid to replace DataAnnotationsModelMetadataProvider and manipulate the returned ModelMetadata

這使我的解決方案如下:

我添加了一個自定義欄目到我的web配置

<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:  
相關問題