RazorLight
RazorLight copied to clipboard
Cannot render template in docker container
Describe the bug
I am trying to render a razor template in a docker container using .NET Core 3.1.
Getting the following error at runtime:
Unhandled exception. System.InvalidOperationException: Cannot find reference assembly 'Microsoft.AspNetCore.Antiforgery.dll' file for package Microsoft.AspNetCore.Antiforgery.Reference
at Microsoft.Extensions.DependencyModel.Resolution.ReferenceAssemblyPathResolver.TryResolveAssemblyPaths(CompilationLibrary library, List`1 assemblies)
at Microsoft.Extensions.DependencyModel.Resolution.CompositeCompilationAssemblyResolver.TryResolveAssemblyPaths(CompilationLibrary library, List`1 assemblies)
at Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths(ICompilationAssemblyResolver resolver, List`1 assemblies)
at Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths()
at RazorLight.Compilation.DefaultMetadataReferenceManager.<>c.<Resolve>b__10_0(CompilationLibrary library)
at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
at RazorLight.Compilation.DefaultMetadataReferenceManager.Resolve(Assembly assembly, DependencyContext dependencyContext)
at RazorLight.Compilation.DefaultMetadataReferenceManager.Resolve(Assembly assembly)
at RazorLight.Compilation.RoslynCompilationService.EnsureOptions()
at RazorLight.Compilation.RoslynCompilationService.get_ParseOptions()
at RazorLight.Compilation.RoslynCompilationService.CreateSyntaxTree(SourceText sourceText)
at RazorLight.Compilation.RoslynCompilationService.CreateCompilation(String compilationContent, String assemblyName)
at RazorLight.Compilation.RoslynCompilationService.CompileAndEmit(IGeneratedRazorTemplate razorTemplate)
at RazorLight.Compilation.RazorTemplateCompiler.CompileAndEmit(RazorLightProjectItem projectItem)
at RazorLight.Compilation.RazorTemplateCompiler.OnCacheMissAsync(String templateKey)
--- End of stack trace from previous location where exception was thrown ---
at RazorLight.EngineHandler.CompileTemplateAsync(String key)
at RazorLight.EngineHandler.CompileRenderAsync[T](String key, T model, ExpandoObject viewBag)
at TestApp.Program.Main(String[] args)
at TestApp.Program.<Main>(String[] args)
To Reproduce
Create a new .NET Core console application and add reference to the RazorLight
NuGet. Also add the following to the corresponding .csproj:
<PropertyGroup>
<PreserveCompilationReferences>true</PreserveCompilationReferences>
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>
Render a simple template in the app:
using System;
using System.Threading.Tasks;
using RazorLight;
namespace TestApp
{
public class Program
{
public static async Task Main(string[] args)
{
var engine = new RazorLightEngineBuilder()
.UseEmbeddedResourcesProject(typeof(Program))
.UseMemoryCachingProvider()
.Build();
var message = "Hello @Model.Name";
var content = await engine.CompileRenderStringAsync(message, message, new
{
Name = "world",
});
Console.WriteLine(content);
}
}
}
To build the docker container use the following Dockerfile
:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine AS build
WORKDIR /source
# copy csproj and restore as distinct layers
COPY *.sln .
COPY TestApp/*.csproj ./TestApp/
RUN dotnet restore ./TestApp/TestApp.csproj -r alpine-x64
# copy everything else and build app
COPY TestApp/. ./TestApp/
WORKDIR /source/TestApp
RUN dotnet publish \
-c Release \
-o ./publish \
-r alpine-x64 \
--self-contained true \
--no-restore \
/p:PublishTrimmed=true \
/p:PublishSingleFile=true \
/p:UseAppHost=true
FROM alpine:3.9.4
# Add some libs required by .NET runtime
RUN apk add --no-cache libstdc++ libintl
# Copy
WORKDIR /app
COPY --from=build /source/TestApp/publish ./
ENTRYPOINT [ "./TestApp" ]
Then build the image:
docker build -t test-app .
And run:
docker run -e DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 test-app
Expected behavior
The application runs without errors and prints "Hello world".
Information (please complete the following information):
- OS: Alpine Linux 3.9.4
- Platform .NET Core 3.1
- RazorLight version: 2.0.0-beta7
- Are you using the OFFICIAL RazorLight package? https://www.nuget.org/packages/razorlight: Yes
- Visual Studio version: Visual Studio for Mac 8.5.3 (build 16)
Additional context
If I remove the /p:PublishTrimmed=true
and /p:PublishSingleFile=true
parameters when compiling the app, then it works fine:
RUN dotnet publish \
-c Release \
-o ./publish \
-r alpine-x64 \
--self-contained true \
--no-restore \
/p:UseAppHost=true
So it looks like the IL linker is stripping some information that RazorLight depends on.
Thanks. This will help #299 a lot. A little off-topic for your issue but, since you're here: Is alpine-x64 capable of testing Unicode features? I thought it wasn't? And maybe that's why you're also passing DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
?
@jzabroski, what are you referring to as Unicode features? I am using DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
because my app doesn't need to support any other cultures and I am using a slimmed down version of alpine-x64 which doesn't include the corresponding dependencies.
Any update on this issue? I have the same issue, when using the RazorLight package within a REST API to send a email based on razor templates. (.net core 3.1) The issue resolved when adding a reference to nuget package Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation