Last active
August 27, 2020 03:20
-
-
Save wmeints/c547209b69128e4ee537cb8f35c3a6dc to your computer and use it in GitHub Desktop.
A template service based on the ASP.NET Core razor engine
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
/// <summary> | |
/// Renders email content based on razor templates | |
/// </summary> | |
public interface ITemplateService | |
{ | |
/// <summary> | |
/// Renders a template given the provided view model | |
/// </summary> | |
/// <typeparam name="TViewModel"></typeparam> | |
/// <param name="filename">Filename of the template to render</param> | |
/// <param name="viewModel">View model to use for rendering the template</param> | |
/// <returns>Returns the rendered template content</returns> | |
Task<string> RenderTemplateAsync<TViewModel>(string filename, TViewModel viewModel); | |
} |
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
public class TemplateService: ITemplateService | |
{ | |
private IRazorViewEngine _viewEngine; | |
private readonly IServiceProvider _serviceProvider; | |
private readonly ITempDataProvider _tempDataProvider; | |
public TemplateService(IRazorViewEngine viewEngine, IServiceProvider serviceProvider, ITempDataProvider tempDataProvider) | |
{ | |
_viewEngine = viewEngine; | |
_serviceProvider = serviceProvider; | |
_tempDataProvider = tempDataProvider; | |
} | |
public async Task<string> RenderTemplateAsync<TViewModel>(string filename, TViewModel viewModel) | |
{ | |
var httpContext = new DefaultHttpContext | |
{ | |
RequestServices = _serviceProvider | |
}; | |
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); | |
using (var outputWriter = new StringWriter()) | |
{ | |
var viewResult = _viewEngine.FindView(actionContext, filename, false); | |
var viewDictionary = new ViewDataDictionary<TViewModel>(new EmptyModelMetadataProvider(), new ModelStateDictionary()) | |
{ | |
Model = viewModel | |
}; | |
var tempDataDictionary = new TempDataDictionary(httpContext, _tempDataProvider); | |
if (!viewResult.Success) | |
{ | |
throw new TemplateServiceException($"Failed to render template {filename} because it was not found."); | |
} | |
try | |
{ | |
var viewContext = new ViewContext(actionContext, viewResult.View, viewDictionary, | |
tempDataDictionary, outputWriter, new HtmlHelperOptions()); | |
await viewResult.View.RenderAsync(viewContext); | |
} | |
catch (Exception ex) | |
{ | |
throw new TemplateServiceException("Failed to render template due to a razor engine failure", ex); | |
} | |
return outputWriter.ToString(); | |
} | |
} | |
} |
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
/// <summary> | |
/// Gets thrown when the template service was unable to render the template | |
/// </summary> | |
public class TemplateServiceException: Exception | |
{ | |
/// <summary> | |
/// Initializes a new instance of <see cref="TemplateServiceException"/> | |
/// </summary> | |
/// <param name="message"></param> | |
public TemplateServiceException(string message) : base(message) | |
{ | |
} | |
/// <summary> | |
/// Initializes a new instance of <see cref="TemplateServiceException"/> | |
/// </summary> | |
/// <param name="message"></param> | |
/// <param name="innerException"></param> | |
public TemplateServiceException(string message, Exception innerException) : base(message, innerException) | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In rendering the view I use Viewbag and javascript in the view. Is that something that can be used as well and how do I specify those?
any thoughts? ideas?