Encontré que los controles de usuario son increíblemente útiles cuando se trabaja con formularios web ASP.NET. Al encapsular el código requerido para mostrar un control con el marcado, la creación de componentes reutilizables fue muy directa y muy, muy útil.ASP.NET MVC: ¿Buena sustitución para el control del usuario?
Si bien MVC proporciona una conveniente separación de preocupaciones, esto parece romper la encapsulación (es decir, puede agregar un control sin agregar o usar su código de soporte, lo que lleva a errores de tiempo de ejecución). Tener que modificar un controlador cada vez que agrego un control a una vista me parece que integra preocupaciones, no separarlas. Prefiero romper la ideología purista de MVC que renunciar a los beneficios de los controles reutilizables empaquetados.
Necesito poder incluir componentes similares a los controles de usuario de formularios web en todo el sitio, pero no para todo el sitio, y no en un nivel que pertenece a una página maestra. Estos componentes deberían tener su propio código, no solo marcado (para interactuar con la capa empresarial), y sería genial si el controlador de la página no necesitara saber sobre el control. Como los controles de usuario de MVC no tienen código subyacente, no veo una buena manera de hacerlo.
Actualización FINALMENTE, una buena (y, en retrospectiva, obvia) forma de lograr esto.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace K.ObjectModel.Controls
{
public class TestControl : ViewUserControl
{
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
writer.Write("Hello World");
base.Render(writer);
}
}
}
crear una nueva clase que hereda ViewUserControl
Reemplazar el método .Render()
como se muestra arriba.
registrar el control a través de su ASCX asociada como lo haría en un formulario web:
<%@ Register TagName="tn" TagPrefix="k" Src="~/Views/Navigation/LeftBar.ascx"%>
utilizar la etiqueta correspondiente en cualquier punto de vista o página maestra que necesita:
<k:tn runat="server"/>
Asegúrese de que su .ascx herede su nuevo control:
<%@ Control Language="C#" Inherits="K.ObjectModel.Controls.TestControl" %>
Voila, ya está en marcha. Esto se prueba con ASP.NET MVC 2, VS 2010 y .NET 4.0.
Su etiqueta personalizada hace referencia a la vista parcial ascx, que hereda de la clase TestControl. Luego, el control anula el método Render()
, que se llama para representar la vista, lo que le brinda control total sobre el proceso desde la etiqueta hasta la salida.
La diferencia entre utilizar este enfoque y llamar a Html.RenderPartial()
o `Html.RenderAction() 'es agregar el control a una vista que se realiza con una etiqueta tipo webforms, que no solo es más cómoda para los diseñadores, sino que también tener que estar al tanto de los nombres y métodos de los controladores. El nombre de la clase de control está aislado en ASCX, lo que facilita la colocación de estos en un ensamblaje y su reutilización en proyectos separados.
Algunos pueden decir que esto infringe el SoC, pero creo que este enfoque es funcionalmente equivalente a vincular una vista parcial y un controlador al mismo tiempo manteniendo un marcado limpio. Sin embargo, debe quedar claro que aún le corresponde al desarrollador mantener solo la lógica relacionada con la presentación en el control. La lógica de acceso a datos y negocios aún pertenece a sus respectivas capas.
Argh ... Su edición es frustrante ya que ha cambiado su pregunta. los "controles reutilizables y empaquetados" con MVC viven en un mundo totalmente diferente a RenderPartial y RenderAction. - Lo que comienza a hablar es el debate/discusión RenderPartial vs. RenderAction que se ha respondido anteriormente y es principalmente un argumento filosófico sobre las responsabilidades del código. – jfar
@jfar ?? He agregado la sección de "opciones" porque eso es lo que todos parecen ofrecer como soluciones. Si tienes una idea mejor, estaría encantado de escucharla. –
@David Lively: no puede comparar las opciones RenderPartial y Portable Areas sin definir el alcance de la solución que intenta resolver. Es como decir "¿cómo debo matar a este insecto, el matamoscas, el bate de béisbol o el arma nuclear desde la órbita" sin decirle a la persona que le pregunta si está tratando de matar a un mosquito o una especie alienígena sintética con sangre ácida? Cuando dices "controles reutilizables y empaquetados" estás hablando de un gran problema, pero si incluyes RenderPartial como opción, dices "reutilización de marcado simple". ¿Cuál es? ¿Qué tipo de error estás tratando de matar? – jfar