Browse Source

添加Api 统一返回值接口

blazor2
王军 4 years ago
parent
commit
36370be366
  1. 36
      aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResult.cs
  2. 3
      aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Lion.AbpPro.Extension.csproj
  3. 129
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/Filters/ResultExceptionFilter.cs
  4. 3
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Lion.AbpPro.Shared.Hosting.Microservices.csproj
  5. 128
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/MVC/Filters/ResultExceptionFilter.cs
  6. 5
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/SharedHostingMicroserviceModule.cs
  7. 6
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/System/WrapResultAttribute.cs

36
aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResult.cs

@ -0,0 +1,36 @@
namespace Lion.AbpPro.Extension.Customs.Dtos
{
public class WrapResult<T>
{
private bool Success { get; set; }
private string Message { get; set; }
private T Data { get; set; }
private int Code { get; set; }
public WrapResult()
{
Success = true;
Message = "Success";
Data = default;
Code = 200;
}
public void SetSuccess(T data, string message = "Success", int code = 200)
{
Success = true;
Data = data;
Code = code;
}
public void SetFail(string message = "Fail", int code = 500)
{
Success = false;
Message = message;
Code = code;
}
}
}

3
aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Lion.AbpPro.Extension.csproj

@ -16,5 +16,8 @@
<PackageReference Include="Volo.Abp.AutoMapper" Version="$(AbpPackageVersion)" />
<PackageReference Include="Volo.Abp.ObjectMapping" Version="$(AbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<Folder Include="Customs\Attributes" />
</ItemGroup>
</Project>

129
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/Filters/ResultExceptionFilter.cs

@ -1,129 +0,0 @@
// using LionAbpPro.Attributes;
// using Microsoft.AspNetCore.Mvc;
// using Microsoft.AspNetCore.Mvc.Abstractions;
// using Microsoft.AspNetCore.Mvc.Filters;
// using Microsoft.Extensions.DependencyInjection;
// using Microsoft.Extensions.Logging;
// using Microsoft.Extensions.Logging.Abstractions;
// using Microsoft.Extensions.Options;
// using System;
// using System.Linq;
// using System.Text;
// using System.Threading.Tasks;
// using Volo.Abp;
// using Volo.Abp.AspNetCore.ExceptionHandling;
// using Volo.Abp.Authorization;
// using Volo.Abp.DependencyInjection;
// using Volo.Abp.Domain.Entities;
// using Volo.Abp.ExceptionHandling;
// using Volo.Abp.Http;
// using Volo.Abp.Json;
// using Volo.Abp.Validation;
//
//
// namespace LionAbpPro.Extensions.Filters
// {
// public class ResultExceptionFilter : IFilterMetadata, IAsyncExceptionFilter, ITransientDependency
// {
// public ILogger<ResultExceptionFilter> Logger { get; set; }
//
// private readonly IExceptionToErrorInfoConverter _errorInfoConverter;
// private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder;
// private readonly IJsonSerializer _jsonSerializer;
// private readonly AbpExceptionHandlingOptions _exceptionHandlingOptions;
//
// public ResultExceptionFilter(
// IExceptionToErrorInfoConverter errorInfoConverter,
// IHttpExceptionStatusCodeFinder statusCodeFinder,
// IJsonSerializer jsonSerializer,
// IOptions<AbpExceptionHandlingOptions> exceptionHandlingOptions)
// {
// _errorInfoConverter = errorInfoConverter;
// _statusCodeFinder = statusCodeFinder;
// _jsonSerializer = jsonSerializer;
// _exceptionHandlingOptions = exceptionHandlingOptions.Value;
// Logger = NullLogger<ResultExceptionFilter>.Instance;
// }
//
// public async Task OnExceptionAsync(ExceptionContext context)
// {
// if (!ShouldHandleException(context))
// {
// return;
// }
//
//
// await HandleAndWrapException(context);
// }
//
// protected virtual bool ShouldHandleException(ExceptionContext context)
// {
// if (context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.GetCustomAttributes(typeof(DontWrapResultAttribute), true).Any())
// {
// return true;
// }
//
// if (context.ActionDescriptor.GetMethodInfo().GetCustomAttributes(typeof(DontWrapResultAttribute), true).Any())
// {
// return true;
// }
// return false;
// }
//
// protected virtual async Task HandleAndWrapException(ExceptionContext context)
// {
// //TODO: Trigger an AbpExceptionHandled event or something like that.
//
// context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true");
// var statusCode = (int)_statusCodeFinder.GetStatusCode(context.HttpContext, context.Exception);
// context.HttpContext.Response.StatusCode = 200;
//
// var remoteServiceErrorInfo = _errorInfoConverter.Convert(context.Exception, _exceptionHandlingOptions.SendExceptionsDetailsToClients);
// remoteServiceErrorInfo.Code = context.HttpContext.TraceIdentifier;
// remoteServiceErrorInfo.Message = SimplifyMessage(context.Exception);
// var result = new WrapResult<object>();
// result.SetFail(remoteServiceErrorInfo.Message);
//
// // HttpResponse
// context.Result = new ObjectResult(result);
//
// // 写日志
// var logLevel = context.Exception.GetLogLevel();
// var remoteServiceErrorInfoBuilder = new StringBuilder();
// remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------");
// remoteServiceErrorInfoBuilder.AppendLine(_jsonSerializer.Serialize(remoteServiceErrorInfo, indented: true));
// Logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
// Logger.LogException(context.Exception, logLevel);
//
// await context.HttpContext
// .RequestServices
// .GetRequiredService<IExceptionNotifier>()
// .NotifyAsync(
// new ExceptionNotificationContext(context.Exception)
// );
//
// context.Exception = null; //Handled!
// }
//
// protected string SimplifyMessage(Exception error)
// {
// string message = string.Empty;
// switch (error)
// {
// case AbpAuthorizationException e:
// return message = "Authenticate failure!";
// case AbpValidationException e:
// return message = "Request param validate failure!";
// case EntityNotFoundException e:
// return message = "not found the entity!";
// case BusinessException e:
// return message = $"{e.Message}";
// case NotImplementedException e:
// return message = "not implement!";
// default:
// return message = "server internal error!";
// }
// }
// }
//
// }

3
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Lion.AbpPro.Shared.Hosting.Microservices.csproj

@ -16,4 +16,7 @@
<PackageReference Include="Swashbuckle.AspNetCore" Version="$(SwashbuckleVersion)" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="$(MicrosoftVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\frameworks\Extensions\src\Lion.AbpPro.Extension\Lion.AbpPro.Extension.csproj" />
</ItemGroup>
</Project>

128
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/MVC/Filters/ResultExceptionFilter.cs

@ -0,0 +1,128 @@
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Lion.AbpPro.Extension.Customs.Dtos;
using Volo.Abp;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.Authorization;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.ExceptionHandling;
using Volo.Abp.Http;
using Volo.Abp.Json;
using Volo.Abp.Validation;
namespace Microsoft.AspNetCore.Mvc.Filters
{
public class ResultExceptionFilter : IFilterMetadata, IAsyncExceptionFilter, ITransientDependency
{
private ILogger<ResultExceptionFilter> Logger { get; set; }
private readonly IExceptionToErrorInfoConverter _errorInfoConverter;
private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder;
private readonly IJsonSerializer _jsonSerializer;
private readonly AbpExceptionHandlingOptions _exceptionHandlingOptions;
public ResultExceptionFilter(
IExceptionToErrorInfoConverter errorInfoConverter,
IHttpExceptionStatusCodeFinder statusCodeFinder,
IJsonSerializer jsonSerializer,
IOptions<AbpExceptionHandlingOptions> exceptionHandlingOptions)
{
_errorInfoConverter = errorInfoConverter;
_statusCodeFinder = statusCodeFinder;
_jsonSerializer = jsonSerializer;
_exceptionHandlingOptions = exceptionHandlingOptions.Value;
Logger = NullLogger<ResultExceptionFilter>.Instance;
}
public async Task OnExceptionAsync(ExceptionContext context)
{
if (!ShouldHandleException(context))
{
return;
}
await HandleAndWrapException(context);
}
protected virtual bool ShouldHandleException(ExceptionContext context)
{
if (context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.GetCustomAttributes(typeof(WrapResultAttribute), true).Any())
{
return true;
}
if (context.ActionDescriptor.GetMethodInfo().GetCustomAttributes(typeof(WrapResultAttribute), true).Any())
{
return true;
}
return false;
}
protected virtual async Task HandleAndWrapException(ExceptionContext context)
{
//TODO: Trigger an AbpExceptionHandled event or something like that.
context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true");
var statusCode = (int)_statusCodeFinder.GetStatusCode(context.HttpContext, context.Exception);
context.HttpContext.Response.StatusCode = 200;
var remoteServiceErrorInfo = _errorInfoConverter.Convert(context.Exception, _exceptionHandlingOptions.SendExceptionsDetailsToClients);
remoteServiceErrorInfo.Code = context.HttpContext.TraceIdentifier;
remoteServiceErrorInfo.Message = SimplifyMessage(context.Exception);
var result = new WrapResult<object>();
result.SetFail(remoteServiceErrorInfo.Message);
// HttpResponse
context.Result = new ObjectResult(result);
// 写日志
var logLevel = context.Exception.GetLogLevel();
var remoteServiceErrorInfoBuilder = new StringBuilder();
remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------");
remoteServiceErrorInfoBuilder.AppendLine(_jsonSerializer.Serialize(remoteServiceErrorInfo, indented: true));
Logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
Logger.LogException(context.Exception, logLevel);
await context.HttpContext
.RequestServices
.GetRequiredService<IExceptionNotifier>()
.NotifyAsync(
new ExceptionNotificationContext(context.Exception)
);
context.Exception = null; //Handled!
}
private string SimplifyMessage(Exception error)
{
string message = string.Empty;
switch (error)
{
case AbpAuthorizationException e:
return message = "Authenticate failure!";
case AbpValidationException e:
return message = "Request param validate failure!";
case EntityNotFoundException e:
return message = "not found the entity!";
case BusinessException e:
return message = $"{e.Message}";
case NotImplementedException e:
return message = "not implement!";
default:
return message = "server internal error!";
}
}
}
}

5
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/SharedHostingMicroserviceModule.cs

@ -1,6 +1,7 @@
using System;
using System.Linq;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@ -55,6 +56,10 @@ namespace Lion.AbpPro
{
options.SendExceptionsDetailsToClients = SendExceptionsDetails;
});
context.Services.AddMvc(options =>
{
options.Filters.Add(typeof(ResultExceptionFilter));
});
}
/// <summary>

6
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/System/WrapResultAttribute.cs

@ -0,0 +1,6 @@
namespace System
{
public class WrapResultAttribute : Attribute
{
}
}
Loading…
Cancel
Save