首页 > 解决方案 > 如何使用 asp.net core 2 中间件包装 graphql.net 端点响应?

问题描述

我有使用 asp.net web api2 开发的 REST API。我正在使用 asp.net core 2 将 REST API 迁移到 GraphQL.net 端点。在现有的 REST API 代码中,我有一个委托处理程序,用于使用附加数据扩展 REST API 调用的结果,在这种情况下,将本地化数据添加到response.Since Delegating 处理程序在 asp.net core 2 中不再支持。我正在尝试将现有的 Delegating 处理程序迁移到中间件组件。

出于参考目的,我遵循了以下详细信息:使用 OWIN 中间件扩展 WebApi 响应https://www.devtrends.co.uk/blog/wrapping-asp.net-web-api-responses-for-consistency-and-to - 提供附加信息

在这里,我有几个疑问:

  1. 在 Middlware 的情况下如何映射以下代码?var response = await base.SendAsync(request, cancelToken);

  2. 我应该将中间件放在 Startup.cs 的配置方法中。

  3. 与现有 Delegating Handler 等效的中间件

代码:

public class CommonResponserHandler : DelegatingHandler
{
    ICommonService _commonService = new CommonService();
    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        string locale = string.Empty;
        if (request.Headers.Contains("Accept-Language"))
        {
            locale = request.Headers.GetValues("Accept-Language").First();
        }

        bool initialAuthorizationStatus = GetInitialAuthorization(request);
        var response = await base.SendAsync(request, cancellationToken);
        APIResult commonResponse;
        if (response.TryGetContentValue<APIResult>(out commonResponse))
        {
            //populate common response here;
            UpdateCommonResponse(request, response, commonResponse);
            //UpdateCommonResponse(basicResponse, commonResponse);
            HttpResponseMessage newResponse;
            bool authorizatinCheckResult = AssertAuthorization(initialAuthorizationStatus, request);
            if (authorizatinCheckResult)
            {
                newResponse = request.CreateResponse(response.StatusCode, commonResponse);
            }
            else
            {
                var unAuthorisedResult = new APIResult{Authorized = false, UserMessage = Constants.Unauthorized, Locale = new Locale(_commonService.GetLanguageFromLocale(locale))};
                newResponse = request.CreateResponse(HttpStatusCode.Unauthorized, unAuthorisedResult);
                var jsonSerializerSettings = new JsonSerializerSettings{ContractResolver = new CamelCasePropertyNamesContractResolver()};
                HttpContext.Current.Items["401message"] = JsonConvert.SerializeObject(unAuthorisedResult, Formatting.Indented, jsonSerializerSettings);
            }

            //Add headers from old response to new response
            foreach (var header in response.Headers)
            {
                newResponse.Headers.Add(header.Key, header.Value);
            }

            return newResponse;
        }

        return response;
    }
}

任何人都可以帮助我提供解决问题的指导吗?

标签: c#jsonasp.net-web-api2asp.net-core-2.0

解决方案


请阅读ASP.NET Core 中间件文档以更好地了解中间件的工作原理。

中间件在其构造函数中接受下一个 RequestDelegate 并支持 Invoke 方法。例如:

 public class CommonResponserMiddleware
{
    private readonly RequestDelegate _next;

    public CommonResponserMiddleware(RequestDelegate next)
    {
        _next = next;

    }

    public async Task Invoke(HttpContext context)
    {
        //process context.Request

        await _next.Invoke(context);

        //process context.Response

    }
}

public static class CommonResponserExtensions
{
    public static IApplicationBuilder UseCommonResponser(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<CommonResponserMiddleware>();
    }
}

并在 Starup.cs 中使用:

public void Configure(IApplicationBuilder app) {
    //...other configuration

    app.UseCommonResponser();

    //...other configuration
}

您还可以参考相关的 SO 问题:

在 ASP.NET Core Web API 中注册一个新的 DelegatingHandler

如何包装 Web API 响应(在 .net 核心中)以保持一致性?


推荐阅读