1

我已經使用web api創建了web應用程序。該應用程序包含一些Controllers例如TodoController如何用.NET中的api端點創建中間件核心

namespace TodoApi.Controllers 
{ 
    [Route("api/[controller]")] 
    public class TodoController : Controller 
    { 
     private readonly TodoContext _context; 

     public TodoController(TodoContext context) 
     { 
      _context = context; 
     }  

     [HttpGet] 
     public IEnumerable<TodoItem> GetAll() 
     { 
      return _context.TodoItems.ToList(); 
     } 
    } 
} 

如果我創建了GET要求 - /api/todo - 我得到待辦事項從數據庫列表中。

我有一個像上面那樣的控制器和API端點列表。

我想這個API分發到其他應用程序的理想像中間件 - 我的想法是登記Startup.cs這樣的:

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddTodoApi(); 
} 

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    app.UseTodoApi(); 
} 

這將是真棒使用情況我的API,但我不知道該怎麼控制器API端點重寫像中間件和返回相同的JSON數據相同方法使用經典Controllers

如何在.NET Core中編寫middleware以創建API endpoints

回答

3

取而代之的是單獨的中間件,可以從另一個組件配置MVC中間件發現控制器:

// using System.Reflection; 

public void ConfigureServices(IServiceCollection services) 
{ 
    ... 
    services 
     .AddMvc() 
     .AddApplicationPart(typeof(TodoController).GetTypeInfo().Assembly); 

控制器是MVC中間件的一部分,他們不是請求管道的一個單獨部分(但這是中間件)。當您註冊自定義中間件時,默認情況下會調用每個請求,並且您有HttpContext context作爲輸入參數來處理/編輯 請求/響應數據。但是,ASP.NET Core provides Map* extensions用作分支管道的約定。

Map根據給定請求路徑的匹配來分支請求管道。如果請求路徑以給定路徑開始,則分支被執行。

例子:

private static void HandleMapTodo(IApplicationBuilder app) 
{ 
    app.Run(async context => 
    { 
     await context.Response.WriteAsync("/api/todo was handled"); 
    }); 
} 

public void Configure(IApplicationBuilder app) 
{ 
    app.Map("/api/todo", HandleMapTodo); 
} 

注意,作爲中間件一無所知MVC中間件,你只有「原始」的請求訪問和沒有像模型綁定或MVC行動的過濾器功能。

+0

是否可能teoreticly使用.AddApplicationPart添加一些MVC Razor視圖以及?如果是這樣,你可以給樣品嗎? – Jenan

+0

@Jenan沒有使用過這個,所以不是100%肯定的,但理論上應該儘可能地發揮你的視圖在你的發佈輸出中的位置。考慮一下,如果你試圖找到任何問題與意見...也許要問一個不同的Q ... – Set

+0

是的,你說得對。謝謝。 – Jenan

1

因爲它看起來像完美的微服務方法(類似於我的團隊現在正在做的),我會創建一個客戶端程序集,可以使用您的API,包含您的TodoController的客戶端程序集,以及定義合同,以及接口,對於那個API,你可以在其他程序集中註冊它,因爲它是一箇中間件,你也可以在你的單元測試中嘲笑這種行爲。

所以,我說,你可以注入在ConfigureServices方法你的客戶,你可以創建:

public static IServiceCollection AddTodoRestClient(this IServiceCollection services) 
{ 
    services.AddSingleton<ITodoRestClient, TodoRestClient>(); 
    return services; 
} 

同時認爲,你將需要提供enpoint因此,它可能是這樣的:

public static IServiceCollection AddConfiguredTodoClient(this IServiceCollection services, string todoEndpoint) 
{ 
    AddTodoClient(services); 
    ITodoRestClient todoRestClient = services.BuildServiceProvider().GetService<ITodoRestClient>(); 
    // Imagine you have a configure method... 
    todoRestClient.Configure(services, todoEndpoint); 
    return services; 
} 

您可以在TodoRestClientInjector類中創建這些方法,並在啓動時在Configure方法中使用它們。

我希望它能幫助

---更多的細節,ANSWER評論---

對我來說TodoClient是實現到待辦事項API調用REST客戶端庫,(我已經編輯以前的代碼是TodoRestClient)方法,即CreateTodoItem(TodoDto todoItem)實現將調用TodoController.Post([FromBody]項)還是GetTodos(),它將調用TodoController.Get()等,等等... 。

關於enpoints ...這種方法意味着(至少)有兩個不同的應用程序(.NET Core應用程序),在一方面是擁有您的TodoController的ASP NET Core應用程序,另一方面是一個控制檯應用程序或另一個ASP NET Core API,您將在其上啓動類,然後在Rest客戶端(Todo Rest客戶端)配置上執行啓動類...

在微服務的方法使用泊塢窗,在開發環境中,您將使用泊塢窗,撰寫-YML,但在傳統的方法,你會用實際端口來定義端點...

所以,想象您在第二個服務中需要使用TodoController的控制器來實現,因此我將使用上述方法,並且「SecondController」將如下所示:

public class SecondController : Controller 
    { 
     private readonly SecondContext _context; 
     private readonly TodoRestClient _todoRestClient; 

     public TodoController(SecondContext context, ITodoRestClient todoRestClient) 
     { 
      _context = context; 
      _todoRestClient= todoRestClient; 
     }  

// Whatever logic in this second controller... but the usage would be like: 

_todoRestClient.GetTodos()

} 

只是一些最後提示:這是關鍵,因爲它增加了延遲,而且越來越多,如果這發生在級聯,以儘量減少服務之間的調用。另外考慮Docker的使用情況,看起來很具挑戰性,但啓動起來相當容易,而且實際上,它被認爲可以用於您提供的場景和我的解決方案。

再次,我希望它有幫助。

胡安

+0

好的。我很可能會看到這個DI系統方法,但我怎樣才能創建特定的API端點?與控制器方法連接在哪裏?您能否使用API​​更詳細地解釋您的想法?什麼是TodoClient? – Jenan

+0

當然,我會在最後編輯我的答案...... – Juan

+0

除了我最後的編輯, a)在.NET Core中創建一個REST客戶端:https://docs.microsoft.com/en-我們/ dotnet/csharp/tutorials/console-webapiclient b)Polly,NET彈性和瞬態故障處理庫:https://github.com/App-vNext/Polly – Juan