• ABP微服务学习系列-修复System.Text.Json不支持序列化Exception


    前面我们已经把服务都启动了,然后我们试试请求API。
    发现请求出现500


    返回错误

    System.NotSupportedException: Serialization and deserialization of 'System.Reflection.MethodBase' instances are not supported. Path: $.Exceptions.TargetSite.
     ---> System.NotSupportedException: Serialization and deserialization of 'System.Reflection.MethodBase' instances are not supported.
       at System.Text.Json.Serialization.Converters.UnsupportedTypeConverter`1.Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
       at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
       at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.Serialization.Converters.ListOfTConverter`2.OnWriteResume(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryWrite(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
       at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
       --- End of inner exception stack trace ---
       at System.Text.Json.ThrowHelper.ThrowNotSupportedException(WriteStack& state, NotSupportedException ex)
       at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.Serialization.JsonConverter`1.WriteCoreAsObject(Utf8JsonWriter writer, Object value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.JsonSerializer.WriteCoreAsObject(Utf8JsonWriter writer, Object value, JsonTypeInfo jsonTypeInfo)
       at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
       at System.Text.Json.JsonSerializer.WriteCore[TValue](Utf8JsonWriter writer, TValue& value, JsonTypeInfo`1 jsonTypeInfo)
       at System.Text.Json.JsonSerializer.WriteString[TValue](TValue& value, JsonTypeInfo`1 jsonTypeInfo)
       at Volo.Abp.Json.SystemTextJson.AbpSystemTextJsonSerializer.Serialize(Object obj, Boolean camelCase, Boolean indented)
       at Volo.Abp.RabbitMQ.Utf8JsonRabbitMqSerializer.Serialize(Object obj)
       at Volo.Abp.EventBus.RabbitMq.RabbitMqDistributedEventBus.PublishAsync(Type eventType, Object eventData, IBasicProperties properties, Dictionary`2 headersArguments)
       at Volo.Abp.EventBus.RabbitMq.RabbitMqDistributedEventBus.PublishToEventBusAsync(Type eventType, Object eventData)
       at Volo.Abp.EventBus.Distributed.DistributedEventBusBase.PublishAsync(Type eventType, Object eventData, Boolean onUnitOfWorkComplete, Boolean useOutbox)
       at Volo.Abp.EventBus.UnitOfWorkEventPublisher.PublishDistributedEventsAsync(IEnumerable`1 distributedEvents)
       at Volo.Abp.Uow.UnitOfWork.CompleteAsync(CancellationToken cancellationToken)
       at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
       at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
       at Volo.Abp.Auditing.AuditingManager.SaveAsync(DisposableSaveHandle saveHandle)
       at Volo.Abp.Auditing.AuditingManager.DisposableSaveHandle.SaveAsync()
       at Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Volo.Abp.AspNetCore.Serilog.AbpSerilogMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
       at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
       at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
       at Volo.Abp.AspNetCore.Security.Claims.AbpClaimsMapMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
       at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
       at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Volo.Abp.AspNetCore.Tracing.AbpCorrelationIdMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
    

    这是由于接口抛出异常,但是System.Text.Json不支持序列化Exception导致的。
    如何解决呢,这里我们需要自己自定义一个ExceptionJsonConverter
    在Shared.Hosting.AspNetCore添加JsonConverters目录,新建一个ExceptionJsonConverter类。
    类继承JsonConverter泛型接口,并重写他的方法。
    完整converter代码如下:

    using System;
    using System.Linq;
    using System.Text.Json;
    using System.Text.Json.Serialization;
    
    namespace FunShow.Shared.Hosting.AspNetCore.JsonConverters
    {
        public class ExceptionJsonConverter<TExceptionType>: JsonConverter<TExceptionType> where TExceptionType : Exception
        {
            public override bool CanConvert(Type typeToConvert)
            {
                return typeof(Exception).IsAssignableFrom(typeToConvert);
            }
    
            public override TExceptionType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            {
                throw new NotSupportedException("Deserializing exceptions is not allowed");
            }
    
            public override void Write(Utf8JsonWriter writer, TExceptionType value, JsonSerializerOptions options)
            {
                var serializableProperties = value.GetType()
                    .GetProperties()
                    .Select(uu => new { uu.Name, Value = uu.GetValue(value) })
                    .Where(uu => uu.Name != nameof(Exception.TargetSite));
    
                if (options?.DefaultIgnoreCondition == System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull)
                {
                    serializableProperties = serializableProperties.Where(uu => uu.Value != null);
                }
    
                var propList = serializableProperties.ToList();
    
                if (propList.Count == 0)
                {
                    // Nothing to write
                    return;
                }
    
                writer.WriteStartObject();
    
                foreach (var prop in propList)
                {
                    writer.WritePropertyName(prop.Name);
                    JsonSerializer.Serialize(writer, prop.Value, options);
                }
    
                writer.WriteEndObject();
            }
        }
    }
    

    然后在FunShowSharedHostingAspNetCoreModule中添加如下代码:

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            Configure(options => options.JsonSerializerOptions.Converters.Add(new ExceptionJsonConverter()));
        }
    

    再次请求,我们发现接口HTTP状态码变成了401,没有再次出现序列化不支持的异常了。


    我们通过swagger的Authorize获取token之后随便输入再次发出请求,请求再次500,但是500返回内容正常,没有再次出现序列化不支持的异常。


    到这我们就解决了System.Text.Json不支持序列化Exception的一个问题。

  • 相关阅读:
    UniVue更新日志:使用ObservableList优化LoopList/LoopGrid组件的使用
    Java面试题:当任务数超过线程池的核心线程数时,如何让它不进入队列,而是直接启用最大线程数
    【Gazebo入门教程】第八讲 Gazebo中的日志与回放
    页面设计都有哪些好用的工具推荐?
    Java高并发编程实战2,原子性、可见性、有序性,傻傻分不清
    git push报错解决
    科创人·味多美CIO胡博:数字化是不流血的革命,正确答案藏在业务的田间地头
    Bert and its family
    Leetcode.2316 统计无向图中无法互相到达点对数
    北邮22级信通院数电:Verilog-FPGA(9)第九周实验(4)实现寄存器74LS374
  • 原文地址:https://www.cnblogs.com/fanshaoO/p/17172285.html