Asp.net mvc 筛选ViewDate.ModelMetaData.Properties中的导航属性

Asp.net mvc 筛选ViewDate.ModelMetaData.Properties中的导航属性,asp.net-mvc,razor,mvc-editor-templates,Asp.net Mvc,Razor,Mvc Editor Templates,我正在为我的类创建自定义的编辑器模板。我想筛选所有导航属性。在不使用我的属性命名约定的情况下,是否可以实现这一点 我的部分观点如下: @foreach (var property in ViewData.ModelMetadata.Properties) { <div class="form-group form-inline"> <div class="col-xs-5"> @if (property.PropertyNa

我正在为我的类创建自定义的
编辑器模板。我想筛选所有导航属性。在不使用我的属性命名约定的情况下,是否可以实现这一点

我的部分观点如下:

@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>
}
@foreach(ViewData.ModelMetadata.Properties中的var属性)
{
@if(property.PropertyName.StartsWith(“Z”)||
property.PropertyName.Equals(“thename”,StringComparison.CurrentCultureIgnoreCase)
){
继续;
}
@Html.Label(property.DisplayName)
@Html.TextBox(property.PropertyName)
}

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

我建议使用的方法是在模型(POCO)上使用自定义属性。使用该属性标记特殊属性。在进入循环之前,您可以使用反射获取
字典
,其中
字符串
是模型上属性的名称,
自定义属性
是应用于类的自定义属性(检查
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版本),以便在管道的早期提供元数据,并简化视图页面中的编程