Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A view Render for Razor (aspnetcore RC2)
public class HomeController : Controller {
private readonly ViewRender view;
public HomeController (ViewRender view) {
this.view = view
}
public string Test () {
// render ~/Views/Emails/ResetCode
var html = this.view.Render("Emails/ResetCode", new ResetCodeModel { Code : "123456" });
return html;
}
}
public class Startup {
// ....
public void ConfigureServices(IServiceCollection services)
{
// ....
services.AddScoped<ViewRender, ViewRender>();
}
}
using System;
using System.IO;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Routing;
namespace Forecast.Services
{
public class ViewRender
{
private IRazorViewEngine _viewEngine;
private ITempDataProvider _tempDataProvider;
private IServiceProvider _serviceProvider;
public ViewRender(
IRazorViewEngine viewEngine,
ITempDataProvider tempDataProvider,
IServiceProvider serviceProvider)
{
_viewEngine = viewEngine;
_tempDataProvider = tempDataProvider;
_serviceProvider = serviceProvider;
}
public string Render<TModel>(string name, TModel model)
{
var actionContext = GetActionContext();
var viewEngineResult = _viewEngine.FindView(actionContext, name, false);
if (!viewEngineResult.Success)
{
throw new InvalidOperationException(string.Format("Couldn't find view '{0}'", name));
}
var view = viewEngineResult.View;
using (var output = new StringWriter())
{
var viewContext = new ViewContext(
actionContext,
view,
new ViewDataDictionary<TModel>(
metadataProvider: new EmptyModelMetadataProvider(),
modelState: new ModelStateDictionary())
{
Model = model
},
new TempDataDictionary(
actionContext.HttpContext,
_tempDataProvider),
output,
new HtmlHelperOptions());
view.RenderAsync(viewContext).GetAwaiter().GetResult();
return output.ToString();
}
}
private ActionContext GetActionContext()
{
var httpContext = new DefaultHttpContext();
httpContext.RequestServices = _serviceProvider;
return new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
}
}
}
@simon25608
Copy link

simon25608 commented Jun 2, 2016

Hello, I render a template to a request by ajax post, I get the following exception System.ArgumentOutOfRangeException in line view.RenderAsync (ViewContext) .GetAwaiter () GetResult ().;

@pholly
Copy link

pholly commented Sep 8, 2016

Thanks for the code. I wish you would have referenced aspnet/Mvc#3091 and https://github.com/aspnet/Entropy/blob/dev/samples/Mvc.RenderViewToString/RazorViewToStringRenderer.cs where I assume the code is from.

@MatthewShelby
Copy link

MatthewShelby commented May 17, 2020

I just wana say thnx to anybody who worked on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment