2011-08-08 24 views
24

Por defecto, la plantilla de proyecto nuevo para ASP.NET MVC 3 añade lo siguiente a la presentación por defecto (masterpage en la maquinilla de afeitar): debealternativa a ViewBag.Title en ASP.NET MVC 3

<title>@ViewBag.Title</title> 

La vista entonces contener los siguientes para asignar el título de la página, por ejemplo:

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

Tal vez es sólo mi preferencia, pero me parece que el uso de la ViewBag a cabo el título un poco mal (estoy pensando demasiado sabor mágico). Entonces mi pregunta es: ¿es esta la mejor práctica recomendada para las personas que usan ASP.NET MVC 3 y navaja de afeitar (utilizando una bolsa de propiedades dinámica) o opta por algo escrito con mayor fuerza (quizás con una clase base personalizada?)

+1

Usar la viewbag para esto es genial, ya que puede declarar la variable en una página de diseño y luego especificar un título diferente para cada vista que herede de ella. Realmente no hay otra manera de hacerlo sin usar un modelo estáticamente estátizado. –

Respuesta

25

I No creo que haya nada malo con la función predeterminada de manejo del título que se envía con asp.net MVC 3, está bien hacerlo.

yo personalmente hago esto (por debajo escrito) para manejar título, yo no estoy apoyando el código de abajo o decir que es mejor que la funcionalidad por defecto, es sólo una preferencia.

Maestro

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

Ver

@section Title 
{ 
    write title 
} 

Una cosa que podría sugerir para mejorar la funcionalidad por defecto

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

Así que cada vez que olvide añadirlo en viewbag, la página mostrará title = Title Not Set

Creación de una clase base y luego hacer todos los controladores que heredan de la clase base también se puede hacer. Pero creo que es muy doloroso para title.

+0

Solo para aclarar (no estaba pensando en una clase base predeterminada del controlador, estaba pensando que podría crear su propia clase base derivada para la vista (que creo que razor), y exponer una propiedad PageTitle en esta clase que la vista puede asignar y el diseño puede representar) –

+0

Me gusta esto '@ViewBag.Title ?? "Predeterminado" 'enfoque. Se puede mover a _ViewStart.cshtml y puede establecer los valores predeterminados aquí para todas las propiedades compartidas. – Darmak

+0

@ soren.enemaerke: supongamos que creó una clase base para que las vistas manejen el título de la página, probablemente dentro de sus vistas establecería un título como este @ {this.pageTitle = "New Title";}, mientras que con la funcionalidad predeterminada podría establecer título como @ {ViewBag.Title = "New Title";}. No hay mucha diferencia en la sintaxis. Una ventaja más que obtiene con este código ViewBag.Title = "something", puede establecer el título dentro de la vista o en el controlador, ambos funcionarán. –

1

Para mí, personalmente, creo que este caso es un uso aceptable de ViewBag. Está limitado a una propiedad "conocida" y es probable que no cause ningún problema en el futuro. Al final, se trata de ser pragmático y encontrar la manera de ser lo más rápido posible. Tener una clase base donde necesitas establecer el título sería, en mi opinión, demasiado código para que valga la pena el tipo de seguridad.

¡Buena suerte!

1

diría que mientras que es sólo el título que desea configurar, es aceptable utilizar la ViewBag. Bueno, tal vez no solo, como máximo 2-3 propiedades.

Pero si usted comienza a ver que está configurando cada vez más propiedades (común) en cada acción del controlador, me gustaría ir con un inflexible "clase ViewModelBase". Pero soy solo yo.

7

ViewBag por el título está perfectamente bien (yo incluso diría que es el propósito de tener ViewBag) - dinámica no es el mal absoluto. El "Título" es bien conocido, es poco probable que cambie e incluso esté predefinido en las plantillas de visualización.Yo personalmente uso el título siguiente:

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

Si usted está preocupado por escribir mal ViewBag.Title puede hacerlo fuerte tipo mediante la creación personalizada WebViewPage pero todavía tendrá que utilizar ViewBag o tal vez HttpContext.Items en el interior de este inmueble inflexible porque hay múltiples instancias de WebViewPage creadas durante la representación de IIRC.

lo recomiendo seguir con ViewBag, creando propia WebViewPage debido a esto parece un exceso - incluso la creación de una sola propiedad en ella si ya tiene la costumbre WebViewPage es en mi opinión es simplemente complicación inútil - y que proviene de una persona que es a menudo superengineering cosas.

+0

O simplemente ' @ (ViewBag.Title ?? ViewBag.Title +" | ") Nombre del sitio' para mantenerlo lo más corto posible. – schaermu

+0

@schaermu su sugerencia no funciona, resulta en '| Nombre del sitio' si la propiedad Título no se ha configurado. –

1

preferimos la configuración de título fuerte ... pocas muestras de nuestra clase BaseController. (Página define encapsulado vista 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); 
} 
1

No hay nada malo con el uso ViewBag.Title = "Mi título";

Todo lo que está haciendo es usar una propiedad dinámica.

La pregunta es realmente dónde debe "declararse" la información.

Es decir, ¿dónde es más accesible para los fines a mano.

Si es por página, entonces ese es el lugar correcto.

Sin embargo, si el título de la página puede derivarse del Modelo, entonces debe hacerlo.

En este caso, probablemente usaría una clase base para el ViewModel que utiliza, y crearía una propiedad PageTitle allí que contenga la lógica para derivar el título de página de las propiedades en el Modelo.

Así:

<title>Model.PageTitle</title> 

En resumen, los caballos para los cursos y no tenga miedo de usar las propiedades dinámicas ... siempre y cuando usted entienda lo que son y lo que hacen.

2

me gusta crear atribuye un PageTitle ActionFilter en lugar de editar ViewBags individuales

uso: mantener a la vista la misma

<title>@ViewBag.Title</title> 

Para en todo el controlador de título de la página:

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

Para vistas individuales:

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

Código Atributo:

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

fácil de manejar y funciona como un encanto.

+0

El título de la página debe establecerse en la vista y no en el controlador. –

+0

¿Debería? ¿Supongamos que reutiliza una vista para cargar diferentes tipos de archivos? P.ej. MyFiles/UploadExcel, MyFiles/UploadCsv ... – nh43de

3

Tampoco uso el ViewBag, en absoluto.

En la parte superior de _Layout.shtml ...

@model <YourWebAppNameSpace>.Models.Base.EveryPageViewModel 

En _Layout.shtml ...

<title>@Model.Title</title> 

En su modelo ...

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

} 

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

En su acción de controlador

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