sintaxis net mvc example asp asp.net-mvc asp.net-mvc-5

asp.net mvc - net - Vista de renderizado de MVC 5 a cadena



render partial view mvc 5 example (4)

Parece que la mayoría del código para representar la vista en una cadena no funciona en MVC 5.

Tengo las últimas plantillas MVC 5.1.2 y estoy tratando de convertir la vista en una cadena.

public static String RenderViewToString(ControllerContext context, String viewPath, object model = null) { context.Controller.ViewData.Model = model; using (var sw = new StringWriter()) { var viewResult = ViewEngines.Engines.FindView(context, viewPath, null); var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData, context.Controller.TempData, sw); viewResult.View.Render(viewContext, sw); viewResult.ViewEngine.ReleaseView(context, viewResult.View); return sw.GetStringBuilder().ToString(); } }

Bueno, está funcionando pero su salida contiene muchas marcas $ en lugar de etiquetas. Leí algo sobre que estaba arreglado en la versión RC, pero esa es una vieja noticia.

El problema se ve así

<$A$><h1></h1> <table</$A$><$B$> class=""</$B$><$C$>> <tbody</$C$><$D$></$D$><$E$>></tbody> </table></$E$>

Me gustaría preguntar, ¿cómo renderizar vistas en cadena en la última plantilla de MVC 5? Gracias.


La respuesta de @ wh1sp3r funciona pero para vistas parciales tuve que hacer los siguientes cambios menores:

string html = FakeController.RenderViewToString("**Controllername**", "~/views/**Controllername**/_AsdfPartialPage.cshtml", fem); public static string RenderViewToString(string controllerName, string viewName, object viewData) { using (var writer = new StringWriter()) { var routeData = new RouteData(); routeData.Values.Add("controller", controllerName); var fakeControllerContext = new ControllerContext(new HttpContextWrapper(new HttpContext(new HttpRequest(null, "http://localhost", null), new HttpResponse(null))), routeData, new FakeController()); var razorViewEngine = new RazorViewEngine(); //var razorViewResult = razorViewEngine.FindView(fakeControllerContext, viewName, "", false); var razorViewResult = razorViewEngine.FindPartialView(fakeControllerContext, viewName, false); var viewContext = new ViewContext(fakeControllerContext, razorViewResult.View, new ViewDataDictionary(viewData), new TempDataDictionary(), writer); razorViewResult.View.Render(viewContext, writer); return writer.ToString(); } }


La siguiente es la solución que funciona con sesión y áreas en MVC5.

public class FakeController : ControllerBase { protected override void ExecuteCore() { } public static string RenderViewToString(string controllerName, string viewName,string areaName, object viewData,RequestContext rctx) { try { using (var writer = new StringWriter()) { var routeData = new RouteData(); routeData.Values.Add("controller", controllerName); routeData.Values.Add("Area", areaName); routeData.DataTokens["area"] = areaName; var fakeControllerContext = new ControllerContext(rctx, new FakeController()); //new ControllerContext(new HttpContextWrapper(new HttpContext(new HttpRequest(null, "http://google.com", null), new HttpResponse(null))), routeData, new FakeController()); fakeControllerContext.RouteData = routeData; var razorViewEngine = new RazorViewEngine(); var razorViewResult = razorViewEngine.FindView(fakeControllerContext, viewName, "", false); var viewContext = new ViewContext(fakeControllerContext, razorViewResult.View, new ViewDataDictionary(viewData), new TempDataDictionary(), writer); razorViewResult.View.Render(viewContext, writer); return writer.GetStringBuilder().ToString(); //use example //String renderedHTML = RenderViewToString("Email", "MyHTMLView", myModel ); //where file MyHTMLView.cstml is stored in Views/Email/MyHTMLView.cshtml. Email is a fake controller name. } } catch (Exception ex) { //do your exception handling here } } }

Así es como llamas a esto desde otro controlador.

var modal = getModal(params); return FakeController.RenderViewToString(controllerName, viewName, areaName, modal, this.Request.RequestContext);

Usando requestcontext podemos pasar fácilmente la sesión actual en fakecontroller y hacer una cadena de afeitar.


Ok, parece que encontré una solución. El autor de la idea es Yakir Manor.

class FakeController : ControllerBase { protected override void ExecuteCore() { } public static string RenderViewToString(string controllerName, string viewName, object viewData) { using (var writer = new StringWriter()) { var routeData = new RouteData(); routeData.Values.Add("controller", controllerName); var fakeControllerContext = new ControllerContext(new HttpContextWrapper(new HttpContext(new HttpRequest(null, "http://google.com", null), new HttpResponse(null))), routeData, new FakeController()); var razorViewEngine = new RazorViewEngine(); var razorViewResult = razorViewEngine.FindView(fakeControllerContext, viewName, "", false); var viewContext = new ViewContext(fakeControllerContext, razorViewResult.View, new ViewDataDictionary(viewData), new TempDataDictionary(), writer); razorViewResult.View.Render(viewContext, writer); return writer.ToString(); } } }

Es un truco con contexto falso y respuesta.

Ejemplo:

String renderedHTML = RenderViewToString("Email", "MyHTMLView", myModel );

Mi archivo MyHTMLView.cstml se almacena en Views / Email / MyHTMLView.cshtml. El correo electrónico es un nombre de controlador falso.


Tuve la necesidad inmediata de devolver 6 vistas parciales como cadenas en un objeto JSON. En lugar de crear un método estático y pasar todos los parámetros innecesarios, decidí agregar métodos protegidos a nuestra clase ControllerBase que se deriva de Controller, y se utiliza como la clase base para todos nuestros controladores.

Aquí hay una clase ControllerBase completamente funcional que proporciona esta funcionalidad y funciona de manera muy similar a los métodos PartialView () y View () que están en la clase Controller. Incluye las adiciones de @Alok.

public abstract class ControllerBase : Controller { #region PartialViewToString protected string PartialViewToString(string partialViewName, object model = null) { ControllerContext controllerContext = new ControllerContext(Request.RequestContext, this); return ViewToString( controllerContext, ViewEngines.Engines.FindPartialView(controllerContext, partialViewName) ?? throw new FileNotFoundException("Partial view cannot be found."), model ); } #endregion #region ViewToString protected string ViewToString(string viewName, object model = null) { ControllerContext controllerContext = new ControllerContext(Request.RequestContext, this); return ViewToString( controllerContext, ViewEngines.Engines.FindView(controllerContext, viewName, null) ?? throw new FileNotFoundException("View cannot be found."), model ); } protected string ViewToString(string viewName, string controllerName, string areaName, object model = null) { RouteData routeData = new RouteData(); routeData.Values.Add("controller", controllerName); if (areaName != null) { routeData.Values.Add("Area", areaName); routeData.DataTokens["area"] = areaName; } ControllerContext controllerContext = new ControllerContext(HttpContext, routeData, this); return ViewToString( controllerContext, ViewEngines.Engines.FindView(controllerContext, viewName, null) ?? throw new FileNotFoundException("View cannot be found."), model ); } #endregion #region Private Methods private string ViewToString(ControllerContext controllerContext, ViewEngineResult viewEngineResult, object model) { using (StringWriter writer = new StringWriter()) { ViewContext viewContext = new ViewContext( ControllerContext, viewEngineResult.View, new ViewDataDictionary(model), new TempDataDictionary(), writer ); viewEngineResult.View.Render(viewContext, writer); return writer.ToString(); } } #endregion }