- ABP Framework version: v3.3.2
- UI type: Angular
- DB provider: EF Core
- Tiered (MVC) or Identity Server Separated (Angular): yes
- Exception message and stack trace:
- Steps to reproduce the issue:
I want to remove/disable the [Required] attribute for "Password" field in IdentityUserCreateDto
It seems could not achieve it so I disabled the validation by putting [DisableValidation] in the CreateAsync method, but it does not work:
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IdentityUserController))]
public class CustomIdentityUserController : IdentityUserController
{
public CustomIdentityUserController(IIdentityUserAppService userAppService) : base(userAppService)
{
}
[DisableValidation]
public override Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input)
{
return UserAppService.CreateAsync(input);
}
}
Any advice woule be appreciated much, thank you.
9 Answer(s)
-
0
When you put a breakpoint in CreateAsync method, do you see it comes inside the method? I want to ensure that you successfully overrided the method.
you may also use Fleunt Validation https://docs.abp.io/en/abp/latest/FluentValidation
-
0
Hi @alper, yes, it hits the breakpoint inside the method.
Regarding fluent validation, can give me some insights how to by pass the [Required] data annotation validation? As I know, it still triggers the data annotation validation before hit the FluentValidation.
Thanks for your support.
-
0
I think you disable the validation on the controller but in the controller method also calls the application service method. application service methods are also being validated automatically. so you need to replace the UserAppService and add
[DisableValidation]
attribute to theUserAppService
CreateAsync
method. -
0
Hi @alper, I tried to put [DisableValidation] to CreateAsync in both Controller and AppService, it still does not work.
if the Password field has value, it hits the method -> the override is succesfully
if the Password is null/empty, the validation is triggered -> the [DisableValidation] is not working
[Dependency(ReplaceServices = true)] [ExposeServices(typeof(IdentityUserController))] public class CustomIdentityUserController : IdentityUserController { public CustomIdentityUserController(IIdentityUserAppService userAppService) : base(userAppService) { } [DisableValidation] public override Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input) { return UserAppService.CreateAsync(input); } }
[Dependency(ReplaceServices = true)] [ExposeServices(typeof(IdentityUserAppService))] public class CustomIdentityUserAppService : IdentityUserAppService { public CustomIdentityUserAppService( IdentityUserManager userManager, IIdentityUserRepository userRepository, IIdentityRoleRepository roleRepository, IOrganizationUnitRepository organizationUnitRepository, IIdentityClaimTypeRepository identityClaimTypeRepository, IdentityTwoFactorManager identityTwoFactorManager ) : base(userManager, userRepository, roleRepository, organizationUnitRepository, identityClaimTypeRepository, identityTwoFactorManager) { } [DisableValidation] public override async Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input) { var user = new IdentityUser( GuidGenerator.Create(), input.UserName, input.Email, CurrentTenant.Id ); input.MapExtraPropertiesTo(user); (await UserManager.CreateAsync(user)).CheckErrors(); await UpdateUserByInput(user, input); await CurrentUnitOfWork.SaveChangesAsync(); var userDto = ObjectMapper.Map<IdentityUser, IdentityUserDto>(user); return userDto; } }
-
0
ok. so there might be a problem. created a issue. you can track this https://github.com/abpframework/abp/issues/9082
-
0
Solution before upgrade:
Use
MyAbpValidationActionFilter
to replace the build-inAbpValidationActionFilter
.using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.Validation; using Volo.Abp.DependencyInjection; using Volo.Abp.Reflection; using Volo.Abp.Validation; namespace MyCompanyName.MyProjectName.Web { public class MyAbpValidationActionFilter : IAsyncActionFilter, ITransientDependency { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (!context.ActionDescriptor.IsControllerAction() || !context.ActionDescriptor.HasObjectResult()) { await next(); return; } if (ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableValidationAttribute>(context.ActionDescriptor.GetMethodInfo()) != null) { await next(); return; } if (ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableValidationAttribute>(context.Controller.GetType()) != null) { await next(); return; } if (context.ActionDescriptor.GetMethodInfo().DeclaringType != context.Controller.GetType()) { var baseMethod = context.ActionDescriptor.GetMethodInfo(); var overrideMethod = context.Controller.GetType().GetMethods().FirstOrDefault(x => x.DeclaringType == context.Controller.GetType() && x.Name == baseMethod.Name && x.ReturnType == baseMethod.ReturnType && x.GetParameters().Select(p => p.ToString()).SequenceEqual(baseMethod.GetParameters().Select(p => p.ToString()))); if (overrideMethod != null) { if (ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableValidationAttribute>(overrideMethod) != null) { await next(); return; } } } context.HttpContext.RequestServices.GetRequiredService<IModelStateValidator>().Validate(context.ModelState); await next(); } } }
public override void ConfigureServices(ServiceConfigurationContext context) { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); PostConfigure<MvcOptions>(mvcOptions => { mvcOptions.Filters.ReplaceOne( x => (x as ServiceFilterAttribute)?.ServiceType == typeof(AbpValidationActionFilter), new ServiceFilterAttribute(typeof(MyAbpValidationActionFilter))); }); }
-
0
Hi @maliming, thanks for your prompt reply.
I just tried, the [DisableValidation] works in controller method but not in AppService method, the validation is still triggered.
-
0
HI
Can you try to add
typeof(IIdentityUserAppService)
toExposeServices
attribute?[Dependency(ReplaceServices = true)] [ExposeServices(typeof(IdentityUserAppService), typeof(IIdentityUserAppService))] public class CustomIdentityUserAppService : IdentityUserAppService
-
0
Hi @maliming, yup, it works now.
Thanks for your support!!!