当前位置 : 主页 > 网络编程 > ASP >

asp.net-web-api – 带协议缓冲区的ASP.NET WebApi – 错误处理

来源:互联网 收集:自由互联 发布时间:2021-06-24
语境: 我现在拥有的: 3层应用程序 客户端 – 服务器通信 服务器:ASP.NET WebApi v1 客户端:HttpClient 序列化 – JSON.NET 然而, JSON.NET很慢 JSON.NET在第一次调用时甚至更慢(我认为这是因为动
语境:

我现在拥有的:

> 3层应用程序
>客户端 – 服务器通信

>服务器:ASP.NET WebApi v1
>客户端:HttpClient

>序列化 – JSON.NET

然而,

> JSON.NET很慢
> JSON.NET在第一次调用时甚至更慢(我认为这是因为动态生成了串行器程序集).这对我来说太慢了 – 根据我需要尽可能优化第一次通话的要求.

我正在考虑使用protobuf-net而不是JSON.NET.在一个简单的PoC应用程序上,它显示的速度是第一次调用的两倍多,特别是当我为协议缓冲区序列化程序预先生成程序集时.

所以我使用protobuf-net实现了MediaTypeFormatter,除了一件事 – 序列化错误之外,一切运行良好.

这是异常传递给客户端的方式:

public class ExceptionShielderAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        context.Response = context.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, context.Exception);
    }
}

在内部,CreateErrorResponse方法创建HttpError的实例(它继承自Dictionary [string,object])并将其写入内容.

默认情况下,protobuf-net对HttpError一无所知所以我试图将HttpError添加到protobuf运行时模型,如下所示

typeModel.Add(typeof (HttpError), true);

但是,当我打电话时,它没有帮助

typeModel.Compile("ModelSerializer", "ModelSerializer.dll")

它抛出InvalidOperationException:没有为类型:System.Object定义的序列化程序.
可能是由于protobuf-net不支持Dictionary [string,object]的类型.

问题:

>我有什么办法可以正确地序列化错误,或者我应该避免使用开箱即用的错误分析并在服务器上实现我自己的错误处理,该服务器使用protobuf知道的众所周知的类型?
> protobuf根本不是我问题的好选择吗?

这是一个使用protobuf-net启用System.Web.Http.HttpError序列化的片段

namespace WS
    using System;
    using System.Runtime.Serialization;
    using System.Web.Http;
    using WebApiContrib.Formatting;

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            config.Formatters.Add(new ProtoBufFormatter());

            ProtoBufFormatter.Model.Add(typeof(HttpErrorProto), true);
            var model = ProtoBufFormatter.Model.Add(typeof(HttpError), false);
            model.IgnoreListHandling = true;
            model.SetSurrogate(typeof(HttpErrorProto));
        }
    }

    [DataContract]
    public class HttpErrorProto
    {
        [DataMember(Order = 1)]
        public String ExceptionMessage { get; set; }
        [DataMember(Order = 2)]
        public String ExceptionType { get; set; }
        [DataMember(Order = 3)]
        public String InnerException { get; set; }
        [DataMember(Order = 4)]
        public String MessageDetail { get; set; }
        [DataMember(Order = 5)]
        public String Message { get; set; }
        [DataMember(Order = 6)]
        public String ModelState { get; set; }
        [DataMember(Order = 7)]
        public String StackTrace { get; set; }


        public static implicit operator HttpErrorProto(HttpError error)
        {
            return error == null ? null : new HttpErrorProto
            {
                ExceptionMessage = error.ContainsKey("ExceptionMessage") ? error["ExceptionMessage"] as string : null,
                ExceptionType = error.ContainsKey("ExceptionType") ? error["ExceptionType"] as string : null,
                InnerException = error.ContainsKey("InnerException") ? error["InnerException"] as string : null,
                MessageDetail = error.ContainsKey("MessageDetail") ? error["MessageDetail"] as string : null,
                Message = error.Message,
                ModelState = error.ContainsKey("ModelState") ? error["ModelState"] as string : null,
                StackTrace = error.ContainsKey("StackTrace") ? error["StackTrace"] as string : null
            };
        }

        public static implicit operator HttpError(HttpErrorProto error)
        {
            return error == null ? null : new HttpError
            {
                Message = error.Message
                ...
            };
        }
    }
}
网友评论