I would like to render a PartialView to an HTML string so I can return it to a SignalR ajax request.
Something like:
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>
My problem is that I can't seem to render a PartialView outside of a Controller. Is it even possible to render a PartialView outside of a Controller? It would be very nice to still be able to leverage the awesome HTML generating abilities that come with Razor.
Am I going about this all wrong? Is there another way?
Here, this is what I use in Controllers for ajax, I modified it a bit so it can be called from method instead of controller, method returnView
renders your view and returns HTML string so you can insert it with JS/jQuery into your page when you recive it on client side:
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));
}
I didn't test it on a Hub but it should work.
Probably the best choice is to use RazorEngine, as Wim is suggesting.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With