我遇到显示模板问题并处理实现该接口的接口和对象。在示例中,我有许多对象,我想以固定的方式呈现,我决定创建一个接口并在视图中引用它,我决定将其放入共享显示模板文件夹中。 DisplayFor
不会为传递给它的对象工作,这些对象在视图中实现了接口,任何人都知道解决方案。
通过代码解释可能更容易,所以我写了一个简单的例子。基接口和从中继承的两个类:
public interface IPet
{
String Name { get; }
}
public class Dog : IPet
{
public String Name { get; set; }
}
public class Cat : IPet
{
public String Name { get; set; }
}
共享显示模板中的示例显示模板
@model IPet
<div>@Model.Name</div>
要传递给视图的示例视图模型
public class VM
{
public IPet Master { get; set; }
public IEnumerable<IPet> Minions { get; set; }
}
控制器(在这种情况下用于创建模拟信息)
public ActionResult Index()
{
var viewModel = new VM();
viewModel.Master = new Cat(){Name = "Fluffy"};
var minions = new List<IPet>();
minions.Add(new Dog(){Name = "Dave"});
minions.Add(new Dog(){Name = "Pete"});
minions.Add(new Cat(){Name = "Alice"});
viewModel.Minions = minions;
return View(viewModel);
}
最后是我期望DisplayFor
工作的视图
@model ViewInheritance.Models.VM
<h2>Master</h2>
@Html.DisplayFor(x => x.Master)
<h2>Minions</h2>
@Html.DisplayFor(x => x.Minions)
鉴于所有对象都是在视图模型中定义为接口,为什么它无法使用显示模板?
我发现的一个解决方案是简单地使用代码
@Html.DisplayFor(x => x.Master, "IPet")
总结一下,问题是:
为什么会这样?
有没有办法让DisplayFor
正确地确定实现Cat
的{{1}}实际上应该查看公共共享视图IPet
?
由于
答案 0 :(得分:1)
启动一个新的MVC应用程序并修复代码以实际编译视图呈现正常。将视图移动到共享文件夹时,它也可以正常呈现。
我在IPet中添加了setter:
public interface IPet
{
String Name { get; set; }
}
我更新了实施并添加了公共访问者:
public class Dog : IPet
{
public String Name { get; set; }
}
public class Cat : IPet
{
public String Name { get; set; }
}
我单独离开了您的VM,也没有更改View中的任何代码。
按F5,运行MVC应用程序按预期呈现结果(参见图像)。
答案 1 :(得分:-1)
不幸的是,我认为ASP.NET MVC目前不支持基于已实现的接口自动选择模板。我认为这是有道理的,因为一个类可以实现多个接口,所以如果你有多个接口的模板,框架应该选择哪一个?
如果您的设计可以处理它,您可以使用基类而不是接口:
IPet
更改为(可能是抽象的)class
。IPet.cshtml
更改为Pet.cshtml
。否则我认为您只需要明确告诉框架使用哪个模板。以下是一些选项:
[UIHint]
装饰视图模型属性。HtmlHelper
方法(例如DisplayFor
。ModelMetadataProvider
并更改结果TemplateHint
的{{1}}属性。