RazorEngine
RazorEngine copied to clipboard
Error in Azure Function
Hi,
I'm getting errors running this inside an Azure function on the simplest possible razor views: "Illegal characters in path during compile"
Is this just not supported yet or is there a known workaround?
Workaround mentioned here with a static ReferenceResolver doesn't seem to help: https://github.com/Antaris/RazorEngine/issues/456
Hello,
Azure Functions are subject of some file system limitations (described here and here) . My best guess is that the Engine may use the file system for template caching in a way that does not comply with Azure Functions limitations. Personally I ended up using another template engine where I can handle template caching by myself.
@bviale thanks, that's unfortunate.... Can I ask you which templating engine you used instead?
Westwind.RazorHosting seems to be promising with Azure Functions...
I've got this issue too, it seems to be related to using pre-compiled Azure functions as I was using the old .csx style with RazorEngine without issue. As soon as I rewrote everything to use the pre-compiled .cs functions, I get this error.
Running into the same issue with RazorEngine when using pre-compiled Azure functions. Funny thing is this was working until we did our latest deployment. I have had issues with Azure functions finding my templates in the past, but had gotten around them by embedding the template in my assembly.
Does anyone know if there is any way to disable file system caching RazorEngine is doing?
Got them working again. For anyone else looking for a temporary workaround, this exception was not thrown in earlier versions of Azure Functions. Until there is a fix in this repo, if you set the FUNCTIONS_EXTENSION_VERSION setting in the Application Settings to 1.0.11247 (the last version I found that this was still working for), then things seem to work again. I'm guessing the Azure Functions team is restricting more of what can be written to the running directories, and the caching of RazorEngine is trying to write something to a temporary file/directory. More information about what is in each function version can be found here: https://github.com/Azure/azure-webjobs-sdk-script/releases
I have been trying to find where I could overwrite RazorEngine's file output, but it doesn't seem to be caused by the main template caching interfaces you can override in the config. Does anyone know of any other places that may be trying to write to a file on disk that we could override?
Another fix/workaround is to change the configuration of RazorEngine
. As described in fix #466.
Create a new TemplateServiceConfiguration
object.
var config = new TemplateServiceConfiguration();
Provide a custom implementation of IReferenceResolver
(take one described in #466).
c.ReferenceResolver = new UseCurrentAssembliesReferenceResolver();
And assign it the static instance of RazorEngine
.
RazorEngine.Engine.Razor = RazorEngine.Templating.RazorEngineService.Create(c);
The custom resolver implementation catches the exception and continues instead of failing.
@chandermani I tried the workaround but is not working for me with Net.Sdk.Functions version - 1.0.7
var config = new TemplateServiceConfiguration();
// You can use the @inherits directive instead (this is the fallback if no @inherits is found).
config.BaseTemplateType = typeof(ExtendTemplateBase<>);
config.ReferenceResolver = new UseCurrentAssembliesReferenceResolver();
using (Engine.Razor = RazorEngineService.Create(config))
{
emailHtmlBody = Engine.Razor.RunCompile(text, template, null,model,viewBag);
}
//By default Razor doesn't support @Html and @Url
public abstract class ExtendTemplateBase<T> : TemplateBase<T>
{
public HtmlHelper<object> Html { get; private set; }
public UrlHelper Url { get; private set; }
protected ExtendTemplateBase() {
InitHelpers();
}
public void InitHelpers()
{
//var httpContext = new HttpContextWrapper(HttpContext.Current);
//var handler = httpContext.CurrentHandler as MvcHandler;
//if (handler == null)
// throw new InvalidOperationException("Unable to run template outside of ASP.NET MVC");
Url = new UrlHelper();
}
public class UrlHelper
{
public string Content(string content)
{
return VirtualPathUtility.ToAbsolute(content);
}
}
}
I was just about to deploy my Azure Function using RazorEngine, when I bumped into this issue, which was quite worrying!
I just tested my function on a 32 bit Azure App Service - the free tier and it works! My production servcie runs 64 bit on a paid tier. Not tested yet.
These are my RazorEngine settings:
// Find templates in a web application
var webPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", templatePath);
// Find templates from a unit test or console application
var libraryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, templatePath);
var config = new TemplateServiceConfiguration
{
TemplateManager = new ResolvePathTemplateManager(new[] { webPath, libraryPath })
};
config.DisableTempFileLocking = true;
config.CachingProvider = new DefaultCachingProvider(t => { });
_service = RazorEngineService.Create(config);
Using version 3.10.0 of RazorEngine.
Hope this helps other with similar problems.
@eigil-rosager that's an interesting solution, thanks for sharing. It seems like you're completely disabling caching like this, or am I wrong there? I'd be curious to see the performance impact on that.
Thanks for the comment @eigil-rosager ! Unfortunately, I still have the same error after trying your suggestion. My setup is slightly different, where I have moved my templates to be embedded in the binary instead of as separate files:
private static Lazy<IRazorEngineService> _service = new Lazy<IRazorEngineService>(() =>
{
var config = new TemplateServiceConfiguration
{
TemplateManager = new EmbeddedResourceTemplateManager(typeof(RazorTemplateManager)),
BaseTemplateType = typeof(HtmlTemplateBase<>)
};
config.DisableTempFileLocking = true;
config.CachingProvider = new DefaultCachingProvider(t => { });
return RazorEngineService.Create(config);
});
Perhaps I will have to try restructuring a few things and remove them from being embedded to see if that in combination with your suggestion helps.
Hi there, I have issues with using a class library that has the template files (inc. layout) as embedded resources in an Azure Function. Just wondering if anyone has had any luck with a successful implementation?
The error I get is "System.NotSupportedException: 'The given path's format is not supported."
https://github.com/Antaris/RazorEngine/pull/466 fixed it for me.
@MattyBearBytes, were you able to resolve the path format not supported issue? I'm facing that one now after converting to a precompiled function from a service.
Hope this can help everyone
RazorEngine throw a NotSupportedException when compiling template in Azure Function
But I am still not satisfied because I would like to run RrazorEngine in another app domain
@csimone86 worked for me! THANK YOU! (especially since Microsoft stopped supporting the version I had to roll back to in order to get around this TODAY)