ASP.NET MVC编辑器模板和Html.EditorFor(...) - 如何消除类型名称的歧义?

时间:2013-08-26 13:00:09

标签: asp.net asp.net-mvc razor

在Razor语法中使用此HTML帮助程序时:

@Html.EditorFor(model => model.Prop1)

...惯例是在Views/<CrtView|Shared>/EditorTemplates/Prop1TypeName.cshtml下呈现视图。

到目前为止一切顺利。请注意,如果(合格)类型的Prop1为my.org.ns.TheType,则会呈现文件TheType.cshtml

但如果我的模型包含.Prop1.Prop2,并且:

Prop1.GetType().FullName == "my.org.ns1.TheType";
Prop2.GetType().FullName == "my.org.ns2.TheType";  //same type name but different namespace

我称之为剃刀:

@Html.EditorFor(model => model.Prop1)
@Html.EditorFor(model => model.Prop2)

...我无法让它显示不同类型的不同的视图。

有没有办法消除歧义?

也许我对.cshtml文件的命名约定了解不止?

3 个答案:

答案 0 :(得分:9)

您可以使用this overload指定要使用的编辑器的名称。有了这个,你可以命名你的EditorTemplates First.cshtmlSecond.cshtml,然后在你的视图中,这样做。

@Html.EditorFor(model => model.Prop1, "First")
@Html.EditorFor(model => model.Prop2, "Second")

但是,我建议避免在同一个项目中重复使用相同的类型名称,即使它们具有不同的名称空间。这将导致阅读代码的人感到困惑,甚至可能会让你感到困惑。这是一个比不知道使用什么模板的框架更大的问题。

答案 1 :(得分:5)

检查ASP.NET MVC source code时(第164行):

 // TODO: Make better string names for generic types
 yield return fieldType.Name;

似乎开发团队意识到这种简化的方法(复杂类型的fieldType.Name)可能是潜在的模糊性。我希望他们能找到一种优雅的方式让我们以更灵活的方式选择模板。

与此同时,您只需使用[UIHint]属性,如下所示:

[UIHint("ns1.TheType")]
public TheType Prop1 { get; set; }

[UIHint("ns2.TheType")]
public TheType Prop2 { get; set; }

更新(根据您的评论):

[UIHint]只能用于属性或字段,因此您无法使用它来装饰您的类。

但是,您可以创建自己的属性,该属性派生自UIHintAttribute

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class, AllowMultiple = true)]
public class MyUIHintAttribute : UIHintAttribute
{
    public MyUIHintAttribute(string templateName) : base(templateName)
    {
    }
}

然后装饰你的课程:

[MyUIHint("ns1.TheType")]
public class TheType
{
    ....
}

[MyUIHint("ns2.TheType")]
public class TheType
{
    ....
}

答案 2 :(得分:2)

您不一定要使用这些约定。您可以拥有自己的模板名称。

像这样,

@Html.EditorFor(model => model.Prop1,"TheType_1")
@Html.EditorFor(model => model.Prop2,"TheType_2")

其中“TheType_1”&amp; “TheType_2”是不同类型的不同模板名称。 这是six different overload methods之一。