自定义HtmlHelper用于更改标签

时间:2012-10-05 10:42:49

标签: asp.net-mvc entity-framework razor asp.net-mvc-4

我想提供一种方法来更改与控件相关联的标签,这些控件将通过查找到sql表在页面上呈现。

理想情况下,我想注入元数据显示字段,然后使用帮助程序在页面上呈现。

@Html.LabelFor(m => m.city)

由于这需要在运行时进行sql查找,所以我不能只是在设计时更改类脚手架tt模板以在displayname注释上加盖标记。

我想到了3种可能的方法。

  1. 重写我想要使用的所有html.helpers。问题是您需要在进行更改之前复制现有帮助程序的所有功能。

  2. 编写自定义数据注释并将其标记在类中的每个属性上,即

    [MyCustomNameAttribute] 公共字符串城市{get;组; }

    然后希望在MyCustomNameAttribute类中我可以找到我所指的linq字段,对metadatamodel的引用和使用这些的数据库上下文我可以根据用户配置的潜在名称自定义来检索和替换DisplayName。我试图这样做,但无法找出[Display(Name =“city”)]注释在后台如何工作。

  3. 修改实体模型支持代码,将名称注入metadatamodel。

  4. 有没有人有上述经验?

    干杯 添

1 个答案:

答案 0 :(得分:1)

您必须通过扩展ModelMetaDataProvider来创建自定义DataAnnotationsModelMetadataProvider

public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(
        IEnumerable<Attribute> attributes,
        Type containerType,
        Func<object> modelAccessor,
        Type modelType,
        string propertyName)
    {
        var meta = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);

               if(meta.DisplayName == null)
               {
                 // TO DO read the display value from database and assign here
                 meta.DisplayName = .. 
               }

        return meta;
    }
}

然后你必须在Global.asax.cs中设置它

protected void Application_Start()
{
   RegisterRoutes(RouteTable.Routes);
   ModelMetadataProviders.Current = new CustomModelMetadataProvider();
}

我假设您只想从db设置显示名称,但是假设您要从db加载完整的modelmetadata,那么我建议您通过实现抽象类{{来创建自定义ModelMetadataProvider 1}}。

每次访问数据库绝对不是一个好主意,所以我们必须为一些缓存策略进行锻炼。

我们必须为每个新的ModelMetadataProvider(我猜)点击数据库并读取容器的元数据信息及其所有属性,并将密钥存储在缓存中containerType(这可能是一项艰巨的工作。)