Mvc: asp.net-core MVC rc2 using net451 on linux

Created on 7 Jun 2016  路  30Comments  路  Source: aspnet/Mvc

I am trying to migrate my website from dotnet core rc1 to dotnet core rc2, but I faced an error, then I tried to run a small test and it also didn't work for me. This is my teste: https://github.com/ricardoalcantara/WebApplicationBasic

My environment is:

  • Debian 8.4
  • Mono 4.2.3
  • dotnet 1.0.0-preview1-002702

I need to run it on top of the "framework": "net451" because my main project needs few libs which still just run on that platform, so I am running with this command line:

dotnet run --framework .NETFramework,Version=v4.5.1

it actually runs, but when I try to access localhost:5000 it throws a long stack error mainly with that message:

z2cw6v06.4ja(43,10): error CS0518: Predefined type 'System.Object' is not defined or imported

z2cw6v06.4ja(43,50): error CS0012: The type 'Attribute' is defined in an assembly that is not referenced. You must add a reference to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

z2cw6v06.4ja(43,10): error CS0518: Predefined type 'System.Void' is not defined or imported

z2cw6v06.4ja(45,10): error CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

z2cw6v06.4ja(45,10): error CS0518: Predefined type 'System.Object' is not defined or imported

z2cw6v06.4ja(45,50): error CS0012: The type 'Attribute' is defined in an assembly that is not referenced. You must add a reference to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

z2cw6v06.4ja(45,10): error CS0518: Predefined type 'System.Void' is not defined or imported

z2cw6v06.4ja(47,10): error CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

z2cw6v06.4ja(47,10): error CS0518: Predefined type 'System.Object' is not defined or imported

z2cw6v06.4ja(47,50): error CS0012: The type 'Attribute' is defined in an assembly that is not referenced. You must add a reference to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

Can someone help me to solve that problem?

Obs.: It works on windows.

Most helpful comment

@ricardoalcantara I solved it!

Add this class to your project and add the following to you startup config:

services.AddMvc().AddRazorOptions( options =>
            {
                var myAssemblyPaths = new [] {"/usr/lib/mono/4.5/mscorlib.dll"};
                var previous = options.CompilationCallback;
                options.CompilationCallback = (context) => 
                {
                    if (previous != null)
                    {
                        previous(context);
                    }

                    var references = myAssemblyPaths.Select(p=>MetadataReference.CreateFromFile(p)).ToArray();
                    context.Compilation = context.Compilation.AddReferences(references);
                };                        

            });

All 30 comments

Full .NET framework is only supported on Windows. You need to convert your app to .NET Core to run on Linux or Mac

But it is fully working on dotnet core rc 1. The reason I need the net451 is because I use few libs which just runs on that platform. For example MySql.Data (https://www.nuget.org/packages/MySql.Data)

@ricardoalcantara at this time we're working with the Mono team to see how we can get better compatibility between ASP.NET Core and Mono. Unfortunately, at this time there are some gaps that we don't have a good solution for.

@ricardoalcantara view compilation is failing for you right? But the application itself runs. Is that correct?

@davidfowl Yes, indeed the application itself runs but the error is different. Let me attach the output error.
LogDemo.txt

@davidfowl Maybe you are right, I do apologize if I missed the following line, but the second time I checked the log after you mentioned about the view compilation, I found that:
Microsoft.AspNetCore.Mvc.Razor.Compilation.CompilationFailedException: One or more compilation failures occurred:

This is a known issue on mono https://github.com/dotnet/cli/issues/1613.

Is there any workaround I could do to make it work while they don't fix it?

You could use the compilation call back to add enough framework assemblies for the view to compile successfully. See https://github.com/aspnet/Mvc/issues/4423#issuecomment-206987910 for an example of the callback usage.

Keep in mind, mono does not have a DynamicAttribute type.

To fix that one just copy and paste the .net class into your project. See https://github.com/aspnet/Razor/issues/774

For the rest this callback method might work. I am going to try it myself see if it works.

I am trying to puts things together, but I didn't realize yet what Assemblies should I load with
services.Configure<RazorViewEngineOptions> and their location.

I tried to add the DynamicAttribute and load some Razor Assemblies without success, @pompomJuice Did you achieve to try it yourself?

At best we are just monkeys pulling levers here.

The people who coded dynamic view compilation should really be looking into this.

I am still trying to figure out where these levers are. I suspect it won't work because the types razor says it cannot find is definitely there. I say this because if I add them manually myself the compiler says they are already there.

I will let you know when I get anything working, but I doubt I will.

@ricardoalcantara I solved it!

Add this class to your project and add the following to you startup config:

services.AddMvc().AddRazorOptions( options =>
            {
                var myAssemblyPaths = new [] {"/usr/lib/mono/4.5/mscorlib.dll"};
                var previous = options.CompilationCallback;
                options.CompilationCallback = (context) => 
                {
                    if (previous != null)
                    {
                        previous(context);
                    }

                    var references = myAssemblyPaths.Select(p=>MetadataReference.CreateFromFile(p)).ToArray();
                    context.Compilation = context.Compilation.AddReferences(references);
                };                        

            });

Well, that did not last long. Razor cant handle generics. This Razor code went against the stream or something it just does not want to work. Why can't it just work like everything else. Why does it always have to break in incomprehensible ways. Why

 fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[0]
 An unhandled exception has occurred while executing the request
 Microsoft.AspNetCore.Mvc.Razor.Compilation.CompilationFailedException: One or more compilation failures occurred:
 rotsoi9y.fbo(510,149): error CS0246: The type or namespace name 'TValue' could not be found (are you missing a using directive or an assembly reference?)
 rotsoi9y.fbo(510,365): error CS0246: The type or namespace name 'TValue' could not be found 
 (are you missing a using directive or an assembly reference?)
 rotsoi9y.fbo(510,199): error CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type
 rotsoi9y.fbo(510,415): error CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type
at Microsoft.AspNetCore.Mvc.Razor.Compilation.CompilationResult.EnsureSuccessful () <0x40aa27c0 + 0x00063> in <filename unknown>:0 
  at Microsoft.AspNetCore.Mvc.Razor.Internal.CompilerCache.CreateCacheEntry (System.String normalizedPath, System.Func`2 compile) <0x40796520 + 0x003af> in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <0x7f1b57c018a0 + 0x00029> in <filename unknown>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) <0x7f1b57bff880 + 0x000a7> in <filename unknown>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) <0x7f1b57bff800 + 0x0006b> in <filename unknown>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) <0x7f1b57bff7b0 + 0x0003a> in <filename unknown>:0 
  at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () <0x40aa2cf0 + 0x0001f> in <filename unknown>:0 
  at Microsoft.AspNetCore.Mvc.Razor.Internal.CompilerCache.GetOrAdd (System.String relativePath, System.Func`2 compile) <0x40796140 + 0x000e8> in <filename unknown>:0 
  at Microsoft.AspNetCore.Mvc.Razor.Internal.DefaultRazorPageFactoryProvider.CreateFactory (System.String relativePath) <0x40795da0 + 0x000ba> in <filename unknown>:0 
  at Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.CreateCacheResult (System.Collections.Generic.HashSet`1 expirationTokens, System.String relativePath, Boolean isMainPage) <0x40795b50 + 0x00053> in <filename unknown>:0 
  at Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.OnCacheMiss (Microsoft.AspNetCore.Mvc.Razor.ViewLocationExpanderContext expanderContext, ViewLocationCacheKey cacheKey) <0x407954c0 + 0x002db> in <filename unknown>:0 

I am still testing my whole environment, I had that similar stack but accusing others missing types, so far I added this other lines:

var myAssemblyPaths = new [] { "/usr/lib/mono/4.5/mscorlib.dll", "/usr/lib/mono/4.5/System.Core.dll", "/usr/lib/mono/4.5/Microsoft.CSharp.dll" };

Thanks, I had those too... then I just added all the dlls, no luck.

The error does not make much sense. Strange thing is the one controller (the trivial home controller) with index.cshtml seems to work but the others controllers with more complex code does not. I am busy eliminating possibilities.

You could try throwing the kitchen sink (of assemblies) at it and add a reference to everything in AppDomain.CurrentDomain.GetAssemblies(). Perhaps that'll help?

For me, the pompomJuice approach with those libs I showed has worked well, so far. Remember to use dotnet run -f net451, otherwise it will crash running on netcoreapp1.0 or use Preprocessor Directives to avoid it to crash.

I tried to run a full test on my main website, It didn't go well, I guess I am not moving to dotnet core RC2. Let's pray to see if the release might solve that problem.

Looks like the problem lies within the new TagHelpers stuff

<label asp-for="Account"></label>

As soon as I use something like that it breaks.

It's the same error.

Adding Microsoft.NETCore.Portable.Compatibility has no effect in Linux net451.

I got same error when I moved Account View models outside of mvc project. In windows .net 4.6.1 btw.
When I comment out asp-for html related tags, error is gone.
So it is not specific to linux...

this is a bad regression on linux. we approach the final version and less it is stable or compatible. truly cross-platform? We lose compatibilities net451 that had the RC1.
That's 18 months of development are compromised.

Here the mail received today for the promotion of visual studio essentials.
french
"Tout ce que vous avez toujours d茅test茅 dans le web chez Microsoft
Vous n'associez peut 锚tre pas web et Microsoft. M锚me si on a pu faire quelques erreurs par le pass茅, nous vous pr茅sentons dans cette vid茅o la direction int茅ressante que prend Microsoft dans ce domaine."

english (translation auto)
"All you have always disliked the web at Microsoft
You can not combine web and Microsoft. Even if we could make some mistakes in the past, we present in this video interesting Direction Microsoft in this area."

Yes, i want to believe that the technologies microsoft is the web of tomorrow. :wink:

@pompomJuice Thank you. It works great.

https://github.com/dotnet/cli/issues/3197

A minor update to @pompomJuice's workaround in https://github.com/aspnet/Mvc/issues/4818#issuecomment-224539449. We added an option to RazorViewEngineOptions to list additional references that Razor could use during compilation. Using this overload should address errors you'd previously encountered using lambda delegates (such as HtmlHelpers) that close over the model.

``` C#
services
.AddMvc()
.AddRazorOptions(options =>
{
var assemblyPaths = new [] { "/usr/lib/mono/4.5/mscorlib.dll", "/usr/lib/mono/4.5/System.Core.dll", "/usr/lib/mono/4.5/Microsoft.CSharp.dll" };

foreach (var path in assemblyPaths)
{
    options.AdditionalCompilationReferences.Add(MetadataReference.CreateFromFile(path));
}

});
```

@mehmetilker, your issue could be related to https://github.com/aspnet/Mvc/issues/4983. Could you see the suggested workaround in https://github.com/aspnet/Mvc/issues/4983#issuecomment-231111258?

Microsoft.Extensions.DependencyModel searches Reference Assemblies inside xbuild-frameworks/.NETFramework/v{.NET Version}.

For working MVC dynamic compilation, use this script.

cd /usr/lib/mono
mkdir xbuild-frameworks
cd xbuild-frameworks
mkdir .NETFramework
cd .NETFramework
ln -s ../../4.5 v4.5.2

If you use net451, please change v4.5.2 to v4.5.1 on the script.

https://github.com/aspnet/Mvc/issues/5088

Was this page helpful?
0 / 5 - 0 ratings