¿Cuáles son los buenos candidatos para la clase de controlador base en ASP.NET MVC?

He visto a mucha gente hablar sobre el uso de controladores base en sus proyectos ASP.NET MVC. Los ejemplos típicos que he visto hacen esto para el registro o quizás para el andamio CRUD. ¿Cuáles son algunos otros buenos usos de una clase de controlador base?

No hay buenos usos de una clase de controlador base.

Ahora escúchame.

Asp.Net MVC, especialmente MVC 3 tiene toneladas de ganchos de extensibilidad que proporcionan una forma más desacoplada para agregar funcionalidad a todos los controladores. Dado que las clases de sus controladores son muy importantes y centrales para una aplicación, es muy importante mantenerlas livianas, ágiles y poco relacionadas con todo lo demás.

  • La infraestructura de registro pertenece a un constructor y debe ser inyectada a través de un marco DI.

  • El andamiaje CRUD debe manejarse mediante la generación de código o un proveedor personalizado de metadatos.

  • El manejo de excepciones globales debe ser manejado por un ActionInvoker personalizado.

  • Los filtros y filtros de acción deben manejar los datos de la vista global y la autorización. Aún más fácil con los filtros de acción globales en MVC3.

  • Las constantes pueden ir en otra clase / archivo llamado ApplicationConstants o algo así.

Los controladores base suelen ser utilizados por desarrolladores de MVC inexpertos que no conocen todas las diferentes piezas de extensibilidad de MVC. Ahora no me malinterpreten, no estoy juzgando y trabajo con personas que los usan por todas las razones equivocadas. Es solo una experiencia que le brinda más herramientas para resolver problemas comunes.

Estoy casi seguro de que no hay un solo problema que no pueda resolver con otro gancho de extensibilidad que una clase de controlador base. No tome la forma más estricta de acoplamiento (herencia) a menos que exista una razón de productividad significativa y no viole a Liskov. Prefiero tomar el <1 segundo para escribir una propiedad 20 veces en mis controladores como public ILogger Logger { get; set; } public ILogger Logger { get; set; } public ILogger Logger { get; set; } que introduce un acoplamiento apretado que afecta la aplicación de maneras mucho más significativas.

Incluso algo como una clave de usuario o de multitarrendatario puede ir en un ControllerFactory en lugar de un controlador de base. El costo de acoplamiento de una clase de controlador base simplemente no lo vale.

Me gusta usar el controlador base para la autorización.

En lugar de decorar cada acción con el atributo “Autorizar”, hago una autorización en el controlador base. La lista de acciones autorizadas se obtiene de la base de datos para el usuario que ha iniciado sesión.

Lea el enlace a continuación para obtener más información sobre la autorización. ¿Buenas prácticas para hacer una autorización común en una fábrica de controladores personalizados?

Lo uso para acceder a la sesión, a los datos de la aplicación, etc.

También tengo un objeto de aplicación que contiene cosas como el nombre de la aplicación, etc. y accedo a eso desde la clase base

Esencialmente lo uso para cosas que repito mucho

Ah, debería mencionar que no lo uso para la lógica empresarial o el acceso a la base de datos. Las constantes son una apuesta bastante buena para una clase base también, supongo.

Utilicé el controlador base en muchos de mis proyectos y trabajé fantástico. Yo solía usar

  • Registro de excepciones
  • Notificación (éxito, error, adición …)
  • Invocando el manejo de errores HTTP404

Según mi experiencia, la mayor parte de la lógica que querría poner en un controlador base idealmente entraría en un filtro de acción. Los filtros de acción solo se pueden inicializar con constantes, por lo que en algunos casos simplemente no se puede hacer eso. En algunos casos, necesita la acción para aplicar a cada método de acción en el sistema, en cuyo caso puede tener más sentido poner su lógica en una base en lugar de anotar cada método de acción con un nuevo atributo actionFilter.

También me ha parecido útil poner en la base las propiedades que hacen referencia a los servicios (que de otro modo están desacoplados del controlador), lo que facilita su acceso e inicialización de forma coherente.

Usamos el BaseController por dos cosas:

  1. Atributos que deberían aplicarse a todos los Controladores.
  2. Una anulación de Redirect, que protege contra ataques de redirección abiertos al verificar que la URL de redirección sea una URL local. De esta forma, todos los controladores que llaman a Redirect están protegidos.

Estoy usando un controlador base ahora para la internacionalización usando la biblioteca i18N . Proporciona un método que puedo usar para localizar cualquier cadena dentro del controlador.

Lo que hice fue usar una clase base de controlador genérico para manejar:

  • BaseCRUDController que requiere un objeto ICRUDService como parámetro de constructor para que la clase base maneje Create / Edit / Delete . y seguro en modo virtual para manejar en situaciones personalizadas
  • El ICRUDService tiene métodos como Save / Update / Delete / Find / Reset Chache / … y lo implemento para cada repository que creo, así puedo agregarle más funcionalidades.
  • Usando esta estructura podría agregar algunas funcionalidades generales como PagedList / AutoComplete / ResetCache / IncOrder & DecOrder (si el modelo es IOrderable)
  • Manejo de mensajes de error / notificación : una parte en el diseño con el @TempData["MHError"] y una propiedad en la base Controlador como

    error de notificación pública {set {TempData [“MHError”] = valor; } get {return (Notification) TempData.Peek (“MHError”); }}

Con estas clases abstractas podría manejar fácilmente los métodos que tenía que escribir cada vez o crear con Code Generator. Pero este enfoque también tiene debilidad.

El filtro no es seguro para subprocesos, la condición del acceso a la base de datos y la dependency injection, las conexiones de la base de datos pueden cerrarse por otro hilo al usarlo.