Альтернатива ViewBag.Название в ASP.NET MVC 3
по умолчанию новый шаблон проекта для ASP.NET MVC 3 добавляет следующее в макет по умолчанию (masterpage в razor):
<title>@ViewBag.Title</title>
затем представление должно содержать следующее, чтобы назначить заголовок страницы, например:
@{
ViewBag.Title = "Log On";
}
возможно, это просто мои собственные предпочтения, но я нахожу, что использование ViewBag для удержания названия немного неправильно (я думаю, слишком много волшебной струны). Итак, мой вопрос: это рекомендуется для людей, использующих ASP.NET MVC 3 и razor (используя динамический пакет свойств) или вы выбираете что-то более строго типизированное (возможно, с использованием пользовательского базового класса?)
8 ответов
Я не думаю, что есть что-то плохое с функцией обработки заголовка по умолчанию, которая поставляется с 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
.
ViewBag для названия отлично (я бы даже сказал, что это цель иметь ViewBag) - dynamic не является абсолютным злом. "Название" хорошо известно, вряд ли изменится и даже предопределенных шаблонов. Я лично использую следующее название:
<title>@(ViewBag.Title == null ? string.Empty : ViewBag.Title + " | ")Site Name</title>
если вы беспокоитесь о mistyping ViewBag.Title
вы можете сделать его сильным типом, создав custom WebViewPage
но вам все равно придется использовать ViewBag
или, может быть,HttpContext.Items
внутри этого строго типизированного свойства, потому что существует несколько примеры WebViewPage
создано во время рендеринга IIRC.
Я бы рекомендовал придерживаться ViewBag
, создавая собственные WebViewPage
из - за этого кажется излишним-даже создание одного свойства на нем, если у вас уже есть custom WebViewPage
на мой взгляд, просто бесполезное осложнение - и это происходит от человека, который часто перегружает вещи.
Я также не использую ViewBag, на всех.
в верхней части _Layout.штмл ...
@model <YourWebAppNameSpace>.Models.Base.EveryPageViewModel
In _Layout.штмл ...
<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);
}
мне нравится создавать атрибуты 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;
}
}
}
легко управлять и работает как шарм.
лично для меня, я думаю, что этот случай является приемлемым использованием ViewBag
. Он ограничен "известным" свойством, и, вероятно, в будущем не вызовет никаких проблем. В конце концов, все дело в том, чтобы быть прагматичным и найти способ быть как можно быстрее. Наличие базового класса, в котором вам нужно установить заголовок, на мой взгляд, слишком много кода, чтобы стоить безопасности типа.
удачи!
Я бы сказал, что пока это только название, которое вы хотите установить, можно использовать ViewBag. Ну, может и не только-максимум 2-3 свойства.
но если вы начнете видеть, что вы устанавливаете все больше и больше (общих) свойств в каждом действии контроллера, я бы пошел со строго типизированным "ViewModelBase class". Но это всего лишь я.
мы предпочитаем сильную настройку титул.. немногие образцы из нашего класса BaseController. (Страница определяет инкапсулированный вид modal)
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);
}
нет ничего плохого в использовании ViewBag.Title = "Мой Титул";
все, что вы делаете использовать динамическое свойство.
вопрос действительно в том, где информация должна быть "объявлена".
Ie, где он наиболее доступен для целей под рукой.
Если это на уровне страницы, то это правильное место.
Если, однако, заголовок страницы может быть получен из модели, то вы должны это сделать.
в этом случае я, вероятно, использовал бы базовый класс для используемой ViewModel и создал бы свойство PageTitle, содержащее логику для получения заголовка страницы из свойств в модели.
Так:
<title>Model.PageTitle</title>
В общем, лошади для курсов и не бойтесь использовать динамические свойства... до тех пор, пока вы понимаете, что они такое и что они делают.