Когда мы должны реализовать собственный MVC ActionFilter? - PullRequest
3 голосов
/ 20 июля 2011

Должны ли мы переместить логику, которая предполагает наличие в Controller (например, данные для визуализации частичного представления) в ActionFilter?

Например, я делаю сайт CMS.На нескольких страницах должен быть рекламный блок, но не на всех.Должен ли я создать атрибут ActionFilter , например [ShowAd (categoryId)] * ​​1006 *, и украсить методы действия этим атрибутом?

Реализация этого контроллера будет включать вызовы службы для извлечения информации из базы данных, построения моделей представления и вставки в ViewData .Будет HtmlHelper для визуализации частичного представления с использованием данных в ViewData , если оно существует.

Ответы [ 2 ]

4 голосов
/ 20 июля 2011

Мне это просто кажется противным.

Когда я пытаюсь выяснить, нужен ли мне ActionFilter, первый вопрос, который у меня возникает, Это сквозная проблема? . Ваш конкретный вариант использования не подходит для этого, на первый взгляд. Причина в том, что реклама - это просто еще одна вещь, отображаемая на странице. В этом нет ничего особенного, что делает его сквозным. Если вы замените слово «Объявление» на «Продукт» в вашем вопросе, все те же факты будут правдой.

Итак, есть и разделение интересов и тестируемость. Насколько проверяемы ваши контроллеры, когда вы установили этот ActionFilter? Это что-то еще, что вы должны смоделировать при тестировании, и что еще хуже, вы должны смоделировать эти зависимости с каждым контроллером, к которому вы добавляете ActionFilter.

Второй вопрос, который я задаю: «Как я могу сделать это таким образом, который кажется наиболее идиоматичным на платформе, которую я использую?»

Для этой конкретной проблемы это звучит как RenderAction , и AdController - это то, что нужно.

И вот почему:

  1. Объявление - это собственный ресурс; обычно он не привязан ни к чему другому на странице; он существует как бы в своем маленьком мире.
  2. У него своя собственная стратегия доступа к данным
  3. Вы на самом деле не хотите повторять код, чтобы генерировать объявление в каждом месте, где вы можете его использовать (вот куда вам может подойти RenderPartial подход)

Так вот как будет выглядеть такой зверь:

public AdController : Controller
{
    //DI'd in
    private AdRepository AdRepository;

    [ChildActionOnly]
    public ActionResult ShowAd(int categoryId)
    {
        Ad ad = Adrepository.GetAdByCategory(categoryId);
        AdViewModel avm = new AdViewModel(ad);
        return View(avm);
    }
}

Тогда вы могли бы иметь собственный частичный вид, который настроен вокруг этого, и нет необходимости устанавливать фильтр на каждое действие (или каждый контроллер), и вам не нужно пытаться установить квадратный колышек (действие фильтр) в круглое отверстие (динамический вид).

Добавление объявления на существующую страницу становится очень простым:

<% Html.RenderAction("ShowAd", "Ad" new { categoryId = Model.CategoryId }); %>
0 голосов
/ 20 июля 2011

Если ваша рекламная система достаточно проста, нет никаких причин, по которым вы не можете / не должны использовать фильтр действий для вставки достаточного количества информации в данные представления, чтобы сгенерировать объявление в вашем коде представления.

Для простой рекламной системы, скажем .. отдельное объявление определенной категории показывается в одном и том же месте в макете на каждой странице, и все, реальный аргумент в пользу лучше способ кроме как подготовиться к будущим изменениям в системе.Хотя эти опасения могут быть законными, у вас также может быть достаточно оснований полагать, что требование никогда не изменится.Но, , даже если требования меняются , упаковка всего кода, который генерирует рекламу в одном месте, является наиболее важным аспектом и сэкономит вам гораздо больше времени, чем более надежное решение.Очевидно, есть несколько способов обернуть этот код в одном месте.

Что касается того, как вы решите это сделать, я бы оставил ваш фильтр действий более чистым, чтобы он только вставлял категорию впросматривать данные и иметь все волшебство внутри вашего помощника HTML, который будет принимать категорию в качестве параметра.Создание моделей представлений для вставки в данные представлений потребует некоторой дополнительной работы и повсеместного размещения кода, когда он не требуется.Сохраняйте это простым и делайте все html-генерацию внутри html-помощника, который отвечает за ... создание html.

...