« Все записи

ASP.NET MVC: добавление метаданных страницы с помощью ActionFilter

Оригинал статьи. Это действительно полезная статья, я взял этот механизм добавления meta тэгов себе на вооружение.

Одна вещь, которая является достаточно общей для приложений, управляемых данными - это необходимость определения метаданных, которые появляются на каждой странице (обычно в виде элементов мастер-страницы).

Пример включают заголовок страницы, и метаданные - описание и ключевые слова:

<title>Index</title>
<meta name="description" content="Some description" />
<meta name="keywords" content="demo, website, mvc" />

Стандартные шаблоны ASP.NET MVC уже предоставить вам способ обновления названия из ваших индивидуальных представлений с помощью динамической коллекции ViewBag. Затем вы можете изменить название страницы в ваших представлениях вот так:

@{
    ViewBag.Title = "Index";
}

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

Первое, что я хочу сделать, это определить интерфейс, который сущности с метаданными должны реализовывать:

public interface IMetaEntity {
    string Description { get; set; }
    string Keywords { get; set; }
}

Теперь создадим объект, который реализует этот интерфейс:

public class Product : IMetaEntity {
    public string Name { get; set; }
    public string Description { get; set; }
    public string Keywords { get; set; }
}

Наконец мы создаем наш собственный ActionFilter и переопреляем OnActionExecuted метод. Это позволяет нам обновлять ViewBag коллекции до выполнения ActionResult:

public class MetaDataAttribute : ActionFilterAttribute {
    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        var viewResult = filterContext.Result as ViewResult;

        if (viewResult == null)
            return;

        // знаяения по умолчанию - должны быть загружены из настроек или базы данных

        var description = "Some description";
        var keywords = "demo, website, mvc";

        var model = viewResult.Model as IMetaEntity;

        if (model != null) {
            description = model.Description;
            keywords = model.Keywords;
        }

        viewResult.ViewBag.Description = description;
        viewResult.ViewBag.Keywords = keywords;
        
        base.OnActionExecuted(filterContext);
    }
}

Все очень просто. Сначала мы проверяем, что результат - это ViewResult. Затем мы проверяем, что модель ViewResult реализует IMetaEntity. Если да, то заполняем ViewBag нашими метаданными нашей сущности, или используем текущие, если нет.

Затем мы можем декорировать наши методы действий этим атрибутом:

public class HomeController : Controller {
    [MetaData]
    public ActionResult Index() {
        return View();
    }

    [MetaData]
    public ActionResult Product(string id) {
        var p = new Product {
            Name = "Crazy Widget",
            Description = "This is a crazy widget that does crazy things",
            Keywords = "crazy, widget"
        };

        return View(p);
    }
}

Наша шаблонная страница обновляется для заполнения мета-тегов при помощи свойства ViewBag (разумеется с помощью наших HtmlHelper-ов):

@Html.MetaKeywords((string)ViewBag.Keywords)
@Html.MetaDescription((string)ViewBag.Description)

Если мы на главной странице нашего сайта:

и если мы перейдем к нашей странице продукта:

Положительным эффектом от использования коллекции ViewBag является то, что мы можем изменить метаданные для статических представлений или с помощью динамических моделей.

Еще один пример того, как легко можно подключиться в конвейер вычислений в ASP.NET MVC.

Progg it

comments powered by Disqus