前面我們已經把服務都啟動了,然後我們試試請求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.<<UseMiddlewareInterface>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.<<UseMiddlewareInterface>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.<<UseMiddlewareInterface>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.<<UseMiddlewareInterface>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.<<UseMiddlewareInterface>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.<<UseMiddlewareInterface>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<AbpSystemTextJsonSerializerOptions>(options => options.JsonSerializerOptions.Converters.Add(new ExceptionJsonConverter<Exception>()));
}
再次請求,我們發現介面HTTP狀態碼變成了401,沒有再次出現序列化不支援的異常了。
我們通過swagger的Authorize獲取token之後隨便輸入再次發出請求,請求再次500,但是500返回內容正常,沒有再次出現序列化不支援的異常。
到這我們就解決了System.Text.Json不支援序列化Exception的一個問題。