Skip to content

Instantly share code, notes, and snippets.

@miensol
Created February 27, 2012 19:18
Show Gist options
  • Save miensol/1926431 to your computer and use it in GitHub Desktop.
Save miensol/1926431 to your computer and use it in GitHub Desktop.
Razor MediaTypeFormatter
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using RazorEngine;
using RazorEngine.Templating;
namespace RazorFromConsole
{
internal class RazorHtmlFormatter : MediaTypeFormatter
{
public static ConcurrentDictionary<string, Func<object, string>> Templates = new ConcurrentDictionary<string, Func<object,string>>();
public RazorHtmlFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
}
protected override bool CanWriteType(Type type)
{
return true;
}
protected override System.Threading.Tasks.Task OnWriteToStreamAsync(Type type, object value,
Stream stream, HttpContentHeaders contentHeaders,
FormatterContext formatterContext, TransportContext transportContext)
{
var task = Task.Factory.StartNew(() =>
{
var templateName = Path.Combine(".", "Views",
type.Name.Replace("ViewModel", "") +
".cshtml");
var rendered = RenderTemplate(templateName, value, type);
var streamWriter = new StreamWriter(stream);
streamWriter.Write(rendered);
streamWriter.Flush();
});
return task;
}
private string RenderTemplate(string templateName, object modelValue, Type type)
{
var templateRunner = Templates.GetOrAdd(templateName, (name) =>
{
try
{
var existingTemplate = Razor.Resolve(templateName);
if (existingTemplate == null && File.Exists(templateName))
{
var templateText = File.ReadAllText(templateName);
Razor.Compile(templateText, type, templateName);
}
if (existingTemplate == null && File.Exists(templateName))
{
Razor.Compile(
string.Format("not template found: {0}",
templateName), templateName);
}
}
catch (TemplateCompilationException ex)
{
Razor.Compile(
ex.Errors.Aggregate(new StringBuilder(),
(sb, error) =>
sb.Append(error.ToString()).Append(
"<br/>")).ToString(), templateName);
return (model)=> Razor.Run(templateName);
}
return (model) => Razor.Run(templateName, model);
});
return templateRunner(modelValue);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment