Browse Source

WrapExtensions

master
wwwk 3 years ago
parent
commit
54bf28f7be
  1. 0
      Sanhe.Abp.Framework.sln
  2. 15
      modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Microsoft/AspNetCore/Cors/AbpCorsPolicyBuilderExtensions.cs
  3. 27
      modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Microsoft/AspNetCore/Mvc/ActionContextExtensions.cs
  4. 5
      modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Sanhe.Abp.AspNetCore.Mvc.Wrapper.csproj
  5. 3
      modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Sanhe/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs
  6. 101
      modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Sanhe/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionPageWrapResultFilter.cs
  7. 129
      modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Sanhe/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionWrapResultFilter.cs
  8. 45
      modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Sanhe/Abp/AspNetCore/Mvc/Wrapper/Filters/AbpWrapResultFilter.cs

0
Sanhe.Abp.Startup.sln → Sanhe.Abp.Framework.sln

15
modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Microsoft/AspNetCore/Cors/AbpCorsPolicyBuilderExtensions.cs

@ -0,0 +1,15 @@
using Microsoft.AspNetCore.Cors.Infrastructure;
using Sanhe.Abp.Wrapper;
namespace Microsoft.AspNetCore.Cors;
public static class AbpCorsPolicyBuilderExtensions
{
public static CorsPolicyBuilder WithAbpWrapExposedHeaders(this CorsPolicyBuilder corsPolicyBuilder)
{
return corsPolicyBuilder
.WithExposedHeaders(
AbpHttpWrapConsts.AbpWrapResult,
AbpHttpWrapConsts.AbpDontWrapResult);
}
}

27
modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Microsoft/AspNetCore/Mvc/ActionContextExtensions.cs

@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Controllers;
using Sanhe.Abp.Wrapper;
namespace Microsoft.AspNetCore.Mvc;
public static class ActionContextExtensions
{
public static bool CanWarpRsult(this ActionDescriptor actionDescriptor)
{
if (actionDescriptor is ControllerActionDescriptor descriptor)
{
if (descriptor.MethodInfo.IsDefined(typeof(IgnoreWrapResultAttribute), true))
{
return false;
}
if (descriptor.ControllerTypeInfo.IsDefined(typeof(IgnoreWrapResultAttribute), true))
{
return false;
}
return true;
}
return false;
}
}

5
modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Sanhe.Abp.AspNetCore.Mvc.Wrapper.csproj

@ -26,9 +26,4 @@
<ProjectReference Include="..\..\common\Sanhe.Abp.Wrapper\Sanhe.Abp.Wrapper.csproj" /> <ProjectReference Include="..\..\common\Sanhe.Abp.Wrapper\Sanhe.Abp.Wrapper.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Microsoft\AspNetCore\Cors\" />
<Folder Include="Microsoft\AspNetCore\Mvc\" />
</ItemGroup>
</Project> </Project>

3
modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Sanhe/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs

@ -47,11 +47,10 @@ public class AbpAspNetCoreMvcWrapperModule : AbpModule
options.IgnoreReturnTypes.Add<ApplicationApiDescriptionModel>(); options.IgnoreReturnTypes.Add<ApplicationApiDescriptionModel>();
// api/abp/application-configuration // api/abp/application-configuration
options.IgnoreReturnTypes.Add<ApplicationConfigurationDto>(); options.IgnoreReturnTypes.Add<ApplicationConfigurationDto>();
// 流 // 流内容
options.IgnoreReturnTypes.Add<IRemoteStreamContent>(); options.IgnoreReturnTypes.Add<IRemoteStreamContent>();
// Abp/ServiceProxyScript // Abp/ServiceProxyScript
options.IgnoreControllers.Add<AbpServiceProxyScriptController>(); options.IgnoreControllers.Add<AbpServiceProxyScriptController>();
// 官方模块不包装结果 // 官方模块不包装结果
options.IgnoreNamespaces.Add("Volo.Abp"); options.IgnoreNamespaces.Add("Volo.Abp");

101
modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Sanhe/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionPageWrapResultFilter.cs

@ -17,72 +17,71 @@ using Volo.Abp.ExceptionHandling;
using Volo.Abp.Http; using Volo.Abp.Http;
using Volo.Abp.Json; using Volo.Abp.Json;
namespace Sanhe.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling namespace Sanhe.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(AbpExceptionPageFilter))]
public class AbpExceptionPageWrapResultFilter : AbpExceptionPageFilter, ITransientDependency
{ {
[Dependency(ReplaceServices = true)] protected async override Task HandleAndWrapException(PageHandlerExecutedContext context)
[ExposeServices(typeof(AbpExceptionPageFilter))]
public class AbpExceptionPageWrapResultFilter : AbpExceptionPageFilter, ITransientDependency
{ {
protected async override Task HandleAndWrapException(PageHandlerExecutedContext context) var wrapResultChecker = context.GetRequiredService<IWrapResultChecker>();
if (!wrapResultChecker.WrapOnException(context))
{ {
var wrapResultChecker = context.GetRequiredService<IWrapResultChecker>(); await base.HandleAndWrapException(context);
if (!wrapResultChecker.WrapOnException(context)) return;
{ }
await base.HandleAndWrapException(context);
return;
}
var wrapOptions = context.GetRequiredService<IOptions<AbpWrapperOptions>>().Value;
var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, options =>
{
options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients;
options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients;
});
var logLevel = context.Exception.GetLogLevel(); var wrapOptions = context.GetRequiredService<IOptions<AbpWrapperOptions>>().Value;
var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, options =>
{
options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients;
options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients;
});
var remoteServiceErrorInfoBuilder = new StringBuilder(); var logLevel = context.Exception.GetLogLevel();
remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------");
remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService<IJsonSerializer>().Serialize(remoteServiceErrorInfo, indented: true));
var logger = context.GetService<ILogger<AbpExceptionPageWrapResultFilter>>(NullLogger<AbpExceptionPageWrapResultFilter>.Instance); var remoteServiceErrorInfoBuilder = new StringBuilder();
logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString()); remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------");
remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService<IJsonSerializer>().Serialize(remoteServiceErrorInfo, indented: true));
logger.LogException(context.Exception, logLevel); var logger = context.GetService<ILogger<AbpExceptionPageWrapResultFilter>>(NullLogger<AbpExceptionPageWrapResultFilter>.Instance);
logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception)); logger.LogException(context.Exception, logLevel);
await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception));
if (context.Exception is AbpAuthorizationException)
{
await context.HttpContext.RequestServices.GetRequiredService<IAbpAuthorizationExceptionHandler>()
.HandleAsync(context.Exception.As<AbpAuthorizationException>(), context.HttpContext);
}
else
{
var statusCodFinder = context.GetRequiredService<IHttpExceptionStatusCodeFinder>();
var exceptionWrapHandler = context.GetRequiredService<IExceptionWrapHandlerFactory>();
var exceptionWrapContext = new ExceptionWrapContext( if (context.Exception is AbpAuthorizationException)
context.Exception, {
remoteServiceErrorInfo, await context.HttpContext.RequestServices.GetRequiredService<IAbpAuthorizationExceptionHandler>()
context.HttpContext.RequestServices, .HandleAsync(context.Exception.As<AbpAuthorizationException>(), context.HttpContext);
statusCodFinder.GetStatusCode(context.HttpContext, context.Exception)); }
else
{
var statusCodFinder = context.GetRequiredService<IHttpExceptionStatusCodeFinder>();
var exceptionWrapHandler = context.GetRequiredService<IExceptionWrapHandlerFactory>();
exceptionWrapHandler.CreateFor(exceptionWrapContext).Wrap(exceptionWrapContext); var exceptionWrapContext = new ExceptionWrapContext(
context.Exception,
remoteServiceErrorInfo,
context.HttpContext.RequestServices,
statusCodFinder.GetStatusCode(context.HttpContext, context.Exception));
context.Result = new ObjectResult(new WrapResult( exceptionWrapHandler.CreateFor(exceptionWrapContext).Wrap(exceptionWrapContext);
exceptionWrapContext.ErrorInfo.Code,
exceptionWrapContext.ErrorInfo.Message,
exceptionWrapContext.ErrorInfo.Details));
context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true"); context.Result = new ObjectResult(new WrapResult(
context.HttpContext.Response.StatusCode = (int)wrapOptions.HttpStatusCode; exceptionWrapContext.ErrorInfo.Code,
} exceptionWrapContext.ErrorInfo.Message,
exceptionWrapContext.ErrorInfo.Details));
context.Exception = null; //Handled! context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true");
context.HttpContext.Response.StatusCode = (int)wrapOptions.HttpStatusCode;
} }
context.Exception = null; //Handled!
} }
} }

129
modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Sanhe/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionWrapResultFilter.cs

@ -17,74 +17,73 @@ using Volo.Abp.ExceptionHandling;
using Volo.Abp.Http; using Volo.Abp.Http;
using Volo.Abp.Json; using Volo.Abp.Json;
namespace Sanhe.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling namespace Sanhe.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(AbpExceptionFilter))]
public class AbpExceptionWrapResultFilter : AbpExceptionFilter, ITransientDependency
{ {
[Dependency(ReplaceServices = true)] protected async override Task HandleAndWrapException(ExceptionContext context)
[ExposeServices(typeof(AbpExceptionFilter))]
public class AbpExceptionWrapResultFilter : AbpExceptionFilter, ITransientDependency
{ {
protected async override Task HandleAndWrapException(ExceptionContext context) var wrapResultChecker = context.GetRequiredService<IWrapResultChecker>();
if (!wrapResultChecker.WrapOnException(context))
{
await base.HandleAndWrapException(context);
return;
}
//TODO: Trigger an AbpExceptionHandled event or something like that.
var wrapOptions = context.GetRequiredService<IOptions<AbpWrapperOptions>>().Value;
var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, options =>
{
options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients;
options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients;
});
var logLevel = context.Exception.GetLogLevel();
var remoteServiceErrorInfoBuilder = new StringBuilder();
remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------");
remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService<IJsonSerializer>().Serialize(remoteServiceErrorInfo, indented: true));
var logger = context.GetService<ILogger<AbpExceptionWrapResultFilter>>(NullLogger<AbpExceptionWrapResultFilter>.Instance);
logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
logger.LogException(context.Exception, logLevel);
await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception));
if (context.Exception is AbpAuthorizationException)
{
await context.GetRequiredService<IAbpAuthorizationExceptionHandler>()
.HandleAsync(context.Exception.As<AbpAuthorizationException>(), context.HttpContext);
}
else
{ {
var wrapResultChecker = context.GetRequiredService<IWrapResultChecker>(); var statusCodFinder = context.GetRequiredService<IHttpExceptionStatusCodeFinder>();
var exceptionWrapHandler = context.GetRequiredService<IExceptionWrapHandlerFactory>();
if (!wrapResultChecker.WrapOnException(context))
{ var exceptionWrapContext = new ExceptionWrapContext(
await base.HandleAndWrapException(context); context.Exception,
return; remoteServiceErrorInfo,
} context.HttpContext.RequestServices,
statusCodFinder.GetStatusCode(context.HttpContext, context.Exception));
//TODO: Trigger an AbpExceptionHandled event or something like that.
var wrapOptions = context.GetRequiredService<IOptions<AbpWrapperOptions>>().Value; exceptionWrapHandler.CreateFor(exceptionWrapContext).Wrap(exceptionWrapContext);
var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>(); context.Result = new ObjectResult(new WrapResult(
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, options => exceptionWrapContext.ErrorInfo.Code,
{ exceptionWrapContext.ErrorInfo.Message,
options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients; exceptionWrapContext.ErrorInfo.Details));
options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients;
}); context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true");
context.HttpContext.Response.StatusCode = (int)wrapOptions.HttpStatusCode;
var logLevel = context.Exception.GetLogLevel();
var remoteServiceErrorInfoBuilder = new StringBuilder();
remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------");
remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService<IJsonSerializer>().Serialize(remoteServiceErrorInfo, indented: true));
var logger = context.GetService<ILogger<AbpExceptionWrapResultFilter>>(NullLogger<AbpExceptionWrapResultFilter>.Instance);
logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
logger.LogException(context.Exception, logLevel);
await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception));
if (context.Exception is AbpAuthorizationException)
{
await context.GetRequiredService<IAbpAuthorizationExceptionHandler>()
.HandleAsync(context.Exception.As<AbpAuthorizationException>(), context.HttpContext);
}
else
{
var statusCodFinder = context.GetRequiredService<IHttpExceptionStatusCodeFinder>();
var exceptionWrapHandler = context.GetRequiredService<IExceptionWrapHandlerFactory>();
var exceptionWrapContext = new ExceptionWrapContext(
context.Exception,
remoteServiceErrorInfo,
context.HttpContext.RequestServices,
statusCodFinder.GetStatusCode(context.HttpContext, context.Exception));
exceptionWrapHandler.CreateFor(exceptionWrapContext).Wrap(exceptionWrapContext);
context.Result = new ObjectResult(new WrapResult(
exceptionWrapContext.ErrorInfo.Code,
exceptionWrapContext.ErrorInfo.Message,
exceptionWrapContext.ErrorInfo.Details));
context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true");
context.HttpContext.Response.StatusCode = (int)wrapOptions.HttpStatusCode;
}
context.Exception = null; //Handled!
} }
context.Exception = null; //Handled!
} }
} }

45
modules/mvc/Sanhe.Abp.AspNetCore.Mvc.Wrapper/Sanhe/Abp/AspNetCore/Mvc/Wrapper/Filters/AbpWrapResultFilter.cs

@ -6,36 +6,35 @@ using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Sanhe.Abp.AspNetCore.Mvc.Wrapper.Filters namespace Sanhe.Abp.AspNetCore.Mvc.Wrapper.Filters;
public class AbpWrapResultFilter : IAsyncResultFilter, ITransientDependency
{ {
public class AbpWrapResultFilter : IAsyncResultFilter, ITransientDependency public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{ {
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) if (ShouldWrapResult(context))
{ {
if (ShouldWrapResult(context)) await HandleAndWrapResult(context);
{
await HandleAndWrapResult(context);
}
await next();
} }
protected virtual bool ShouldWrapResult(ResultExecutingContext context) await next();
{ }
var wrapResultChecker = context.GetRequiredService<IWrapResultChecker>();
return wrapResultChecker.WrapOnExecution(context); protected virtual bool ShouldWrapResult(ResultExecutingContext context)
} {
var wrapResultChecker = context.GetRequiredService<IWrapResultChecker>();
protected virtual Task HandleAndWrapResult(ResultExecutingContext context) return wrapResultChecker.WrapOnExecution(context);
{ }
var options = context.GetRequiredService<IOptions<AbpWrapperOptions>>().Value;
var actionResultWrapperFactory = context.GetRequiredService<IActionResultWrapperFactory>();
actionResultWrapperFactory.CreateFor(context).Wrap(context);
context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true");
context.HttpContext.Response.StatusCode = (int)options.HttpStatusCode;
return Task.CompletedTask; protected virtual Task HandleAndWrapResult(ResultExecutingContext context)
} {
var options = context.GetRequiredService<IOptions<AbpWrapperOptions>>().Value;
var actionResultWrapperFactory = context.GetRequiredService<IActionResultWrapperFactory>();
actionResultWrapperFactory.CreateFor(context).Wrap(context);
context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true");
context.HttpContext.Response.StatusCode = (int)options.HttpStatusCode;
return Task.CompletedTask;
} }
} }

Loading…
Cancel
Save