I'm trying to use IsolatedRazor to build HTML e-mails based on Razor templates. This is inside an ASP.NET Web API project; IsolatedRazor lives inside an ApiController and gets called on a schedule using FluentScheduler.
Intermittently, but frequently enough that it's not practical to use right now, I get one of two errors:
- a
FileNotFoundException trying to load ImpromptuInterface or one of its dependencies. Here's an example stacktrace:
2018-05-04 06:00:02.6015|3|ERROR|TAG.Accounts.WebApi.Controllers.Statistics.NightlyUserAccountStatisticsController|System.AggregateException: Mindestens ein Fehler ist aufgetreten. ---> System.Reflection.TargetInvocationException: Ein Aufrufziel hat einen Ausnahmefehler verursacht. ---> System.IO.FileNotFoundException: Die Datei oder Assembly "ImpromptuInterface, Version=6.2.2.0, Culture=neutral, PublicKeyToken=0b1781c923b2975b" oder eine Abh�ngigkeit davon wurde nicht gefunden. Das System kann die angegebene Datei nicht finden.
bei IsolatedRazor.DynamicViewBag..ctor(Object parentViewBag)
bei IsolatedRazor.TemplateBase..ctor()
bei IsolatedRazor.RazorTemplate.C_GetTemplate_SummaryTableAsync..ctor()
--- Ende der internen Ausnahmestapel�berwachung ---
bei System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
bei System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
bei System.Activator.CreateInstance(Type type, Boolean nonPublic)
bei System.Activator.CreateInstance(Type type)
bei IsolatedRazor.RazorTemplater.PrepareTemplate(String assemblyPath, String typeName, DynamicViewBag viewBag, TemplateCache templateCache, TemplateEncoding encoding)
bei IsolatedRazor.RazorTemplater.RenderTemplateInternal[T](String assemblyPath, String typeName, T model, DynamicViewBag viewBag, TemplateCache templateCache, TemplateEncoding encoding)
bei IsolatedRazor.RazorTemplater.RenderTemplateInternal[T](String assemblyPath, String typeName, T model, DynamicViewBag viewBag, TemplateCache templateCache, TemplateEncoding encoding)
bei IsolatedRazor.RazorTemplater.<>c__DisplayClass4c`1.<Render>b__4b()
bei System.Threading.Tasks.Task`1.InnerInvoke()
bei System.Threading.Tasks.Task.Execute()
- or an
UnauthorizedAccessException trying to delete a generated template DLL:
2018-04-25 23:03:51.5419|2|ERROR|TAG.Accounts.WebApi.WebApiApplication|System.UnauthorizedAccessException: Der Zugriff auf den Pfad "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\15a0a301\13ba4d00\_GetTemplate_SummaryTableAsync.dll" wurde verweigert.
bei System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
bei System.IO.File.InternalDelete(String path, Boolean checkHost)
bei IsolatedRazor.RazorTemplater.Dispose()
bei IsolatedRazor.RazorTemplater.Finalize()
This happens regardless of whether I set persistTemplates to true. Other than that, IsolatedRazor gets called like so:
using (var templateEngine = new IsolatedRazor.RazorTemplater(templateAssemblyPath, renderTimeout: 5000))
{
[..various calls to merge portions of the templates..]
// …the final piece:
return await _GetTemplate_StatisticsAsync(summaryTable, newAccountsTable, unusedAccountsTable, templateEngine);
}
And on the inside:
private async Task<string> _GetTemplate_StatisticsAsync(string summaryTable, string newAccountsTable, string unusedAccountsTable, IsolatedRazor.RazorTemplater templateEngine)
{
var result = new Models.Statistics
{
SummaryTable = summaryTable,
NewAccountsTable = newAccountsTable,
UnusedAccountsTable = unusedAccountsTable,
};
var template = System.IO.File.ReadAllText(System.Web.Hosting.HostingEnvironment.MapPath("~/Mails/TemplateHTML/NightlyUserAccountStatistics.cshtml"));
return await _ParseTemplate(templateEngine, template, result);
}
private async Task<string> _ParseTemplate<T>(IsolatedRazor.RazorTemplater templateEngine,
string template,
T model,
[System.Runtime.CompilerServices.CallerMemberName] string caller = "")
{
var templateName = caller;
return await templateEngine.ParseAsync(templateName, template, DateTime.Now, model);
}
I'm guessing the two exceptions are related: when the clean-up fails in IsolatedRazor.RazorTemplater.Dispose(), IsolatedRazor can't subsequently load its references in IsolatedRazor.TemplateBase..ctor(). However, I'm not sure about that.
I also believe I observed that when this does happen, IsolatedRazor no longer tries to run in its own app domain.
This is unfortunately not 100% reproducible (as far as I can see).
I'm trying to use IsolatedRazor to build HTML e-mails based on Razor templates. This is inside an ASP.NET Web API project; IsolatedRazor lives inside an ApiController and gets called on a schedule using FluentScheduler.
Intermittently, but frequently enough that it's not practical to use right now, I get one of two errors:
FileNotFoundExceptiontrying to loadImpromptuInterfaceor one of its dependencies. Here's an example stacktrace:UnauthorizedAccessExceptiontrying to delete a generated template DLL:This happens regardless of whether I set
persistTemplatesto true. Other than that, IsolatedRazor gets called like so:And on the inside:
I'm guessing the two exceptions are related: when the clean-up fails in
IsolatedRazor.RazorTemplater.Dispose(), IsolatedRazor can't subsequently load its references inIsolatedRazor.TemplateBase..ctor(). However, I'm not sure about that.I also believe I observed that when this does happen, IsolatedRazor no longer tries to run in its own app domain.
This is unfortunately not 100% reproducible (as far as I can see).