在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
文件的命名约定了解不止?
答案 0 :(得分:9)
您可以使用this overload指定要使用的编辑器的名称。有了这个,你可以命名你的EditorTemplates First.cshtml
和Second.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之一。