在ViewDate.ModelMetaData.Properties中过滤导航属性

时间:2015-05-19 04:10:14

标签: asp.net-mvc razor mvc-editor-templates

我正在为我的课程创建自定义Editor Templates。我想过滤所有导航属性。无论如何不使用我的属性的命名约定来实现这一点吗?

我的部分视图如下所示:

@foreach (var property in ViewData.ModelMetadata.Properties)
{
    <div class="form-group form-inline">
        <div class="col-xs-5">
            @if (property.PropertyName.StartsWith("Z") || 
                property.PropertyName.Equals("thename", StringComparison.CurrentCultureIgnoreCase)
                ){
                continue;
            }
            @Html.Label(property.DisplayName)
            @Html.TextBox(property.PropertyName)
        </div>
        <div class="col-xs-5">

        </div>
    </div>
}

2 个答案:

答案 0 :(得分:1)

尝试使用bool标志来显示。如果该标志设置为“显示”,则使用标签和文本框显示该属性。

答案 1 :(得分:1)

我建议使用的方法是在模型上使用自定义属性(POCO)。使用该属性标记特殊属性。在进入循环之前,您可以使用反射来获取Dictionary<string, customAttribute>,其中string是模型上属性的名称,customAttribute是应用于类的自定义属性(检查null处理未应用自定义属性的属性。我附上了一个演示这些概念的LinqPad脚本,你会看到很好的视觉效果来看看发生了什么。

void Main()
{

    var obj = new MyCustomClass();
    var tModel = obj.GetType(); /*in your case this will probably be ModelMetadata.ModelType as below */
    //var tModel = ViewData.ModelMetadata.ModelType;

    var pAttributes = tModel
        .GetProperties() /*modify the parameter to determine whether you want public fields as well etc*/
        .ToDictionary(p =>
            p.Name,
            p => ((MyCustomAttribute)p.GetCustomAttribute(typeof(MyCustomAttribute)))
        );

    pAttributes.Dump();

    /*I'm using this to mimic your ViewData.ModelMetadata.Properties */
    var modelProperties = new[] { 
        new { PropertyName = "Age" }, 
        new { PropertyName = "Name" },
        new { PropertyName = "Height" },
        new { PropertyName = "Area" }
    }.ToList();

    foreach (var property in modelProperties)
    {
        if (pAttributes.ContainsKey(property.PropertyName) && (pAttributes[property.PropertyName]?.HasSpecialTreatment ?? false))
            Console.WriteLine("I am special: " + property.PropertyName);
        else
            Console.WriteLine(property.PropertyName);

    }

}

// Define other methods and classes here
public class MyCustomClass
{
    [MyCustomAttribute(HasSpecialTreatment = true)]
    public string Name { get; set; }
    [MyCustomAttribute(HasSpecialTreatment = false)]
    public int Age { get; set; }
    [MyCustomAttribute(HasSpecialTreatment = true)]
    public int Height { get; set; }
    public int Length { get; set; }
    public int Area { get; set; }
}

public class MyCustomAttribute : Attribute
{
    public bool HasSpecialTreatment = false;
}

这种方法的缺点是它依赖于反射,我会更早地使用这种方法来生成模板,而不是每次页面执行时动态执行。

您使用的是哪个版本的MVC?更好的方法是使用ModelMetaDataProvider或IDisplayMetadataProvider,具体取决于MVC版本,以便在管道的早期提供元数据,并简化View页面中的编程。