tutorial net mvc example asp c# asp.net-mvc asp.net-mvc-3 partial-views signalr

c# - net - Renderizar MVC PartialView en la respuesta de SignalR



signalr asp net example (6)

¿Has pensado en utilizar un motor de plantilla de afeitar como http://razorengine.codeplex.com/ ? No puede usarlo para analizar vistas parciales, pero puede usarlo para analizar las plantillas de afeitar, que son casi similares a las vistas parciales.

Me gustaría presentar un PartialView en una cadena HTML para que pueda devolverlo a una solicitud SignalR ajax.

Algo como:

SignalR Hub (mySignalHub.cs)

public class mySignalRHub: Hub { public string getTableHTML() { return PartialView("_MyTablePartialView", GetDataItems()) // *How is it possible to do this* } }

Razor PartialView (_MyTablePartialView.cshtml)

@model IEnumerable<DataItem> <table> <tbody> @foreach (var dataItem in Model) { <tr> <td>@dataItem.Value1</td> <td>@dataItem.Value2</td> </tr> } </tbody> </table>

HTML (MySignalRWebPage.html)

<Script> ... //Get HTML from SignalR function call var tableHtml = $.connection.mySignalRHub.getTableHTML(); //Inject into div $(''#tableContainer).html(tableHtml); </Script> <div id="tableContainer"></div>

Mi problema es que parece que no puedo renderizar una vista parcial fuera de un controlador. ¿Es incluso posible renderizar una vista parcial fuera de un controlador? Sería muy agradable poder aprovechar las increíbles capacidades generadoras de HTML que vienen con Razor.

¿Me estoy equivocando? ¿Hay otra manera?


¿Qué tal el uso de RazorEngineHost y RazorTemplateEngine ? Encontré este lindo artículo que podría ser lo que estás buscando. Se trata de alojar Razor fuera de ASP.NET (MVC).


Además de la respuesta proporcionada por @ user1010609 anterior, he tenido problemas con esto y he terminado con una función que devuelve el PartialView renderizado dado el nombre de un controlador, la ruta a la vista y el modelo.

Toma en cuenta el hecho de que no tiene un controlador y, por lo tanto, ninguno del estado habitual proviene de un evento SignalR.

public static string RenderPartialView(string controllerName, string partialView, object model) { var context = new HttpContextWrapper(System.Web.HttpContext.Current) as HttpContextBase; var routes = new System.Web.Routing.RouteData(); routes.Values.Add("controller", controllerName); var requestContext = new RequestContext(context, routes); string requiredString = requestContext.RouteData.GetRequiredString("controller"); var controllerFactory = ControllerBuilder.Current.GetControllerFactory(); var controller = controllerFactory.CreateController(requestContext, requiredString) as ControllerBase; controller.ControllerContext = new ControllerContext(context, routes, controller); var ViewData = new ViewDataDictionary(); var TempData = new TempDataDictionary(); ViewData.Model = model; using (var sw = new StringWriter()) { var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialView); var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } }

Lo llamarías con algo similar a:

RenderPartialView("MyController", "~/Views/MyController/_partialView.cshtml", model);


Aquí, esto es lo que uso en Controladores para ajax, lo modifiqué un poco para que pueda llamarse desde el método en lugar del controlador, el método returnView representa tu vista y devuelve una cadena HTML para que puedas insertarla con JS / jQuery en tu página cuando lo recibes por parte del cliente:

public static string RenderPartialToString(string view, object model, ControllerContext Context) { if (string.IsNullOrEmpty(view)) { view = Context.RouteData.GetRequiredString("action"); } ViewDataDictionary ViewData = new ViewDataDictionary(); TempDataDictionary TempData = new TempDataDictionary(); ViewData.Model = model; using (StringWriter sw = new StringWriter()) { ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(Context, view); ViewContext viewContext = new ViewContext(Context, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } //"Error" should be name of the partial view, I was just testing with partial error view //You can put whichever controller you want instead of HomeController it will be the same //You can pass model instead of null private string returnView() { var controller = new HomeController(); controller.ControllerContext = new ControllerContext(HttpContext,new System.Web.Routing.RouteData(), controller); return RenderPartialToString("Error", null, new ControllerContext(controller.Request.RequestContext, controller)); }

No lo probé en un Hub, pero debería funcionar.


En función de las respuestas proporcionadas a la siguiente pregunta similar, sugeriría utilizar

Html.Partial ( partialViewName )

Devuelve un MvcHtmlString, que debería poder usar como contenido de su respuesta de SignalR. No he probado esto, sin embargo.

Pregunta de desbordamiento de pila: ¿es posible representar una vista fuera de un controlador?


Probablemente la mejor opción es usar RazorEngine , como sugiere Wim .

public class mySignalRHub: Hub { public string getTableHTML() { var viewModel = new[] { new DataItem { Value1 = "v1", Value2 = "v2" } }; var template = File.ReadAllText(Path.Combine( AppDomain.CurrentDomain.BaseDirectory, @"Views/PathToTablePartialView/_MyTablePartialView.cshtml")); return Engine.Razor.RunCompile(template, "templateKey", null, viewModel); } }