Reputation: 2430
I must compile a razor view in an azure function to send an email, but something goes wrong. I obtain the a NotSupportedException
error: The given path's format is not supported.
Here my code:
private IRazorEngineService _engine;
public MyCtor(bool isTestEnvironment)
{
TemplateServiceConfiguration configuration = new TemplateServiceConfiguration();
configuration.Debug = isTestEnvironment;
this._engine = RazorEngineService.Create(configuration);
}
public string GetHtmlEmailBody(string templateFileName, object emailData, string layoutFileName)
{
//Get data type of email data
Type emailDataType = emailData.GetType();
string layoutFullFileName = Path.Combine(this._layoutPath, layoutFileName);
string layoutContentString = File.ReadAllText(layoutFullFileName);
var layout = new LoadedTemplateSource(layoutContentString, layoutFullFileName);
this._engine.AddTemplate("layoutName", layout);
string templateFullFileName = Path.Combine(this._templatePath, templateFileName);
string templateContentString = File.ReadAllText(templateFullFileName);
var template = new LoadedTemplateSource(templateContentString, templateFullFileName);
this._engine.AddTemplate("templateName", template);
this._engine.Compile("templateName"); //<-- Here I get the exception
string htmlEmailBody = this._engine.Run("templateName", emailDataType, emailData);
return htmlEmailBody;
}
Paths are similar to D:\\...\\Emails\\Templates
.. I am testing locally and it does not work... I have googled and it seems that Azure Functions have some limitations in caching and in file system management, but it is not clear how can I solve the problem.
I think I have same problem this person has written here
Any idea how can I solve it? There is something wrong in what I am doing?
I am using RazorEngine 3.10.0 Thank you
Upvotes: 3
Views: 697
Reputation: 2430
I have found the problem, downloading the code and doing reverse engineering.
Problem was inside the UseCurrentAssembliesReferenceResolver
class, in the GetReferences
method... here the code that throws the exception:
return CompilerServicesUtility
.GetLoadedAssemblies()
.Where(a => !a.IsDynamic && File.Exists(a.Location) && !a.Location.Contains(CompilerServiceBase.DynamicTemplateNamespace))
.GroupBy(a => a.GetName().Name).Select(grp => grp.First(y => y.GetName().Version == grp.Max(x => x.GetName().Version))) // only select distinct assemblies based on FullName to avoid loading duplicate assemblies
.Select(a => CompilerReference.From(a))
.Concat(includeAssemblies ?? Enumerable.Empty<CompilerReference>());
Exactly the statements that throw the exception are File.Exists(a.Location) && !a.Location.Contains(CompilerServiceBase.DynamicTemplateNamespace))
. The problem is that in Azure function some assemblies are protected, so no information can be retrieved about them... (surely I must study about azure functions)...
At the moment I solved writing a custom ReferenceResolver. I copied exactly the same code from the UseCurrentAssembliesReferenceResolver
and I changed just the Where
conditions..
So
.Where(a => !a.IsDynamic && File.Exists(a.Location) && !a.Location.Contains(CompilerServiceBase.DynamicTemplateNamespace))
became
.Where(a => !a.IsDynamic && !a.FullName.Contains("Version=0.0.0.0") && File.Exists(a.Location) && !a.Location.Contains("CompiledRazorTemplates.Dynamic"))
I am almost sure that it is not the best way to solve the problem... but now I solved it, and after two days my work is blocked I need to go on... I hope this can help someone...
Upvotes: 3