首页 > 解决方案 > 如何构建自定义 WebApi 路由,例如“package/{packageName}/{controller}”以路由到单独程序集中的应用程序部件?

问题描述

我们的应用程序在我们称为包的外部程序集中加载控制器。我想创建一个路由,该路由使用诸如package/BillingPackage/Invoice而不是api/BillingPackage/Invoice. 这是我所做的:

启动.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseEndpointRouting()
        .UseMvc(routes =>
    {
        routes.MapRoute(
            name: "package", 
            template: "package/{package}/{controller}/{id?}");
        routes.MapRoute("api", "api/{controller}/{action=Get}/{id?}");            
        routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
    app.UseStaticFiles();
}

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    var source = new PackageAssemblySource(Configuration);
    var packageAssemblies = source.Load();
    var builder = new ContainerBuilder();
    builder.RegisterModule(new WebApiModule(packageAssemblies));

    services
        .AddMvc()
        .ConfigureApplicationPartManager(manager =>
        {
            // Add controllers and parts from package assemblies.
            foreach (var assembly in packageAssemblies)
            {
                manager.ApplicationParts.Add(new AssemblyPart(assembly));
            }
        });
        .AddControllersAsServices() // Now that AssemblyParts are loaded.
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);;

    builder.Populate(services);
    ApplicationContainer = builder.Build();

    return new AutofacServiceProvider(ApplicationContainer);
}

然后我定义一个这样的控制器:

[Route("package/BillingPackage/[controller]", Name = "Invoice")]
public class InvoiceController : ControllerBase
{
    [HttpGet()]
    public ActionResult<Invoice> Get()
    {
        return new SampleInvoice();
    }
}

即使这样,也会package/BillingPackage/Invoice产生 404 而api/BillingPackage/Invoice不会。如何让我的 WebApi 服务于端点package而不是api

标签: c#asp.net-coreasp.net-core-webapiasp.net-core-2.2

解决方案


您可能遇到与模板的路由冲突: "package/{package}/{controller}/{id?}"

如果在控制器上使用属性路由,则删除该基于约定的路由

要获得所需的行为,您需要包含一个模板参数[Route("package/{package}/[controller]", Name = "Invoice")]以及一个方法/操作参数public ActionResult<Invoice> Get(string package),该参数将从 URL 中的匹配值填充。

例如

[Route("package/{package}/[controller]", Name = "Invoice")]
public class InvoiceController : ControllerBase {

    //GET package/BillingPackage/Invoice
    [HttpGet()]
    public ActionResult<Invoice> Get(string package) {
        return new SampleInvoice();
    }
}

参考路由到 ASP.NET Core 中的控制器操作


推荐阅读