I am having an issue where my controller is not being detected by Mvc in my barebones web app. The code for this problem can be found at https://github.com/awec/WeirdRC2Mvc. Also available at https://gist.github.com/awec/c4cb7be9dffdc5a0e29b813743628878 for easier reading.
I'm using VSCode (VS is not installed on this machine) and dotnet cli. I've installed RC2 and Preview 1 of the sdk (dotnet --version is 1.0.0-preview1-002702).
Other people who have looked at this issue report that it works in VS, however they also can repro the issue outside of VS (i.e. using the cli) on their machines (including non-Windows machines).
Repro steps:
Expected: exception to be thrown (exception purposefully thrown in controller constructor to demonstrate the controller isn't being initialized).
The trace logs show:
dbug: Microsoft.AspNetCore.Routing.RouteBase[1]
Request successfully matched the route with name 'default' and template '{controller=Home}/{action=Index}/{id?}'.
dbug: Microsoft.AspNetCore.Mvc.Internal.MvcRouteHandler[3]
No actions matched the current request
Things I have tried:
I definitely have the correct URL (localhost:5000) because I can get responses outside of MVC.
As far as I can tell my controller meets the requirements for discovery from https://github.com/aspnet/Announcements/issues/165
@awec you need to add "preserveCompilationContext": true to your buildOptions in your project.json. Without this we don't don't know what assemblies to consider as part of your application.
Example here: https://github.com/aspnet/Mvc/blob/dev/samples/MvcSandbox/project.json#L5
Also tried that, made no difference. @pranavkm said it shouldn't be required also on the aspnetcore Slack.
@rynowak You don't need it unless you're compiling razor views
/cc @javiercn
Update: this works if I add a reference to "Microsoft.AspNetCore.Mvc.Core": "1.0.0-rc2-final".
Is this expected? I don't see that package listed in the StarterWeb template for example at https://github.com/aspnet/Templates/blob/dev/src/BaseTemplates/StarterWeb/project.json
So um, this actually is caused by the lowercase 'n' in Microsoft.Aspnet.Mvc (should be AspNet) in my project.json.
We're treating library names (nuget package \ project names) which are generally case insensitive as assembly names. https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultAssemblyPartDiscoveryProvider.cs#L17 needs to change to be ordinal ignore case.
The weird thing is that this seems to work on the full .NET framework. I just changed the project.json to this and it worked:
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.AspNetCore.Server.Kestrel" : "1.0.0-rc2-final",
"Microsoft.AspnetCore.Mvc": "1.0.0-rc2-final",
"Microsoft.Extensions.Logging": "1.0.0-rc2-final",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc2-final"
},
"frameworks": {
"net46": { }
}
}
Might be an issue with how the deps file is contructed. Regardless, NuGet treats package names (for most parts - https://github.com/NuGet/Home/issues/2522) as case insensitive and we should follow suit.
@pranavkm do we still need to do a fix in MVC then?
I'm trying to understand this cause I'm curious. In this case:
Have I understood this correctly?
In that case, should calling UseMvc and then have no Mvc packages being detected not result in some sort of exception? Or is silent failure of middleware the expected result (ignoring the whole case sensitivity thing for a moment) ?
@Eilon - we should. Restore from a feed is case insensitive. We're trying to match library names (which are case insensitive) and not assembly names (which are case sensitive).
@awec - at startup, Mvc attempts to look up assemblies \ components that reference any of the Mvc packages. The idea is to limit controller \ view component \ tag helper discovery to only those assemblies that have directly or transitively referenced Mvc. It might be useful to throw an exception later on (maybe when we're building the ApplicationModel) and cannot find any controllers. cc @rynowak \ @javiercn for throughts on this.
@pranavkm I don't understand very well the difference between Library vs Assembly names. I believe that the output in the .deps file should always have the correct casing, independently of whatever the user put in his project.json. The generated .deps file shouldn't change based on the casing the user uses on project.json
I've just been hit by the general issues of which assemblies are searched for controllers. The net effect was that by migrating to RC2, none of my API controllers was ever reached.
Most importantly: My assembly reference had the correct casing, so changing the HashSet's StringComparer in DefaultAssemblyPartDiscoveryProvider.ReferenceAssemblies wouldn't have fixed my issue.
I was actually bitten by the fact that assemblies that only transitively reference Mvc are not considered candidate libraries contrary to what @pranavkm mentioned. My main project with all the controllers itself didn't have a reference to Mvc, but a different referenced library had. So everything compiled correctly, but the RuntimeLibrary.Dependencies didn't include MVC and the check failed.
As a workaround, I added Mvc to my main project.json and the controllers were successfully discovered.
Most helpful comment
So um, this actually is caused by the lowercase 'n' in Microsoft.Aspnet.Mvc (should be AspNet) in my project.json.