从 ASP.NET 核心中的类库加载和注册 API 控制器

Posted

技术标签:

【中文标题】从 ASP.NET 核心中的类库加载和注册 API 控制器【英文标题】:Loading and registering API Controllers From Class Library in ASP.NET core 【发布时间】:2017-03-22 08:57:42 【问题描述】:

我正在使用 ASP.NET Core 1.0.1。我有以下

一个使用"Microsoft.AspNetCore.Mvc": "1.0.1"的类库来开发我的控制器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace CoreAPIsLibrary.Controllers


    [Route("api/[controller]")]
    public class ValuesContoller : Controller
     
        public string Get()
        
            return "value";
        

        // GET api/values/5
        [HttpGet("id")]
        public string Get(int id)
        
            return "value";
        

        // POST api/values
        [HttpPost]
        public void Post([FromBody]string value)
        
        

        // PUT api/values/5
        [HttpPut("id")]
        public void Put(int id, [FromBody]string value)
        
        
    

这是我的类库的 project.json:


  "version": "1.0.0-*",

  "dependencies": 
    "Microsoft.AspNetCore.Mvc": "1.0.1",
    "NETStandard.Library": "1.6.0"
  ,

  "frameworks": 
    "netstandard1.6": 
      "imports": "dnxcore50"
    
  

将托管我的控制器和引用的 Asp.net 核心应用程序(Web API 模板) 那个类库。但是,它从来没有达到断点 控制器。这是我在 Web 应用程序中的启动类:

  using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.Reflection;
using CoreAPIsLibrary.Controllers;

namespace APIsHost

    public class Startup
    
        public Startup(IHostingEnvironment env)
        
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.env.EnvironmentName.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        

        public IConfigurationRoot Configuration  get; 

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        
            services.AddMvc()
              .AddApplicationPart(typeof(ValuesContoller).GetTypeInfo().Assembly).AddControllersAsServices();
        

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseMvc(routes =>
            
                routes.MapRoute("default", "controller/action/id");
            );
            //app.UseMvc();
        
    

我还检查了控制器是否被注入:

那么,缺少什么?

【问题讨论】:

尝试将typeof(ValuesContoller).GetTypeInfo().Assembly 替换为typeof(ValuesContoller).Assembly 这不是有效的方法或扩展。 我可以使用这个方法。你能用完整的 Startup.cs 更新你的问题吗? 尝试在你的控制器中插入[Route("api/[controller]")]。另外,尝试在应用程序的同一程序集中创建一个控制器,以确保 MVC 工作正常。 我在程序集中创建了一个控制器,但也没有工作。我没想到。有什么问题? 【参考方案1】:

也许你做错了什么。所以,这里是完成这项工作的步骤。

新建项目:ASP.NET Core Web Application (.NET Core); 选择 Web API 模板; 运行项目并访问“api/values”以确保其正常工作; 在名为 ClassLibrary 的解决方案中添加一个新项目:类库 (.NET Core); 删除Class1.cs,创建TestController.cs类;

在 ClassLibrary 项目的 project.json 中添加 MVC 依赖项:

"dependencies": 
  "NETStandard.Library": "1.6.0",
  "Microsoft.AspNetCore.Mvc": "1.0.0"
,

将您的 TestController.cs 更新为:

[Route("api/[controller]")]
public class TestController : Controller
  [HttpGet]
  public IEnumerable<string> Get() 
    return new string[]  "test1", "test2" ;
  

在您的 WebAPI 项目中添加对 ClassLibrary 的引用:右键单击“引用”->“添加引用...”或更新您的 project.json,如下所示:

"dependencies": 
  "Microsoft.NETCore.App": 
    "version": "1.0.0",
    "type": "platform"
  ,
  "Microsoft.AspNetCore.Mvc": "1.0.0",
  "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
  "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
  "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
  "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
  "Microsoft.Extensions.Configuration.Json": "1.0.0",
  "Microsoft.Extensions.Logging": "1.0.0",
  "Microsoft.Extensions.Logging.Console": "1.0.0",
  "Microsoft.Extensions.Logging.Debug": "1.0.0",
  "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
  "ClassLibrary": "1.0.0-*"
,

更新您的 Startup.cs ConfigureServices 方法:

public void ConfigureServices(IServiceCollection services) 
  services.AddMvc().AddApplicationPart(Assembly.Load(new AssemblyName("ClassLibrary")));

再次运行项目并访问“api/test”;

【讨论】:

谢谢,法布里科。这正是我所做的,我的机器上有一些非常奇怪的东西,因为我对我的启动进行了更改,然后将其返回到我的问题中的代码,现在它可以工作,但不知道原因。 我希望我能在几个小时前找到这个答案。它会为我节省很多时间。有时它归结为特定的搜索词。干得好。【参考方案2】:

你不需要在主 web 应用的 Startup.cs 中做任何特殊的事情,它只需要引用类库。

一个技巧是,要发现您的控制器,您的类库必须在其 project.json 文件依赖项部分中直接引用 MVC:

"Microsoft.AspNetCore.Mvc": "1.0.*"

更新:对于 MVC 应用程序,我的 Startup 不需要任何特别的东西,但在我的一个 api 应用程序中,我确实需要它,可能是因为使用了属性路由。

services.AddMvc()
            .AddApplicationPart(Assembly.Load(new AssemblyName("CSharp.WebLib")))
            ;

其中 CSharp.WebLib 是我的类库的名称

【讨论】:

在 Asp.Net Core 6 中,您不再需要包含 AddApplicationPart(Assembly.Load(new AssemblyName("CSharp.WebLib")))。它会自动选择带有属性路由的控制器【参考方案3】:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)

    ...

    services.AddMvc()
        .AddApplicationPart(typeof(Namespace.SubNamespace.ControllerName).Assembly);

    ...

【讨论】:

这与其他响应完全相同,您正在从类型返回完整程序集...【参考方案4】:

@法布里西奥·科赫

如果我在 dotnet 5 中发布启用 Trimming 选项,它如何处理以下代码。

public void ConfigureServices(IServiceCollection services) 
  services.AddMvc().AddApplicationPart(Assembly.Load(new AssemblyName("ClassLibrary")));

【讨论】:

以上是关于从 ASP.NET 核心中的类库加载和注册 API 控制器的主要内容,如果未能解决你的问题,请参考以下文章

使用 JWT 令牌保护 asp.net 核心 Web api 时如何从 Azure AD 获取用户

asp.net MVC - 我可以从类库中引用视图吗?

从控制器重新加载配置(asp.net 核心应用程序)

限制对 ASP.NET Web API 和身份中的注册用户的访问

在应用程序启动时注册所有实现接口的类 (Web API)

Razor 页面在 ASP.NET Core RC2 运行时看不到引用的类库