Today I ran into a problem with starting my AspNet5 app. (for the record, I'm using aspnet version
1.0.0-beta8) This is what happened:
> dnx web Application startup exception: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) at System.Reflection.RuntimeAssembly.get_DefinedTypes() at Microsoft.AspNet.Hosting.Startup.StartupLoader.FindStartupType(String startupAssemblyName, IList`1 diagnosticMessages) at Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureStartup() at Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureApplicationServices() at Microsoft.AspNet.Hosting.Internal.HostingEngine.BuildApplication() Hosting environment: Production Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down.
The exception occurs in
FindStartupType method, before app is even started. A quick search led me to this SO thread: Run ASPNET5 web application with Kestrel, which suggests there may be a mismatch between current dnx version and downloaded package dependencies. I double checked current dnx version using
dnvm list. Then I ran
dnu restore to be sure:
> dnu restore (...) Done, without errors. Restore complete, 18523ms elapsed
I also tried removing all packages from
%UserProfile%\.dnx\packages and restoring them again, but that didn't help either.
Try to compile then:
> dnu build (...) Build succeeded. 0 Warning(s) 0 Error(s) Time elapsed 00:00:01.9781471 Total build time elapsed: 00:00:02.0094707 Total projects built: 1
Seems ok to me. What the hell is causing the problem then?
How can I debug this exception, when my code isn't even running yet? Turns out that
dnx has a little option called
--debug. Let's try this:
dnx --debug web Process Id: 15396 Waiting for the debugger to attach... ```
Ok, Let's attach Visual studio and see what happens. In VS, do
Debug -> Attach to Process, then find
dnx.exe process and attach to it (if there is more than one, just try to attach to each of them).
dnx console window you should now see:
If the exception is still thrown, and nothing happens in VS, you need to enable breaking on exceptions in VS. Go to
Debug -> Windows -> Exception Settings and make sure "Common Language Runtime Exceptions" is checked. (Remember to uncheck it after you're done with debugging, otherwise debugger will break on all sort of internal exceptions.)
Now, repeat the process - restart
dnx --debug web and attach VS debugger to it.
And voila, we have our exception caught. What now? How to get details for this exception?
Click OK, then open a Watch window (
Debug -> Windows -> Watch -> Watch1). In the
Name column, type
$exception. This is a clever pseudo-variable, which displays information on the last exception.
If caught exception is of type
ReflectionTypeLoadException, look for
LoaderExceptions field and check if there are any understandable exceptions or messages.
In fact, you may have already caught the exception which is the real cause of error, even before
ReflectionTypeLoadException is thrown.
In my case the problem was:
Exception thrown: 'Microsoft.Dnx.Compilation.CSharp.RoslynCompilationException' in Microsoft.Dnx.Compilation.CSharp.dll Additional information: c:\projects\dnxtest\dnxtest.core\FilePositionCommand.cs(272,21): DNX,Version=v4.5.1 error CS0162: Unreachable code detected
The compilation error came from a project that my main app was referencing. Why did
dnu build succeed then?
It seems like
dnu doesn't do full compilation of referenced projects. It checks referenced classes, fields, etc., but it completely ignores any code errors.
I'm sure there's a reason for such behavior, but I think there should be also a way to compile everything, something like
dnu build --recursive, or running
dnu at the root directory level.
Of corse, if you're using Visual Studio or VS Code, you will see compilation errors. But if you like to stick with commandline and simpler editors -
I currently don't see other way than compiling every project separately. Of course you can write a script that does that, but - shouldn't something like that be included 'out of the box'?
If the runtime exception was at least a little bit more meaningfull - just
RoslynCompilationException instead of cryptic
ReflectionTypeLoadException - that would be enough.
I hope that will be fixed in next releases!