簡體   English   中英

.NET 6 - 連接基類的路由

[英].NET 6 - Concatenate routes of base classes

在我的代碼中,我有以下基類:

[ApiController]
[Produces("application/json")]
[Route("modules/example/v{apiVersion:apiVersion}")]
public abstract class ModuleControllerBase : ControllerBase
{ ... }

我的 API 處理的數據有時具有復合主鍵,為此我定義了另一個繼承上述內容的基類:

[ApiController]
[Route("subsidiary/{subsidiaryId:int:required}/branch/{branchId:int:required}")]
public abstract class CollectionControllerBase : ModuleControllerBase
{ ... }

然后,最后,上述類的實現將如下所示:

[ApiController]
[Route("[controller]")]
public class WorkOrderLineController : CollectionControllerBase
{ ... }

我的想法是,這會在運行時產生一個類似{api-url}/modules/example/v1/subsidiary/1/branch/3/WorkOrderLine/{some-endpoint-in-WorkOrderLineController}

但是,當 Swagger 在瀏覽器中打開時,它只顯示來自已實現控制器的路由。 Swagger 生成的端點文檔

是否有一些我需要更改的默認配置,或者我誤解了什么?

我只能找到有關處理多態響應模型的結果。

在 ASP.NET Core 中, Route屬性是“靜態的”,因為它只是從指定的字符串值中提取路由,用[controller]標記替換控制器名稱。

如果您想要您指定的行為,您可以創建一個實現IRouteTemplateProvider的新屬性創建一個自定義應用程序模型

自定義屬性,例如NestedRouteAttribute ,可能會更容易。 我沒有代碼示例,但這里有一個描述:

您可以讓IRouteTemplateProvider.Template實現遍歷繼承樹(使用controller.GetType().BaseType ),直到它到達ControllerBase 獲得類型列表后,您可以遍歷從父類型到子類型的列表,連接Route屬性的值。

編輯:這是一個快速而骯臟的例子:

using System.Reflection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;

[AttributeUsage(AttributeTargets.Class)]
public class NestedRouteAttribute : Attribute, IRouteTemplateProvider
{
    Type _controllerType;
    string _template;

    public NestedRouteAttribute(string template, Type t)
    {
        _controllerType = t;
        _template = template;
    }

    public string? Template
    {
        get
        {
            // Look up the route from the parent type. This only goes up one level, but if the parent class also has a `NestedRouteAttribute`, then it should work recursively.
            Type? bt  = _controllerType.BaseType;

            IRouteTemplateProvider? routeAttr = bt?.GetCustomAttributes().Where(a => a is IRouteTemplateProvider).FirstOrDefault() as IRouteTemplateProvider;
            return Path.Join(routeAttr?.Template, _template);
        }
    }

    public int? Order => null;

    public string? Name => _template;
}
[Route("api/v1")]
public class MyApiControllerBase : ControllerBase { }
[NestedRoute("api/v1", typeof(MyBranchControllerBase))]
public class MyBranchControllerBase : ControllerBase { }
using Microsoft.AspNetCore.Mvc;

[NestedRoute("[controller]", typeof(FooController))]
public class FooController : MyApiControllerBase
{
    [HttpGet]
    public string HelloWorld() => "hello, world!";

}

請求/api/v1/branch/division/foo應該返回hello, world! .

注意1:由於屬性沒有關於它們所附加的類型的信息,如果你想擺脫在屬性中使用typeof(FooController) ,我認為你需要使用自定義應用程序模型反而。 您也可以更改 API 以在 NestedRouteAttribute 中聲明父類。

注意 2:這僅從父類中檢索第一個路由屬性,因此不支持同一類上的多個路由屬性。 這被微軟認為是不好的做法,但如果你需要它,我認為這是一個單獨的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM