9

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

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

...惯例是在 Views/<CrtView|Shared>/EditorTemplates/Prop1TypeName.cshtml.

到目前为止,一切都很好。请注意,如果 Prop1 的(合格)类型是my.org.ns.TheTypeTheType.cshtml则将呈现文件。

但是,如果我有一个带有.Prop1and 和.Prop2and 的模型:

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

4

3 回答 3

9

您可以使用此重载来指定要使用的编辑器的名称。有了这个,您将命名您的 EditorTemplates First.cshtmlSecond.cshtml然后在您的视图中执行此操作。

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

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

于 2013-08-26T13:11:46.410 回答
5

检查 ASP.NET MVC源代码时(第 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
{
    ....
}
于 2013-08-26T13:56:17.803 回答
2

您不一定必须使用约定。您可以拥有自己的模板名称。

像这样,

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

其中“TheType_1”和“TheType_2”是不同类型的不同模板名称。这是可用的六种不同重载方法之一。

于 2013-08-26T13:11:38.410 回答