3

我在显示模板和处理实现该接口的接口和对象时遇到问题。在示例中,我有许多对象,我想以固定方式呈现它们,我决定创建一个接口并在我决定放入共享显示模板文件夹的视图中引用它。 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实现IPet实际上应该查看公共共享视图IPet.cshtml

谢谢

4

2 回答 2

0

启动一个新的 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; }
}

我离开了你的虚拟机,也没有更改你视图中的任何代码。按 F5,运行 MVC 应用程序按预期呈现结果(见图)。在此处输入图像描述

于 2012-02-03T12:02:04.590 回答
-1

不幸的是,我认为 ASP.NET MVC 目前不支持根据实现的接口自动选择模板。我认为这是有道理的,因为一个类可以实现多个接口,所以如果你有多个接口的模板,框架应该选择哪一个?

如果您的设计可以处理它,您可以使用基类而不是接口:

  • 更改IPet为(可能是抽象的)class
  • 更改IPet.cshtmlPet.cshtml

否则我认为你只需要明确告诉框架使用哪个模板。以下是一些选项:

  • 用 装饰视图模型属性[UIHint]
  • 在对方法的调用中指定模板,HtmlHelper例如DisplayFor.
  • 自己制作ModelMetadataProvider并更改TemplateHint结果的属性ModelMetadata
于 2014-07-10T00:24:08.573 回答