EditorFor不处理派生类型

Jos*_*ank 6 vb.net asp.net-mvc editorformodel razor asp.net-mvc-3

至少,我认为这与问题有关.我的情况是这样的:

我有许多具有公共字段的业务实体,每个实体都有该实体独有的自定义字段.所以在代码中,这被建模为一个EntityBase类,并且有许多类派生自此,例如,Derived.

为了创建一个可重用的UI,我有一个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
Run Code Online (Sandbox Code Playgroud)

然后一个调用Derived.vbhtml派生类来执行此操作:

@ModelType Derived
[show an EditorFor for various Derived-specific fields]
Run Code Online (Sandbox Code Playgroud)

然后,当您导航到时\Derived\Edit\123,它将返回默认视图Derived\Edit.vbhtml,它只是这样做:

@Html.EditorForModel("EntityBase")
Run Code Online (Sandbox Code Playgroud)

通过这种方式,控制器只返回预期的默认Edit视图,这是对视图的一次性调用EntityBase,它执行其操作并调用它Derived来呈现它不知道的派生类内容.

我认为这不起眼,但它不起作用.如在视图代码中标记的那样,当我在基类视图中调用EditorForModel时,指定派生类的名称以用作模板时,它不会呈现任何内容.我测试过,如果我在顶级编辑模板中调用完全相同的代码行,它就可以正常工作.所以有一些关于MVC不喜欢的继承,但我看不出是什么.请帮忙!

更新:它可以正常工作,而不是EditorFor我使用Partial(并将相应的模板从EditorTemplates文件夹移动到Shared文件夹),但这不是一个很好的解决方案,因为我认为不遵循EditorFor模板的命名约定令人困惑.

Jos*_*ank 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
Run Code Online (Sandbox Code Playgroud)

在英语中,这意味着:向对象询问其类型名称,形成该类型的编辑器模板的显式路径,然后调用 HtmlHelper.Partial,指定对象和模板的完整路径。我确信这可能更通用(并且不是针对 vb 进行硬编码),但它确实有效。

那么用法是这样的:

@Html.EditorForObject(Model)
Run Code Online (Sandbox Code Playgroud)

实际上,这甚至比我想要做的要好,这要混乱得多:

@Html.EditorFor(Function(x) Model, Model.GetType.Name)
Run Code Online (Sandbox Code Playgroud)

即使没有模板查找问题,这也会很方便,因为能够方便地传递对象进行编辑(或显示),而不是仅返回该对象的虚拟 lambda。

不过,我认为查找问题一定是 MVC 中的一个错误。(如果我有时间,我想我可以检查源代码。)任何人都可以确认或评论这一点吗?