2

如何將模型(它是接口類型)轉換爲其實際類型?剃刀模型鑄造

你在下面看到的顯然是非常簡化的版本,專注於手頭的問題。所以問題是不是如何重新架構我的解決方案,但具體是如何將接口類型模型實例轉換爲剃刀中的實際類類型。

視圖模型:

public interface IData 
{ 
    string Data { get; set; } 
} 
public class Child1 : IData 
{ 
    [Display(Name = "Name1", Description = "Desc1", Prompt = "Prompt1")] 
    public string Data { get; set; } 
} 
public class Child2 : IData 
{ 
    [Display(Name = "Name2", Description = "Desc2", Prompt = "Prompt2")] 
    public string Data { get; set; } 
} 
// It gets to Child10 and there is dynamic number of each of them in the main ViewModel 

在我需要顯示的數據註解的觀點,但MVC不會做它在面向對象FASION。 如果我只是說

@model <path to>.IData 
@Html.LabelFor(m => model.Data) 
@Html.TextBoxFor(m => model.Data) 
@Html.ValidationMessageFor(m => model.Data) 

我得到什麼的在接口中定義的,而不是什麼實際的類。 愚蠢的解決方案是巨大的開關和鑄模型,它來自實際類型:

@switch(Model.GetType().Name) 
{ 
    case "Child1": 
    var c1 = Model as Child1; 
    @Html.LabelFor(m => c1.Data) 
    @Html.TextBoxFor(m => c1.Data) 
    @Html.ValidationMessageFor(m => c1.Data) 
    break; 
    // etc 
} 

切換變得萬一我有IBASE超過3個孩子無法控制的(和我一樣),更遑論相貌醜陋。 而不是做開關,我如何使用反射來獲得Model的類型? 注意,簡單

@{ 
    var c1 = Model as Model.GetType(); 
    var c2 = (Model.GetType()) Model; 
    var c3 = (Type.GetType(Model.GetType())) Model; 
    var c4 = Model as Type.GetType(Model.GetType(); 
} 

等給出了可怕的警告,並肯定剃刀不運行。

我相信可以通過模型反射來獲得,但不管我嘗試過的方法都行不通。 希望你們有一些新鮮的想法。

小更新

,其中X是數成一個模型,因爲事先不知道有多少人都在那裏,在主視圖它可以增加它的/刪除那些我不能結合兒童。我繪製的圖片非常針對這個問題,視圖/控制器/模型比您在這裏看到的複雜得多。

在此先感謝。

+1

+1 - 非常好的問題,尋找正確的建議.. – 2012-08-04 16:03:04

回答

2

有關您的示例的簡要說明:您將顯示IBase的接口,但您的類正在實現接口IData。

您的模型應該是您將要使用的實際類型的對象(或者包含您想要使用的類型的屬性),而不是將模型作爲接口。

舉個例子,如果你想顯示關於在你看來這兩個孩子的數據,建立模型是這樣的:如果您在ChildModel返回到您的視圖

public class ChildModel { 
    public Child1 { get; set; } 
    public Child2 { get; set; } 
} 
public class Child1 : IData 
{ 
    [Display(Name = "Name1", Description = "Desc1", Prompt = "Prompt1")] 
    public string Data { get; set; } 
} 
public class Child2 : IData 
{ 
    [Display(Name = "Name2", Description = "Desc2", Prompt = "Prompt2")] 
    public string Data { get; set; } 
} 

,然後你不需要在你的視野內進行任何投射(你應該避免這種投射)。

+0

感謝您指出IData/IBase問題,修復它。原因我沒有選擇你的答案是正確的,我需要那些Child1 - ChildN是動態的,即我不知道模型中有多少人,我可以在視圖中添加/刪除它們。所以ChildModel不適用於我的情況(我希望事情很簡單)。 感謝您花費時間。 – 2012-08-04 15:52:28

+0

你可能不知道每種類型有多少,但你應該知道你將*可能需要處理的對象類型,對嗎?相反,將ChildModel更改爲使用類型的「List」,然後可以處理動態數量。 – 2012-08-04 16:33:18

+1

我的解決方案中恰好有ChildModel,就像你描述的那樣:'List '。並且視圖模型類型是'IData',但是它的實際裝飾被丟失了,因爲MVC並沒有通過實際類型(我認爲它應該遵循OO原則),而是通過模型類型,即接口(未修飾)類型。因此我需要將它轉換爲實際類型,我的問題是如何去做。 – 2012-08-05 02:14:15