Mvc: Actions lost when referencing Microsoft.AspNetCore.Mvc in dependency

Created on 19 May 2016  路  6Comments  路  Source: aspnet/Mvc

When you have some library that references Microsoft.AspNetCore.Mvc such as in the following project.json

_ClassLibrary1 project.json_

{
  "version": "1.0.0-*",

  "dependencies": {
    "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
    "NETStandard.Library": "1.5.0-rc2-24027"
  },

  "frameworks": {
    "netstandard1.5": {
      "imports": "dnxcore50"
    }
  }
}

and you have an application that depends on MVC by referencing this library, it causes actions to not be added to the ActionDescriptorCollectionProvider.

This can be reproduced by the following steps:

  1. Create an ASP.NET Core Web Application with the default web application template
    image
  1. Add a class library as a project
    image

  2. Change project.json of the class library to the content listed above in _ClassLibrary1 project.json_

  3. Remove reference to Microsoft.AspNetCore.Mvc in web application project.json

{
  "userSecretsId": "{REMOVED}",

  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.0-rc2-3002702",
      "type": "platform"
    },
    "Microsoft.ApplicationInsights.AspNetCore": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Diagnostics": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0-rc2-final",
    //"Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Razor.Tools": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    },
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    },
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Console": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Debug": "1.0.0-rc2-final",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc2-final",
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    },
    "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    }
  },

  "tools": {
    "Microsoft.AspNetCore.Razor.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": [
        "portable-net45+win8+dnxcore50",
        "portable-net45+win8"
      ]
    },
    "Microsoft.Extensions.SecretManager.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": [
        "portable-net45+win8+dnxcore50",
        "portable-net45+win8"
      ]
    }
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "dnxcore50",
        "portable-net45+win8"
      ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "gcServer": true
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "Views",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ],
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}
  1. Add reference from web application to the class library.

The following can be used to verify there are no actions being found

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

if (app.ApplicationServices.GetRequiredService<IActionDescriptorCollectionProvider>().ActionDescriptors.Items.Count == 0) {
    throw new Exception("No actions found.");
}
duplicate

Most helpful comment

@BillDines, you should be able to workaround this by explicitly registering your ClassLibrary as an application part:

In your startup:

C# services .AddMvc() .AddApplicationPart(typeof(ValuesControllerFromClassLib).Assembly)

I suspect this is an issue with how DependencyContext computes references for csproj based class libraries.

All 6 comments

/cc @javiercn

I believe this is a dupe of https://github.com/aspnet/Mvc/issues/4555
The workaround for the moment is to just reference Microsoft.AspNetCore.Mvc directly in your web app or in any class library that contains things like controllers and so on.

@BillDines, you should be able to workaround this by explicitly registering your ClassLibrary as an application part:

In your startup:

C# services .AddMvc() .AddApplicationPart(typeof(ValuesControllerFromClassLib).Assembly)

I suspect this is an issue with how DependencyContext computes references for csproj based class libraries.

@pranavkm - thanks, that fixes it! Sorry, I deleted my comment already and started a new issue #4983

That's alright. It'll help us to keep track of the underlying issue so that it works out of the box.

Was this page helpful?
0 / 5 - 0 ratings