如何包装Web API响应(在.net核心中)以保持一致性? [英] How can I wrap Web API responses(in .net core) for consistency?

查看:35
本文介绍了如何包装Web API响应(在.net核心中)以保持一致性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要返回一个一致的响应,并为所有请求返回类似的结构.在以前的.NET Web API中,我能够使用DelegatingHandler(MessageHandlers)实现此目的.我要返回的对象将封装在Result元素中.因此,基本上json响应将采用这种结构:

I need to return a consistent response with a similar structure returned for all requests. In the previous .NET web api, I was able to achieve this using DelegatingHandler (MessageHandlers). The object that I want to return will be encapsulated in the Result element. So basically the json response will be in this kind of structure:

示例1:

{
    "RequestId":"some-guid-abcd-1234",
    "StatusCode":200,
    "Result":
    {
        "Id":42,
        "Todo":"Do Hello World"
    }
}

示例2:

{
    "RequestId":"some-guid-abcd-1235",
    "StatusCode":200,
    "Result":
    {
        [
            {        
                "Id":42,
                "Todo":"Print Hello World"
            },
            {        
                "Id":43,
                "Todo":"Print Thank you"
            }           
        ]

    }
}

在.NET核心中,看来我需要通过中间件来执行此操作.我曾尝试过,但是当您可以调用HttpResponseMessage.TryGetContentValue来获取内容并将其包装在全局/通用响应模型中时,我没有看到更好的方法来像在以前的Web API中那样提取内容.

In .NET core, it looks like I need to do this via middleware. I tried but I don't see a nicer way to extract the content like how in the previous web API when you can call HttpResponseMessage.TryGetContentValue to get the content and wrap it in global/common response model.

如何在.NET Core中实现相同的目标?

How can I achieve the same in .NET core?

推荐答案

我创建了一个中间件来包装响应以保持一致性.为了方便注册此中间件,我还为IApplicationBuilder创建了扩展方法.因此,在Startup.cs中,注册中间件:

I created a middleware to wrap the response for consistency. I also created an extension method to IApplicationBuilder for convenience when registering this middleware. So in Startup.cs, register middleware :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    //code removed for brevity.
    ...
    app.UseResponseWrapper();

    //code removed for brevity.
    ...
}

这是中间件代码:

using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;

namespace RegistrationWeb.Middleware
{
    public class ResponseWrapper
    {
        private readonly RequestDelegate _next;

        public ResponseWrapper(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            var currentBody = context.Response.Body;

            using (var memoryStream = new MemoryStream())
            {
                //set the current response to the memorystream.
                context.Response.Body = memoryStream;

                await _next(context);

                //reset the body 
                context.Response.Body = currentBody;
                memoryStream.Seek(0, SeekOrigin.Begin);

                var readToEnd = new StreamReader(memoryStream).ReadToEnd();
                var objResult = JsonConvert.DeserializeObject(readToEnd);
                var result = CommonApiResponse.Create((HttpStatusCode)context.Response.StatusCode, objResult, null);
                await context.Response.WriteAsync(JsonConvert.SerializeObject(result));
            }
        }

    }

    public static class ResponseWrapperExtensions
    {
        public static IApplicationBuilder UseResponseWrapper(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<ResponseWrapper>();
        }
    }


    public class CommonApiResponse
    {
        public static CommonApiResponse Create(HttpStatusCode statusCode, object result = null, string errorMessage = null)
        {
            return new CommonApiResponse(statusCode, result, errorMessage);
        }

        public string Version => "1.2.3";

        public int StatusCode { get; set; }
        public string RequestId { get; }

        public string ErrorMessage { get; set; }

        public object Result { get; set; }

        protected CommonApiResponse(HttpStatusCode statusCode, object result = null, string errorMessage = null)
        {
            RequestId = Guid.NewGuid().ToString();
            StatusCode = (int)statusCode;
            Result = result;
            ErrorMessage = errorMessage;
        }
    }
}

这篇关于如何包装Web API响应(在.net核心中)以保持一致性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆