mirror of https://github.com/abpframework/abp.git
committed by
GitHub
33 changed files with 313 additions and 42 deletions
@ -0,0 +1,31 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.AspNetCore.Mvc.Abstractions; |
||||
|
using Microsoft.AspNetCore.Mvc.Controllers; |
||||
|
using Volo.Abp.AspNetCore.Filters; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.ApplicationModels; |
||||
|
|
||||
|
public class AbpMvcActionDescriptorProvider : IActionDescriptorProvider |
||||
|
{ |
||||
|
public virtual int Order => -1000 + 10; |
||||
|
|
||||
|
public virtual void OnProvidersExecuting(ActionDescriptorProviderContext context) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public virtual void OnProvidersExecuted(ActionDescriptorProviderContext context) |
||||
|
{ |
||||
|
foreach (var action in context.Results.Where(x => x is ControllerActionDescriptor).Cast<ControllerActionDescriptor>()) |
||||
|
{ |
||||
|
var disableAbpFeaturesAttribute = action.ControllerTypeInfo.GetCustomAttribute<DisableAbpFeaturesAttribute>(true); |
||||
|
if (disableAbpFeaturesAttribute != null && disableAbpFeaturesAttribute.DisableMvcFilters) |
||||
|
{ |
||||
|
action.FilterDescriptors.RemoveAll(x => x.Filter is ServiceFilterAttribute serviceFilterAttribute && |
||||
|
typeof(IAbpFilter).IsAssignableFrom(serviceFilterAttribute.ServiceType)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,6 @@ |
|||||
|
namespace Volo.Abp.AspNetCore.Filters; |
||||
|
|
||||
|
public interface IAbpFilter |
||||
|
{ |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
using System.Reflection; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.AspNetCore.Mvc.Controllers; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Middleware; |
||||
|
|
||||
|
public abstract class AbpMiddlewareBase : IMiddleware |
||||
|
{ |
||||
|
protected Task<bool> ShouldSkipAsync(HttpContext context, RequestDelegate next) |
||||
|
{ |
||||
|
var endpoint = context.GetEndpoint(); |
||||
|
var controllerActionDescriptor = endpoint?.Metadata.GetMetadata<ControllerActionDescriptor>(); |
||||
|
var disableAbpFeaturesAttribute = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttribute<DisableAbpFeaturesAttribute>(); |
||||
|
return Task.FromResult(disableAbpFeaturesAttribute != null && disableAbpFeaturesAttribute.DisableMiddleware); |
||||
|
} |
||||
|
|
||||
|
public abstract Task InvokeAsync(HttpContext context, RequestDelegate next); |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp; |
||||
|
|
||||
|
[AttributeUsage(AttributeTargets.Class)] |
||||
|
public class DisableAbpFeaturesAttribute : Attribute |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The framework will not register any interceptors for the class.
|
||||
|
/// This will cause the all features that depend on interceptors to not work.
|
||||
|
/// </summary>
|
||||
|
public bool DisableInterceptors { get; set; } = true; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The framework middleware will skip the class.
|
||||
|
/// This will cause the all features that depend on middleware to not work.
|
||||
|
/// </summary>
|
||||
|
public bool DisableMiddleware { get; set; } = true; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The framework will not remove all built-in filters for the class.
|
||||
|
/// This will cause the all features that depend on filters to not work.
|
||||
|
/// </summary>
|
||||
|
public bool DisableMvcFilters { get; set; } = true; |
||||
|
} |
||||
@ -0,0 +1,74 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.AspNetCore.Mvc.Controllers; |
||||
|
using Microsoft.AspNetCore.Mvc.Filters; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Auditing; |
||||
|
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Features; |
||||
|
using Volo.Abp.AspNetCore.Mvc.GlobalFeatures; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Response; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Uow; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Validation; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.Filters; |
||||
|
|
||||
|
[Route("api/enabled-features-test")] |
||||
|
public class EnabledAbpFeaturesController : AbpController, IRemoteService |
||||
|
{ |
||||
|
[HttpGet] |
||||
|
public Task<List<string>> GetAsync() |
||||
|
{ |
||||
|
var filters = HttpContext.GetEndpoint().Metadata.GetMetadata<ControllerActionDescriptor>() |
||||
|
.FilterDescriptors.Where(x => x.Filter is ServiceFilterAttribute) |
||||
|
.Select(x => x.Filter.As<ServiceFilterAttribute>().ServiceType.FullName).ToList(); |
||||
|
|
||||
|
return Task.FromResult(filters); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Route("api/disabled-features-test")] |
||||
|
[DisableAbpFeatures] |
||||
|
public class DisabledAbpFeaturesController : AbpController, IRemoteService |
||||
|
{ |
||||
|
[HttpGet] |
||||
|
public Task<List<string>> GetAsync() |
||||
|
{ |
||||
|
var filters = HttpContext.GetEndpoint().Metadata.GetMetadata<ControllerActionDescriptor>() |
||||
|
.FilterDescriptors.Where(x => x.Filter is ServiceFilterAttribute) |
||||
|
.Select(x => x.Filter.As<ServiceFilterAttribute>().ServiceType.FullName).ToList(); |
||||
|
|
||||
|
return Task.FromResult(filters); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class MvcDisableAbpFeaturesAttribute_Tests : AspNetCoreMvcTestBase |
||||
|
{ |
||||
|
[Fact] |
||||
|
public async Task Should_Disable_MVC_Filters() |
||||
|
{ |
||||
|
var filters = await GetResponseAsObjectAsync<List<string>>("/api/enabled-features-test"); |
||||
|
filters.ShouldContain(typeof(GlobalFeatureActionFilter).FullName); |
||||
|
filters.ShouldContain(typeof(AbpAuditActionFilter).FullName); |
||||
|
filters.ShouldContain(typeof(AbpNoContentActionFilter).FullName); |
||||
|
filters.ShouldContain(typeof(AbpFeatureActionFilter).FullName); |
||||
|
filters.ShouldContain(typeof(AbpValidationActionFilter).FullName); |
||||
|
filters.ShouldContain(typeof(AbpUowActionFilter).FullName); |
||||
|
filters.ShouldContain(typeof(AbpExceptionFilter).FullName); |
||||
|
|
||||
|
filters = await GetResponseAsObjectAsync<List<string>>("/api/disabled-features-test"); |
||||
|
filters.ShouldNotContain(typeof(GlobalFeatureActionFilter).FullName); |
||||
|
filters.ShouldNotContain(typeof(AbpAuditActionFilter).FullName); |
||||
|
filters.ShouldNotContain(typeof(AbpNoContentActionFilter).FullName); |
||||
|
filters.ShouldNotContain(typeof(AbpFeatureActionFilter).FullName); |
||||
|
filters.ShouldNotContain(typeof(AbpValidationActionFilter).FullName); |
||||
|
filters.ShouldNotContain(typeof(AbpUowActionFilter).FullName); |
||||
|
filters.ShouldNotContain(typeof(AbpExceptionFilter).FullName); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.DynamicProxy; |
||||
|
|
||||
|
public class AlwaysExceptionAsyncInterceptor : AbpInterceptor |
||||
|
{ |
||||
|
public override Task InterceptAsync(IAbpMethodInvocation invocation) |
||||
|
{ |
||||
|
throw new AbpException("This interceptor should not be executed!"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.TestBase.Logging; |
||||
|
|
||||
|
namespace Volo.Abp.DynamicProxy; |
||||
|
|
||||
|
[DisableAbpFeatures] |
||||
|
public class DisableInterceptionTargetClass : ICanLogOnObject |
||||
|
{ |
||||
|
public List<string> Logs { get; } = new List<string>(); |
||||
|
|
||||
|
public virtual void DoIt() |
||||
|
{ |
||||
|
Logs.Add("ExecutingDoIt"); |
||||
|
} |
||||
|
|
||||
|
public virtual int GetValue() |
||||
|
{ |
||||
|
Logs.Add("ExecutingGetValue"); |
||||
|
return 42; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<int> GetValueAsync() |
||||
|
{ |
||||
|
Logs.Add("EnterGetValueAsync"); |
||||
|
await Task.Delay(5); |
||||
|
Logs.Add("MiddleGetValueAsync"); |
||||
|
await Task.Delay(5); |
||||
|
Logs.Add("ExitGetValueAsync"); |
||||
|
return 42; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task DoItAsync() |
||||
|
{ |
||||
|
Logs.Add("EnterDoItAsync"); |
||||
|
await Task.Delay(5); |
||||
|
Logs.Add("MiddleDoItAsync"); |
||||
|
await Task.Delay(5); |
||||
|
Logs.Add("ExitDoItAsync"); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue