Last active
June 8, 2018 06:19
-
-
Save alonstar/5cb4a81a9200b7756bd04a8ecd6eb97f to your computer and use it in GitHub Desktop.
for ASP.NET CORE 2.0 Email Render
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Threading.Tasks; | |
namespace Services | |
{ | |
public interface IViewRenderService | |
{ | |
Task<string> RenderToStringAsync(string viewName); | |
Task<string> RenderToStringAsync<TModel>(string viewName, TModel model); | |
string RenderToString<TModel>(string viewPath, TModel model); | |
string RenderToString(string viewPath); | |
} | |
public class ViewRenderService : IViewRenderService | |
{ | |
private readonly IRazorViewEngine _viewEngine; | |
private readonly ITempDataProvider _tempDataProvider; | |
private readonly IServiceProvider _serviceProvider; | |
private readonly IHttpContextAccessor _httpContextAccessor; | |
public ViewRenderService(IRazorViewEngine viewEngine, IHttpContextAccessor httpContextAccessor, | |
ITempDataProvider tempDataProvider, | |
IServiceProvider serviceProvider) | |
{ | |
_viewEngine = viewEngine; | |
_httpContextAccessor = httpContextAccessor; | |
_tempDataProvider = tempDataProvider; | |
_serviceProvider = serviceProvider; | |
} | |
public string RenderToString<TModel>(string viewPath, TModel model) | |
{ | |
try | |
{ | |
var viewEngineResult = _viewEngine.GetView("~/", viewPath, false); | |
if (!viewEngineResult.Success) | |
{ | |
throw new InvalidOperationException($"Couldn't find view {viewPath}"); | |
} | |
var view = viewEngineResult.View; | |
using (var sw = new StringWriter()) | |
{ | |
var viewContext = new ViewContext() | |
{ | |
HttpContext = _httpContextAccessor.HttpContext ?? new DefaultHttpContext { RequestServices = _serviceProvider }, | |
ViewData = new ViewDataDictionary<TModel>(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = model }, | |
Writer = sw | |
}; | |
view.RenderAsync(viewContext).GetAwaiter().GetResult(); | |
return sw.ToString(); | |
} | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception("Error ending email.", ex); | |
} | |
} | |
public async Task<string> RenderToStringAsync<TModel>(string viewName, TModel model) | |
{ | |
var httpContext = _httpContextAccessor.HttpContext ?? new DefaultHttpContext { RequestServices = _serviceProvider }; | |
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); | |
using (var sw = new StringWriter()) | |
{ | |
var viewResult = _viewEngine.FindView(actionContext, viewName, false); | |
// Fallback - the above seems to consistently return null when using the EmbeddedFileProvider | |
if (viewResult.View == null) | |
{ | |
viewResult = _viewEngine.GetView("~/", viewName, false); | |
} | |
if (viewResult.View == null) | |
{ | |
throw new ArgumentNullException($"{viewName} does not match any available view"); | |
} | |
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(); | |
} | |
} | |
public string RenderToString(string viewPath) | |
{ | |
return RenderToString(viewPath, string.Empty); | |
} | |
public Task<string> RenderToStringAsync(string viewName) | |
{ | |
return RenderToStringAsync<string>(viewName, string.Empty); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
example: