加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – Owin Middleware vs ExceptionHandler vs HttpMessag

发布时间:2020-12-15 22:34:57 所属栏目:asp.Net 来源:网络整理
导读:请任何人给我一些想法,以下三个模块在asp.net Web API 2.1中一起工作 Owin中间件 HttpMessageHandler(或DelegatingHandler) ExceptionHandler 我想要做的是开发和提供一个不变格式的json数据的web api,意味着如果实际的数据是 {"Id":1,"UserName":"abc","Ema
请任何人给我一些想法,以下三个模块在asp.net Web API 2.1中一起工作

> Owin中间件
> HttpMessageHandler(或DelegatingHandler)
> ExceptionHandler

我想要做的是开发和提供一个不变格式的json数据的web api,意味着如果实际的数据是

{"Id":1,"UserName":"abc","Email":"abc@xyz.com"}

然后我喜欢提供json

{__d:{"Id":1,"Email":"abc@xyz.com"},code:200,somekey: "somevalue"}

为此,我尝试使用自定义ActionFilterAttribute,但我觉得(仍然不能确认),如果代码遇到异常,这样做不能提供类似的格式数据

请建议我最好的方向.

这是我的简短的自定义属性代码片段.还建议我是自定义属性是好的目的

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,Inherited = true,AllowMultiple = false)]
public class ResponseNormalizationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
            base.OnActionExecuted(actionExecutedContext);
            var response = actionExecutedContext.Response;
            object contentValue;
            if (response.TryGetContentValue(out contentValue))
            {
                var nval = new { data=contentValue,status = 200 };


                var newResponse = new HttpResponseMessage { Content = new ObjectContent(nval.GetType(),nval,new JsonMediaTypeFormatter()) };
                newResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                actionContext.Response = newResponse;
            }
     }
}

解决方法

如果您不使用Owin中间件,则可以全局包装所有响应,以便使用委托处理程序返回常量格式的json数据.

编写一个继承自DelegatingHandler的自定义处理程序:

public class ApiResponseHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,CancellationToken cancellationToken)
    {
        var response = await base.SendAsync(request,cancellationToken);

        return BuildResponse(request,response);
    }

    private static HttpResponseMessage BuildResponse(HttpRequestMessage request,HttpResponseMessage response)
    {
        object content;
        string errorMessage = null;

        if (response.TryGetContentValue(out content) && !response.IsSuccessStatusCode)
        {
            HttpError error = content as HttpError;

            if (error != null)
            {
                content = null;
                errorMessage = error.Message;
            }
        }

        var newResponse = request.CreateResponse(response.StatusCode,new ApiResponse((int)response.StatusCode,content,errorMessage));

        foreach (var header in response.Headers)
        {
            newResponse.Headers.Add(header.Key,header.Value);
        }

        return newResponse;
    }
}

//ApiResponse is your constant json response
public class ApiResponse
{

    public ApiResponse(int statusCode,object content,string errorMsg)
    {
        Code = statusCode;
        Content = content;
        Error = errorMsg;
        Id = Guid.NewGuid().ToString();
    }

    public string Error { get; set; }

    //your actual data is mapped to the Content property
    public object Content { get; set; }
    public int Code { get; private set; }
    public string Id { get; set; }
}

在WebApiConfig.cs中注册处理程序:

public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();
        ...

        config.MessageHandlers.Add(new ApiResponseHandler());

        config.Routes.MapHttpRoute(
            name: "DefaultApi",routeTemplate: "{controller}/{id}",defaults: new { id = RouteParameter.Optional }
        );

        ...
    }

我在SO中发布了一个类似的答案,但这是在.NET Core中,并被实现为一个OWIN中间件(因为DelegatingHandler在.NET Core中). How can I wrap Web API responses(in .net core) for consistency?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读