2011-05-25 11 views

Respuesta

36

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 de 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.

  • infraestructura Logging pertenece en un constructor y debe inyectarse a través de un marco DI.

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

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

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

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

Los controladores de 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; } que introducir un acoplamiento ajustado que afecte la aplicación de maneras mucho más significativas.

Incluso algo así como una Id. De usuario o una clave multiusuario puede ir en una ControladorFactory en lugar de un controlador base. El costo de acoplamiento de una clase de controlador base simplemente no lo vale.

+2

Ok podemos hacer cosas sin usar el controlador base. Podría decirnos algunas desventajas de usar el controlador base – Tassadaque

+6

@ Tassaque - Acoplamiento, acoplamiento, acoplamiento y acoplamiento. – jfar

+29

No estoy convencido. Prefiere tener el mismo código en todos sus controladores que tener un controlador base, por lo que debe haber una ventaja. Usted dice que la ventaja es el "acoplamiento flexible", pero ¿qué significa eso exactamente, qué problemas resuelve, qué hace, excepto el desacoplamiento en aras del desacoplamiento? – Stijn

3

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

También tengo un objeto de aplicación que contiene cosas como el nombre de la aplicación, etc y tengo acceso que a partir de la clase base

Esencialmente lo uso para cosas repito mucho

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

2

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 colocar 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 inicializa de forma coherente.

+2

No es cierto que ActionFilters solo se pueda inicializar con constantes. La inicialización de constantes es una característica de Atributos, en lugar de la interfaz IActionFilter. Puede crear su filtro de acción y luego asignarlo a GlobalFilterCollection en su configuración de filtro, o donde sea que maneje tales cosas. En su filtro, simplemente verificaría la existencia de un atributo separado que creó, antes de continuar con la lógica del filtro. – crush

7

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

En lugar de decorar cada acción con el atributo "Autorizar", hago la 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. Good practice to do common authorization in a custom controller factory?

1

Utilizamos el BaseController por dos cosas:

  1. atributos que se deben aplicar a todos los controladores.
  2. 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.
+0

su segundo punto no es muy claro.cómo anular la redirección en el controlador base? vendría con algún ejemplo de cómo hacerlo. Me educaría si fuera posible acerca de cómo los ataques de redirección abiertos suceden y cómo se puede evitar por clase base con el ejemplo. gracias – Mou

+0

1) Esto podría hacerse con [filtros registrados globalmente] (https://msdn.microsoft.com/en-us/library/gg416513 (VS.98) .aspx) en su lugar. Aún mejor, los filtros personalizados pueden usar atributos personalizados para excluirlos condicionalmente (lo que sería una pesadilla mantener en un controlador base con anulación). 2) Esta lógica aislada podría colocarse en un método de extensión de la clase 'Controller'. No es necesario heredar un controlador base personalizado en todas partes (ni preocuparse por eventualmente olvidarse de hacerlo en alguna parte). – NightOwl888

0

lo que hice fue utilizar una clase base del controlador genérico de manejar:

  • creé BaseCRUDController<Key,Model> que requirió un objeto ICRUDService<TModel> como parámetro constructor por lo que la clase base manejará Crear/Editar/Eliminar. y seguro que en modo virtual de manejar en situaciones personalizados
  • El ICRUDService<TModel> tiene métodos como Guardar/actualización/Eliminar/Encuentra/ResetChache/... y lo apliquen para cada repositorio creo entonces puedo agregarle más funcionalidad.
  • usando esta estructura podría añadir alguna funcionalidad general, como PagedList/Autocompletar/ResetCache/IncOrder & decodificador (si el modelo es IOrderable)
  • Error/Notificación manejo de mensajes : una parte en el diseño con el código @TempData["MHError"] y una propiedad en el controlador base como

    pu error de notificación blic { conjunto {TempData ["MHError"] = valor; } get {return (Notificación) TempData.Peek ("MHError"); }}

Con esta clases abstractas que fácilmente podría manejar métodos que tenía que escribir cada vez o crear con el generador de código. Pero este enfoque también tiene debilidad.

1

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.

2

He utilizado el controlador de base en muchos de mis proyectos y he trabajado fantásticamente. Yo sobre todo utilizado para

  • registro de excepciones
  • Notificación (éxito, error, añadiendo ..)
  • Invocando Http404 manejo de errores
+0

¿me redirigiría a algunos artículos como cómo manejar su situación por el controlador base. las situaciones son como 'Exception logging, Notification (success, error, adding ...) y HTTP404 error handling' gracias – Mou

0

filtro no es seguro para subprocesos, la condición de la base de datos de acceso y Inyección de dependencia, las conexiones de la base de datos pueden cerrarse por otro hilo al usarlo.

Cuestiones relacionadas