C# 如何使用foreach将属性从模型中获取到视图中?

C# 如何使用foreach将属性从模型中获取到视图中?,c#,asp.net-mvc,razor,ienumerable,C#,Asp.net Mvc,Razor,Ienumerable,如何使用foreach将属性从模型中获取到视图中 我知道我可以使用@Html.EditorFor(model=>model.ID),但在我的例子中,这是不可能的,因为我对不同的模型使用一个视图(从基本模型继承) 型号: public class MyModel : IEnumerable { private PropertyInfo[] propertys { get { if (propertys != null)

如何使用foreach将属性从模型中获取到视图中

我知道我可以使用
@Html.EditorFor(model=>model.ID)
,但在我的例子中,这是不可能的,因为我对不同的模型使用一个视图(从基本模型继承)

型号:

public class MyModel :  IEnumerable
{
    private PropertyInfo[] propertys 
    { 
        get
        {
            if (propertys != null) return propertys;

            string projectName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
            Type classtype = Type.GetType(string.Format("{0}.Models.{1}", projectName, FQModelname));
            PropertyInfo[] properties = classtype.GetProperties();

            return properties;
        }
    }

    public int ID { get; set; }

    public string Name { get; set; }

    //...

    public IEnumerator GetEnumerator()
    {
        return propertys.GetEnumerator();
    }
}
RazorView:

@foreach (var property in Model)
{
    // [Error] need Typeargument...?
    @Html.EditorFor(property);
}

这可以做得更好,但这是一个快速实现的想法,至少,你会想完善一些概念,让你的具体项目的工作

void Main()
{
    BaseModel baseModelTest = new Concrete() { Test = "test property" };

    foreach ( var property in baseModelTest.EnumerateProperties())
    {
        var value = baseModelTest.GetPropertyValue(property.Name);
        value.Dump();
    }


}

public class EnumeratedProperty
{
    public string Name { get; private set; }
    public Type Type { get; private set; }
    public EnumeratedProperty(string PropertyName, Type PropertyType)
    {
        this.Name = PropertyName;
        this.Type = PropertyType;
    }
}

public abstract class BaseModel
{
    protected IEnumerable<PropertyInfo> PropertyInfoCache { get; set; }
    protected IEnumerable<EnumeratedProperty> EnumeratedPropertyCache { get; set; }
    protected BaseModel()
    {
        PropertyInfoCache = this.GetType().GetProperties();
        EnumeratedPropertyCache = PropertyInfoCache.Select(p=> new EnumeratedProperty(p.Name,p.GetType()));
    }
    public IEnumerable<EnumeratedProperty> EnumerateProperties()
    {
        return EnumeratedPropertyCache;
    }
    public object GetPropertyValue(string PropertyName)
    {
        var property = PropertyInfoCache.SingleOrDefault(i=>i.Name==PropertyName);
        if(property!=null)
            return property.GetValue(this,null);
        return null;
    }
}

public class Concrete : BaseModel
{
    public string Test { get; set; }
}


这可以做得更好,但这是一个快速实现的想法,至少,你会想完善一些概念,让你的具体项目的工作

void Main()
{
    BaseModel baseModelTest = new Concrete() { Test = "test property" };

    foreach ( var property in baseModelTest.EnumerateProperties())
    {
        var value = baseModelTest.GetPropertyValue(property.Name);
        value.Dump();
    }


}

public class EnumeratedProperty
{
    public string Name { get; private set; }
    public Type Type { get; private set; }
    public EnumeratedProperty(string PropertyName, Type PropertyType)
    {
        this.Name = PropertyName;
        this.Type = PropertyType;
    }
}

public abstract class BaseModel
{
    protected IEnumerable<PropertyInfo> PropertyInfoCache { get; set; }
    protected IEnumerable<EnumeratedProperty> EnumeratedPropertyCache { get; set; }
    protected BaseModel()
    {
        PropertyInfoCache = this.GetType().GetProperties();
        EnumeratedPropertyCache = PropertyInfoCache.Select(p=> new EnumeratedProperty(p.Name,p.GetType()));
    }
    public IEnumerable<EnumeratedProperty> EnumerateProperties()
    {
        return EnumeratedPropertyCache;
    }
    public object GetPropertyValue(string PropertyName)
    {
        var property = PropertyInfoCache.SingleOrDefault(i=>i.Name==PropertyName);
        if(property!=null)
            return property.GetValue(this,null);
        return null;
    }
}

public class Concrete : BaseModel
{
    public string Test { get; set; }
}



您是否尝试过
@Html.EditorForModel()
而不是
@Html.EditorFor()

您是否尝试过
@Html.EditorForModel()
而不是
@Html.EditorFor(),然后在视图中调用它。听起来不错,你能给我举个例子吗?@Ian第一次听到这个集合时不知道这个集合会有什么帮助:-(很抱歉我读错了这个问题的标签…忽略我:)使你的基础抽象化,并强制你的模型类实现某种类型的对象属性[index]操作符或方法,然后在视图中调用它。听起来不错,你能给我举个例子吗?@Ian第一次听到这个集合时,不知道这个集合有什么帮助:-(对不起,我看错了这个问题的标签……忽略我:)我现在已经测试过了,但它抛出了一些错误。但是我认为这不是正确的方法,因为我需要一种方法来获取
@Html.EditorFor
的属性。仅属性名称是不够的,因为基金会应确定必须创建的字段:-(@myName EditorFor需要知道要为其创建html控件的类型,我们不得不放弃它,因为我们需要能够返回任何可能的类型,即Object。这里有几个解决方案-放弃这个想法,找到另一条路线,可能使用更多的视图类型和部分视图,以便一切都保持良好和稳定或者编写您自己的HtmlHelper扩展。这可能是最有效的方法,因为我会将属性名称和类型传递给您,这样您既可以使用,又可以选择正确的html标记在运行时呈现。@asawyer我看过了,我知道我在自定义HtmlHelper中有所有需要的参数,但我知道我不知道如何正确调用此方法。我发现调用此方法的问题值得一提:但现在似乎不可能:-(@myName-我还没有时间尝试正确的调用方法,但我会打开一个测试用例,今天稍后再尝试。我现在已经测试了它,但它会抛出一些错误。但我认为这不是正确的方法,因为我需要一种方法将属性获取到
@Html.EditorFor
。属性的名称还不够原因基金会应确定必须创建的字段:-(@myName EditorFor需要知道要为其创建html控件的类型,我们不得不放弃它,因为我们需要能够返回任何可能的类型,即Object。这里有几个解决方案-放弃这个想法,找到另一条路线,可能使用更多的视图类型和部分视图,以便一切都保持良好和稳定或者编写您自己的HtmlHelper扩展。这可能是最有效的方法,因为我会将属性名称和类型传递给您,这样您既可以使用,又可以选择正确的html标记在运行时呈现。@asawyer我看过了,我知道我在自定义HtmlHelper中有所有需要的参数,但我知道我不知道如何正确调用此方法。我发现调用此方法的问题值得一提:但现在似乎不可能:-(@myName-我还没有时间尝试正确的调用方法,但我会打开一个测试用例,今天稍后再尝试。当然,如果不创建自定义模板,我无法定义自己的布局,而一个好的自定义模板并不简单-我试过了;-)当然,如果不创建一个自定义模板,我就无法定义自己的布局,而一个好的自定义模板并不简单——我尝试过;-)
@foreach (var property in Model.EnumerateProperties())
{
    // call the new extention method, pass the EnumeratedProperty type
    // and the model reference
    @Html.EditorForProperty(Model,property);
}