2011-06-27 18 views
1

如何使用foreach將我的屬性從模型導入到我的視圖中?如何使用foreach將我的屬性從模型導入到我的視圖中?

我知道我可以使用@Html.EditorFor(model => model.ID)但在我的情況下,這是不可能的,因爲我使用一個視圖爲不同的模型(從BaseModel繼承)。

型號:

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); 
} 
+0

製作您的基本抽象,並強制您的模型類實現某種類型的對象屬性[index]運算符或方法,並在視圖中調用它。 – asawyer

+0

聽起來不錯,你能舉個例子嗎? – jwillmer

+0

當然,現在發佈。 – asawyer

回答

0

可以這樣做更強的類型化,但是這是一個快速實現的想法,至少,你要細化一些概念併爲你的特定項目找點工作。

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; } 
} 

....

public static class ExtensionMethods 
{ 
    public static MvcHtmlString EditorForProperty(this HtmlHelper html, BaseModel Model, EnumeratedProperty property) 
    { 
     // invoke the appropriate Html.EditorFor(...) method at runtime 
     // using the type info availible in property.Type 
     return ... 
    } 
} 

....

@foreach (var property in Model.EnumerateProperties()) 
{ 
    // call the new extention method, pass the EnumeratedProperty type 
    // and the model reference 
    @Html.EditorForProperty(Model,property); 
} 
+0

我已經測試它,但它會拋出一些錯誤。但我認爲這不是正確的方式,因爲我需要一種方法來獲取屬性到'@ Html.EditorFor'。財產的名稱是不夠的,因爲資金應該確定什麼字段必須創建:-( – jwillmer

+0

@myName EditorFor需要知道的類型來創建的HTML控制,我們必須扔掉,因爲我們需要能夠返回任何可能的類型,即Object。在這裏有幾個解決方案 - 放棄這個整個想法的想法,找到另一條路線,可能使用更多的視圖類型和部分視圖,以便一切都保持良好和強類型,或編寫自己的HtmlHelper擴展名。這個路徑可能會工作得最好,因爲我傳遞給你屬性名稱和類型,所以你可以同時使用這兩個選項,並且能夠在運行時選擇正確的html標籤來顯示。 – asawyer

+0

@myName參見編輯 – asawyer

1

你試過@Html.EditorForModel()而不是@Html.EditorFor()

+0

當然,但我不能定義我自己的佈局,而不創建一個自定義模板和一個好的自定義模板不是微不足道的 - 我試過了;-) – jwillmer

相關問題