2011-04-03 13 views
5

Así que, básicamente, tengo una vista parcial que puede construir una buena mesa para mí. Me gustaría enviar esta tabla cada semana a mis usuarios. En lugar de tener que copiar básicamente la plantilla nuevamente, me gustaría reenviar mi modelo al controlador y recibir el correspondiente HTML generado como String.Renderizar parcial a cadena en el controlador o en otro lugar

Es posible hacer esto en un controlador, creo que debería ser un proceso bastante simple.

+0

añadido una etiqueta para asp.net - esto es asp.net, ¿derecho? Es realmente útil si los encuestadores etiquetan las preguntas con la plataforma o la tecnología que utilizan, de modo que los que responden pueden decir de un vistazo si esto es algo que pueden ayudar. Soy un chico de Java, así que no puedo, pero tuve que venir aquí, leer la pregunta, adivinar y google antes de saber que no iba a ser de ninguna utilidad. –

+0

gracias, lo siento. realmente no estaba concentrándose! sí, esto es asp.net mvc – Steve

+0

http://stackoverflow.com/questions/483091/render-a-view-as-a-string/2759898#2759898 – dotjoe

Respuesta

0

Mire en el proyecto MvcMailer. Junto con una vista parcial que rinde su tabla, debería ser capaz de juntar fácilmente correos electrónicos con sus tablas.

+0

¿cómo podría utilizar esto si no fuera a envíelo por correo electrónico. Digamos que tal vez quería pasar el control a la página? – Steve

+0

@Steve - Supongo que utilizaría la lógica condicional para procesar con el programa de correo o para obtener una vista normal. – tvanfosson

4

Si busca renderizar vistas parciales en cadenas, también encontrará algunas buenas pistas. Eso es lo que hice para llegar a la siguiente método de extensión para la clase ControllerBase:

public static string RenderPartialViewToString(this ControllerBase controller, string partialPath, ViewDataDictionary viewData = null) 
{ 
    if(string.IsNullOrEmpty(partialPath)) 
     partialPath = controller.ControllerContext.RouteData.GetRequiredString("action"); 

    using(StringWriter sw = new StringWriter()) 
    { 
     ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialPath); 

     ViewContext viewContext = new ViewContext(controller.ControllerContext, 
      viewResult.View, 
      (viewData == null) ? controller.ViewData : viewData, 
      controller.TempData, 
      sw); 

     // copy retVal state items to the html helper 
     foreach(var item in viewContext.Controller.ViewData.ModelState) 
     { 
      if(!viewContext.ViewData.ModelState.Keys.Contains(item.Key)) 
       viewContext.ViewData.ModelState.Add(item); 
     } 

     viewResult.View.Render(viewContext, sw); 

     return sw.GetStringBuilder().ToString(); 
    } 
} 

Conceptualmente, el procedimiento a seguir consiste en utilizar los ViewEngines definidos para su aplicación para encontrar una vista parcial por su nombre. A continuación, crea un ViewContext fuera de ese parcial y copia las diversas propiedades del estado del modelo.

El código asigna un ViewDataDictionary opcional que puede proporcionar al ViewContext. Si no proporciona el ViewDataDictionary, toma el ViewDataDictionary definido para el controlador contra el que está siendo invocado.

Lo que esto significa es que puede definir valores ViewData (o propiedades ViewBag) directamente en su controlador y luego llamar al método de extensión - que aplicará esas propiedades ViewData/ViewBag al parcial cuando se procesa - o puede crear un objeto ViewDataDictionary separado en su método de acción y pasarlo al método de extensión. El primero es más rápido/más fácil, pero "contamina" ViewData para su método de acción, mientras que el segundo tarda un poco más en configurarse, pero le permite mantener sus datos de vista parcial separados del ViewData de su método de acción.

0

Render a view as a string

que utilizar algo tan simple como el anterior pero casi siempre crear vistas separadas para los mensajes de correo electrónico. Principalmente debido a la necesidad de usar enlaces absolutos e insertar el CSS en la cabeza.

14

poner esto en un archivo de Ayudante:

public static string RenderViewToString(ControllerContext context, string viewName, object model) 
     { 
      if (string.IsNullOrEmpty(viewName)) 
       viewName = context.RouteData.GetRequiredString("action"); 

      ViewDataDictionary viewData = new ViewDataDictionary(model); 

      using (StringWriter sw = new StringWriter()) 
      { 
       ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName); 
       ViewContext viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw); 
       viewResult.View.Render(viewContext, sw); 

       return sw.GetStringBuilder().ToString(); 
      } 
     } 

Y luego desde el controlador se le puede llamar así:

var order = orderService.GetOrder(id); 

var orderPrint = MyHelper.RenderViewToString(this.ControllerContext, "_OrderView", order); 
+0

esto funcionó para mí. +1! –

Cuestiones relacionadas