Подтвердить что ты не робот

Альтернатива ViewBag.Title в ASP.NET MVC 3

По умолчанию новый шаблон проекта для ASP.NET MVC 3 добавляет следующее в макет по умолчанию (главная страница в бритве):

<title>@ViewBag.Title</title>

В представлении должно быть указано следующее, чтобы назначить заголовок страницы, например:

@{
     ViewBag.Title = "Log On";
}

Возможно, это только мои собственные предпочтения, но я нахожу, что использование ViewBag, чтобы держать заголовок немного неправильным (я думаю, слишком много волшебного вкуса). Поэтому мой вопрос: рекомендуется ли это рекомендация для людей, использующих ASP.NET MVC 3 и бритву (используя динамический пакет свойств), или вы выбираете что-то более строго типизированное (возможно, с использованием пользовательского базового класса?)

4b9b3361

Ответ 1

Я не думаю, что есть что-то плохое с функцией обработки заголовков по умолчанию, которая поставляется с asp.net MVC 3, ее все в порядке.

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

Мастер

<title>
    @RenderSection("Title");
</title>

Вид

@section Title
{
    write title
}

Одна вещь, которую я мог бы предложить улучшить функциональность по умолчанию

@{
    string pageTitle = @ViewBag.Title ?? "Title Not Set";
}
<title>@pageTitle</title>

Поэтому, когда вы забудете добавить его в viewbag, на странице будет отображаться заголовок = Title Not Set

Создание базового класса, в результате чего все ваши контроллеры наследуются от этого базового класса также могут быть выполнены. Но я думаю, что он так сильно болел за title.

Ответ 2

ViewBag для заголовка прекрасно (я бы даже сказал, что это цель иметь ViewBag) - динамика не является абсолютным злом. "Название" хорошо известно, маловероятно, чтобы изменить и даже предустановить в виде шаблонов. Я лично использую следующий заголовок:

<title>@(ViewBag.Title == null ? string.Empty : ViewBag.Title + " | ")Site Name</title>

Если вы обеспокоены ошибкой ViewBag.Title, вы можете сделать его сильным типом, создав пользовательский WebViewPage, но вам все равно придется использовать ViewBag или, может быть, HttpContext.Items внутри этого сильно типизированного свойства, потому что есть несколько экземпляров WebViewPage, созданный во время рендеринга IIRC.

Я бы рекомендовал придерживаться ViewBag, создав собственный WebViewPage, потому что это похоже на overkill - даже создание одного свойства на нем, если у вас уже есть пользовательский WebViewPage, на мой взгляд, просто бесполезное усложнение - и что происходит от человека, который часто переоценивает вещи.

Ответ 3

Я тоже не использую ViewBag.

В верхней части _Layout.shtml...

@model <YourWebAppNameSpace>.Models.Base.EveryPageViewModel

В _Layout.shtml...

<title>@Model.Title</title>

В вашей модели...

/// <summary>
/// Index View Model
/// </summary>
public class IndexViewViewModel : EveryPageViewModel {

}

В EveryPageViewModel

/// <summary>
/// Every Page View Model
/// </summary>
public abstract class EveryPageViewModel {
    /// <summary>
    /// Title
    /// </summary>
    public string Title { get; set; }
    /// <summary>
    /// Sub Title
    /// </summary>
    public string SubTitle { get; set; }
}

В действии вашего контроллера

    /// <summary>
    /// Index
    /// </summary>
    /// <returns></returns>
    public ActionResult Index() {
        var model = new IndexViewViewModel();
        model.Title = "Home";
        return View(model);
    }

Ответ 4

Мне нравится создавать атрибуты PageTitle ActionFilter, а не редактировать отдельные ViewBags

Использование: сохранить представление тем же самым

<title>@ViewBag.Title</title>

Для заголовка всей панели управления:

[PageTitle("Manage Users")]
public class UsersController : Controller {
    //actions here
}

Для отдельных просмотров:

public class UsersController : Controller {
    [PageTitle("Edit Users")]
    public ActionResult Edit(int id) {
          //method here
    }
}

Код атрибута:

public class PageTitleAttribute : ActionFilterAttribute
{
    private readonly string _pageTitle;
    public PageTitleAttribute(string pageTitle)
    {
        _pageTitle = pageTitle;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.ViewBag.Title = _pageTitle;
        }
    }
}

Легко управлять и работает как шарм.

Ответ 5

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

Удачи!

Ответ 6

Я бы сказал, что пока это только название, которое вы хотите установить, хорошо использовать ViewBag. Ну, может быть, не только - не более 2-3 свойств.

Но если вы начнете видеть, что вы устанавливаете все новые и новые свойства в каждом действии контроллера, я бы пошел с строго типизированным "классом ViewModelBase". Но это только я.

Ответ 7

мы предпочитаем сильную настройку заголовка. Несколько примеров из нашего класса BaseController. (Страница определяет инкапсулированный режим просмотра)

protected override ViewResult View(string viewName, string masterName, object model)
{
    if (model is Page)
    {
        ViewBag.Title = ((Page)model).Title;
        //HACK: SEO
        //TODO: SEO
    }
    return base.View(viewName, masterName, model);
}

Ответ 8

Нет ничего плохого в использовании ViewBag.title= "My Title";

Все, что вы делаете, это использование динамического свойства.

Вопрос в том, где информация должна быть "объявлена".

Т.е., где он наиболее доступен для целей.

Если это зависит от каждой страницы, то это правильное место.

Если, однако, название страницы можно получить из Модели, тогда вы должны это сделать.

В этом случае я, вероятно, использовал бы базовый класс для ViewModel, который вы используете, и создайте там свойство PageTitle, которое содержит логику для получения названия страницы из свойств в модели.

Итак:

<title>Model.PageTitle</title>

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