Шаблон отображения не используется для интерфейса - PullRequest
3 голосов
/ 03 февраля 2012

У меня проблема с шаблонами отображения и с интерфейсами и объектами, которые реализуют интерфейс.В этом примере у меня есть много объектов, которые я хочу отображать фиксированным способом, я решил создать интерфейс и ссылаться на него в виде, который я решил поместить в папку общих шаблонов отображения.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?

Спасибо

Ответы [ 2 ]

1 голос
/ 03 февраля 2012

Запуск нового приложения MVC и исправление кода для фактической компиляции представления прекрасно.Он также хорошо обрабатывается при перемещении представления в общую папку.

I Добавлен установщик IPet:

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; }
}

Я оставил вашу ВМ в покое, а также не изменил код в вашем View.При нажатии клавиши F5 запущенное приложение MVC отобразило результаты, как и ожидалось (см. Изображение). enter image description here

0 голосов
/ 10 июля 2014

К сожалению, я не думаю, что ASP.NET MVC в настоящее время поддерживает автоматический выбор шаблонов на основе реализованных интерфейсов.Я думаю, что это имеет смысл, потому что класс может реализовывать несколько интерфейсов, поэтому, если у вас есть шаблоны для более чем одного из этих интерфейсов, какой из них следует выбрать фреймворку?

Вы можете использовать базовый класс вместо интерфейса, еслиВаш дизайн может справиться с этим:

  • Изменить IPet на (возможно, абстрактный) class.
  • Изменить IPet.cshtml на Pet.cshtml.

В противном случае, я думаю, вам просто нужно явно указать платформе, какой шаблон использовать.Вот некоторые параметры:

  • Украсьте свойства модели представления с помощью [UIHint].
  • Укажите шаблон в вызовах для ваших методов HtmlHelper, таких как DisplayFor.
  • Создайте свой собственный ModelMetadataProvider и измените свойство TemplateHint получившегося ModelMetadata.
...