2011-11-23 36 views
6

至少,我認爲這與問題有關。我的場景是這樣的:EditorFor對派生類型不起作用

我有一些業務實體具有公共字段,每個具有該實體唯一的自定義字段。因此,在代碼中,這被建模爲EntityBase類,並且有許多類派生自此,例如Derived

要製作可重複使用的用戶界面,我已經有了一個叫EntityBase.vbhtml認爲是這樣的:

@ModelType EntityBase 

@Using Html.BeginForm("Edit", Model.GetType.Name) 
    @* show the editor template for the derived type *@ 
    @* !!the next line renders nothing!! *@ 
    @Html.EditorFor(Function(x) Model, Model.GetType.Name) 

    [show a bunch of stuff common to all EntityBase objects] 
End Using 

,然後一個叫Derived.vbhtml派生類,這樣處理:

@ModelType Derived 
[show an EditorFor for various Derived-specific fields] 

然後,當您導航到\Derived\Edit\123時,它將返回默認視圖Derived\Edit.vbhtml,它只是這樣做:

@Html.EditorForModel("EntityBase") 

通過這種方式,控制器只是返回預期的默認編輯視圖,該視圖是對EntityBase視圖的單線調用,它執行它的操作並調用Derived來渲染它不知道的派生類。

我以爲這不起眼,但它不起作用。如視圖代碼中所標記的,當我在基類視圖中調用EditorForModel時,指定派生類的名稱用作模板時,它不會呈現任何內容。我測試過,如果我在頂層編輯模板中調用完全相同的代碼行,它可以正常工作。所以有一些關於MVC不喜歡的繼承,但我看不到。請幫忙!

更新:它的工作原理,因爲我認爲這是混淆不是我希望的,如果不是EditorFor我使用Partial(和移動相應的模板,從EditorTemplates文件夾的共享文件夾),但是這並不是一個很好的解決方案遵循EditorFor模板的命名約定。

回答

3

看起來,雖然MVC在這種情況下不會找到命名模板,但如果您指定了模板的完整路徑,則會發現它。因此,而不是任何進一步打這個,我採取了以下輔助函數:

<Extension()> _ 
Public Function EditorForObject(Of T, TValue)(ByVal htmlHelper As HtmlHelper(Of T), ByVal obj As TValue) As IHtmlString 
    Dim sTemplateName = "~/Views/Shared/EditorTemplates/" & obj.GetType.Name & ".vbhtml" 

    'Return htmlHelper.EditorFor(Function(x) obj) <-- this should work but doesn't 
    Return htmlHelper.Partial(sTemplateName, obj) 
End Function 

在英語中,這意味着:詢問其類型名稱的對象,形成以該類型的編輯器模板顯式路徑,並然後調用HtmlHelper.Partial,指定對象和模板的完整路徑。我敢肯定,這可能是更一般的(而不是硬編碼的VB),但它的工作原理。

然後使用是這樣的:

@Html.EditorForObject(Model) 

,實際上,這是比我要怎樣做,這是更混亂甚至更好:

@Html.EditorFor(Function(x) Model, Model.GetType.Name) 

即使沒有模板查詢問題,這將會很方便,因爲能夠傳遞一個對象進行編輯(或顯示)很方便,而不是隻返回該對象的虛擬lambda。

不過,我認爲查找問題必須是MVC中的錯誤。 (如果我有時間,我想我可以檢查源代碼。)任何人都可以確認或評論這個?

+0

我遇到了同樣的問題。感謝您的解決方法。我正要放棄:) –

+0

很高興聽到它!我真的把我的頭髮弄在這一張上。 –