Varias de mis acciones de controlador tienen un conjunto estándar de comportamiento de manejo de fallas. En general, quiero:Creación de ViewResults fuera de los controladores en ASP.NET MVC
- Cargar un objeto basado en los datos de ruta (identificadores y similares)
- Si los datos de ruta no apunta a un objeto válido (por ejemplo: a través de la URL piratería) a continuación, informar al usuario del problema y devolver un HTTP 404 no encontrado
- validar que el usuario actual tiene los permisos adecuados en el objeto
- Si el usuario no tiene permiso, informar al usuario del problema y devolver un HTTP 403 Prohibido
- Si lo anterior es exitoso, entonces haga algo con ese objeto que sea específico de la acción (es decir: renderízalo en una vista).
Estos pasos están tan estandarizados que quiero tener código reutilizable para implementar el comportamiento.
Mi plan actual de ataque era tener un método de ayuda a hacer algo como esto:
public static ActionResult HandleMyObject(this Controller controller,
Func<MyObject,ActionResult> onSuccess) {
var myObject = MyObject.LoadFrom(controller.RouteData).
if (myObject == null) return NotFound(controller);
if (myObject.IsNotAllowed(controller.User)) return NotAllowed(controller);
return onSuccess(myObject);
}
# NotAllowed() is pretty much the same as this
public static NotFound(Controller controller){
controller.HttpContext.Response.StatusCode = 404
# NotFound.aspx is a shared view.
ViewResult result = controller.View("NotFound");
return result;
}
El problema aquí es que Controller.View() es un método protegido y por lo tanto no es accesible desde un ayudante . He considerado crear una nueva instancia de ViewResult explícitamente, pero hay suficientes propiedades para establecer que soy cauteloso al hacerlo sin conocer las trampas primero.
¿Cuál es la mejor manera de crear un ViewResult desde fuera de un controlador en particular?
+1: Así es como lo haría. –
Lo que no me gusta de esto es que significa que un controlador solo puede tener un conjunto de comportamiento de acción compartido: el que hereda (solo). Para este ejemplo en particular, no es un problema, pero puedo ver que se vuelve mucho más difícil a medida que el proyecto crece. –
Me di cuenta de que su pregunta tiene años, pero pensé que mencionaría otra posibilidad. Podría exponer una versión pública de 'View()' llamada 'GetView()' en su controlador base, luego podría mantener su ayudante en una clase separada. Todavía necesitarías pasar tu controlador a tu ayudante, lo cual es un poco incómodo, pero permite la composición en lugar de la herencia. – devuxer