/
ViewRenderer.cs
93 lines (77 loc) · 3.59 KB
/
ViewRenderer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Westwind.AspNetCore.Properties;
namespace Westwind.AspNetCore.Views
{
/// <summary>
/// Allows you to render a view to string.
/// </summary>
public class ViewRenderer
{
/// <summary>
/// Renders a view to string.
/// </summary>
/// <param name="viewName">Name of the view to render. Use Controller relative view name syntax</param>
/// <param name="model">Model data to pass in</param>
/// <param name="controllerContext">A controller context needed to process this View</param>
/// <param name="isPartial">Renders either a partial or main page (default)</param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static async Task<string> RenderViewToStringAsync(
string viewName, object model,
ControllerContext controllerContext,
bool isPartial = false)
{
var actionContext = controllerContext as ActionContext;
var serviceProvider = controllerContext.HttpContext.RequestServices;
var razorViewEngine = serviceProvider.GetService(typeof(IRazorViewEngine)) as IRazorViewEngine;
if (razorViewEngine == null)
throw new InvalidOperationException( Resources.RazorViewEngineNotAvailable);
var tempDataProvider = serviceProvider.GetService(typeof(ITempDataProvider)) as ITempDataProvider;
using (var sw = new StringWriter())
{
var viewResult = razorViewEngine.FindView(actionContext, viewName, !isPartial);
if (viewResult?.View == null)
{
throw new ArgumentException(string.Format(Resources.ViewNameDoesNotMatchAvailableView,viewName));
}
var viewDictionary =
new ViewDataDictionary(new EmptyModelMetadataProvider(),
new ModelStateDictionary())
{ Model = model };
var viewContext = new ViewContext(
actionContext,
viewResult.View,
viewDictionary,
new TempDataDictionary(actionContext.HttpContext, tempDataProvider),
sw,
new HtmlHelperOptions()
);
await viewResult.View.RenderAsync(viewContext);
return sw.ToString();
}
}
/// <summary>
/// Creates a controller context from a base Url and without an Http Context
/// </summary>
/// <param name="baseUrl"></param>
/// <returns></returns>
public static ControllerContext CreateControllerContext(string baseUrl)
{
var httpContext = new DefaultHttpContext();
var currentUri = new Uri(baseUrl); // Here you have to set your url if you want to use links in your email
httpContext.Request.Scheme = currentUri.Scheme;
httpContext.Request.Host = HostString.FromUriComponent(currentUri);
var actionContext = new ActionContext(httpContext, new Microsoft.AspNetCore.Routing.RouteData(), new Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor());
return new ControllerContext(actionContext);
}
}
}