自定义 ocelot 中间件输出自定义错误信息
自定義 ocelot 中間件輸出自定義錯誤信息
Intro
ocelot 中默認(rèn)的 Response 中間件在出錯的時候只會設(shè)置 StatusCode 沒有具體的信息,想要展示自己定義的錯誤信息的時候就需要做一些自定義了,對 ocelot 中的 Response 中間件做了一些小改動,實現(xiàn)了輸出自定義錯誤信息的功能。
Implement
實現(xiàn)起來其實也很簡單,原來的有錯誤的時候,只設(shè)置了 Response 的 StatusCode,我們只需要加一下輸出錯誤信息就可以了,錯誤信息的格式完全可以自定義,實現(xiàn)代碼如下:
public?class?CustomResponseMiddleware?:?Ocelot.Middleware.OcelotMiddleware {private?readonly?RequestDelegate?_next;private?readonly?IHttpResponder?_responder;private?readonly?IErrorsToHttpStatusCodeMapper?_codeMapper;public?CustomResponseMiddleware(RequestDelegate?next,IHttpResponder?responder,IErrorsToHttpStatusCodeMapper?codeMapper,IOcelotLoggerFactory?loggerFactory):?base(loggerFactory.CreateLogger<UrlBasedAuthenticationMiddleware>()){_next?=?next;_responder?=?responder;_codeMapper?=?codeMapper;}public?async?Task?Invoke(HttpContext?httpContext){await?_next.Invoke(httpContext);if?(httpContext.Response.HasStarted)return;var?errors?=?httpContext.Items.Errors();if?(errors.Count?>?0){Logger.LogWarning($"{errors.ToErrorString()}?errors?found?in?{MiddlewareName}.?Setting?error?response?for?request?path:{httpContext.Request.Path},?request?method:?{httpContext.Request.Method}");var?statusCode?=?_codeMapper.Map(errors);var?error?=?string.Join(",",?errors.Select(x?=>?x.Message));httpContext.Response.StatusCode?=?statusCode;//?output?errorawait?httpContext.Response.WriteAsync(error);}else{Logger.LogDebug("no?pipeline?errors,?setting?and?returning?completed?response");var?downstreamResponse?=?httpContext.Items.DownstreamResponse();await?_responder.SetResponseOnHttpContext(httpContext,?downstreamResponse);}} }相比之前的中間件,主要變化就是對于 Error 的處理,感覺這里 ocelot 可以抽象一下,增加一個接口 ErrorResponser 之類的,現(xiàn)在的 responder 沒有直接把錯誤信息直接傳進(jìn)去造成一些不變,加一個 ErrorResponder 只處理 Error 相關(guān)的邏輯,把錯誤信息直接傳進(jìn)去,這樣用戶也就可以更為靈活的注冊自己的服務(wù)來無侵入的修改發(fā)生錯誤時的行為
Sample
要使用這個中間件,就要自己定義 ocelot 中間件的配置,把默認(rèn)的 Response 中間件替換成自己的中間件即可,示例如下:
app.UseOcelot((ocelotBuilder,?ocelotConfiguration)?=> {//?this?sets?up?the?downstream?context?and?gets?the?configapp.UseDownstreamContextMiddleware();//?This?is?registered?to?catch?any?global?exceptions?that?are?not?handled//?It?also?sets?the?Request?Id?if?anything?is?set?globallyocelotBuilder.UseExceptionHandlerMiddleware();//?This?is?registered?first?so?it?can?catch?any?errors?and?issue?an?appropriate?response//ocelotBuilder.UseResponderMiddleware();ocelotBuilder.UseMiddleware<CustomResponseMiddleware>();ocelotBuilder.UseDownstreamRouteFinderMiddleware();ocelotBuilder.UseMultiplexingMiddleware();ocelotBuilder.UseDownstreamRequestInitialiser();ocelotBuilder.UseRequestIdMiddleware();//?自定義中間件,模擬沒有權(quán)限的情況ocelotBuilder.Use((ctx,?next)?=>{ctx.Items.SetError(new?UnauthorizedError("No?permission"));return?Task.CompletedTask;});//ocelotBuilder.UseMiddleware<UrlBasedAuthenticationMiddleware>();ocelotBuilder.UseLoadBalancingMiddleware();ocelotBuilder.UseDownstreamUrlCreatorMiddleware();ocelotBuilder.UseHttpRequesterMiddleware(); }).Wait();除了上面的 Response 中間件,為了測試方便,我還加了一個中間件,直接設(shè)置了一個 Error 來方便測試,隨便訪問一個 Path 來測試一下是不是會有錯誤信息,可以看到正如預(yù)期的結(jié)果一樣,輸出了我們自定義的錯誤信息
More
完整示例可以從 Github 上獲取 https://github.com/WeihanLi/AspNetCorePlayground/tree/master/OcelotDemo
Reference
https://github.com/WeihanLi/AspNetCorePlayground/blob/master/OcelotDemo/OcelotMiddleware/CustomResponseMiddleware.cs
https://github.com/WeihanLi/AspNetCorePlayground/tree/master/OcelotDemo
https://github.com/ThreeMammals/Ocelot/blob/17.0.0/src/Ocelot/Responder/HttpContextResponder.cs
https://github.com/ThreeMammals/Ocelot/blob/17.0.0/src/Ocelot/Responder/Middleware/ResponderMiddleware.cs
總結(jié)
以上是生活随笔為你收集整理的自定义 ocelot 中间件输出自定义错误信息的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在 ASP.Net Core 中使用
- 下一篇: 为什么对gRPC做负载均衡会很棘手?