사용자 지정 유효성 검사 속성에 대한 종속성 주입

올라프 스벤슨

API 컨트롤러 DTO에 사용할 사용자 지정 유효성 검사 속성을 만들었습니다. 이 속성에는 구성된 옵션의 값이 필요하기 때문에 생성자에이 값을 삽입하여 나중에 IsValidand FormatErrorMessage메서드 에서 옵션 서비스를 사용할 수 있습니다 .

internal class MyValidationAttribute : ValidationAttribute
{
    private readonly IOptionsMonitor<MyOptions> myOptionsMonitor;

    public MyValidationAttribute(IOptionsMonitor<MyOptions> myOptionsMonitor)
    {
        this.myOptionsMonitor = myOptionsMonitor;
    }

    public override bool IsValid(object value)
    {
        // ... use myOptionsMonitor here ...

        return false;
    }

    public override string FormatErrorMessage(string name)
    {
        // ... use myOptionsMonitor here ...

        return string.Empty;
    }
}

불행히도 이것을 DTO의 속성으로 사용하고 싶을 때

internal class MyDTO
{
    [MyValidationAttribute]
    public string Foo { get; set; }
}

오류 메시지가 나타납니다.

'MyValidationAttribute.MyValidationAttribute (IOptionsMonitor)'의 필수 형식 매개 변수 'myOptionsMonitor'에 해당하는 인수가 없습니다.

유효성 검사 속성에 종속성 주입을 사용할 수있는 방법이 있습니까? 나는 내가 ValidationContext그렇게 사용할 수 있다는 것을 안다.

internal class MyValidationAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            IOptionsMonitor<MyOptions> myOptionsMonitor = validationContext.GetService<IOptionsMonitor<MyOptions>>();

            // ...

            return ValidationResult.Success;
        }

        return new ValidationResult("Something failed");
    }
}

하지만 FormatErrorMessage기본 클래스 메서드 를 사용하고 싶지만 옵션 서비스에 액세스 할 수 없습니다.


내 현재 솔루션

지금은 이것이 제가 사용하고있는 코드입니다.

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
internal class CustomValidationAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        IOptionsMonitor<MyOptions> myOptionsMonitor = validationContext.GetService<IOptionsMonitor<MyOptions>>();
        Dictionary<string, string> myMap = myOptionsMonitor.CurrentValue.MyMap;
        string key = value.ToString() ?? string.Empty;

        if (myMap.ContainsKey(key))
            return ValidationResult.Success;

        string[] formattedKeys = myMap.Keys.Select(key => $"'{key}'").ToArray();
        string keysText = string.Join(" / ", formattedKeys);
        string errorMessage = $"Invalid value. Valid ones are {keysText}";

        return new ValidationResult(errorMessage);
    }
}
예고 르 안드로 소프

속성은 이러한 목적으로 설계되지 않았습니다. 하지만 대신 액션 필터를 사용할 수 있습니다.

속성을 가능한 한 간단하게 만들어 보겠습니다. 여기에는 유효성 검사 논리가 필요하지 않습니다.

[AttributeUsage(AttributeTargets.Property)]
public class CustomValidationAttribute : Attribute
{ }

예를 들어 주입 할 서비스를 만들었습니다.

public class SomeService
{
    public bool IsValid(string str)
    {
        return str == "Valid";
    }
}

그리고 우리가 검증 할 클래스

public class ClassToValidate
{
    [CustomValidation]
    public string ValidStr { get; set; } = "Valid";
    
    [CustomValidation]
    public string InvalidStr { get; set; } = "Invalid";
}

이제 마지막으로 속성의 유효성을 검사하는 작업 필터를 만들 수 있습니다. 아래 스 니펫에서는 컨트롤러 작업이 실행되기 직전에 코드를 실행하기 위해 ASP.NET Core 파이프 라인에 연결합니다. 여기서 나는 행동 인수를 얻고 CustomValidationAttribute모든 속성 을 찾으려고 노력 합니다. 존재하는 경우 속성에서 값을 가져 와서 유형으로 캐스트 (간단히 호출 .ToString())하고 서비스에 전달합니다. 서비스에서 반환 된 값에 따라 실행을 계속하거나 ModelState사전 에 오류를 추가합니다 .

public class CustomValidationActionFilter : ActionFilterAttribute
{
    private readonly SomeService someService;

    public CustomValidationActionFilter(SomeService someService)
    {
        this.someService = someService;
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var actionArguments = context.ActionArguments;

        foreach (var actionArgument in actionArguments)
        {
            var propertiesWithAttributes = actionArgument.Value
                .GetType()
                .GetProperties()
                .Where(x => x.GetCustomAttributes(true).Any(y => y.GetType() == typeof(CustomValidationAttribute)))
                .ToList();

            foreach (var property in propertiesWithAttributes)
            {
                var value = property.GetValue(actionArgument.Value).ToString();

                if (someService.IsValid(value))
                    continue;
                else
                    context.ModelState.AddModelError(property.Name, "ModelState is invalid!!!");
            }
        }

        base.OnActionExecuting(context);
    }
}

Startup.cs! 의 파이프 라인에 필터를 추가하는 것을 잊지 마십시오 .

services.AddMvc(x =>
{
    x.Filters.Add(typeof(CustomValidationActionFilter));
});

최신 정보:

속성 내에서 종속성 주입을 엄격하게 사용하려면 서비스 로케이터 안티 패턴을 사용할 수 있습니다. 이를 위해 DependencyResolver.CurrentASP.NET MVC에서 에뮬레이트해야합니다.

public class CustomValidationAttribute : ValidationAttribute
{
    private IServiceProvider serviceProvider;

    public CustomValidationAttribute()
    {
        serviceProvider = AppDependencyResolver.Current.GetService<IServiceProvider>();
    }

    public override bool IsValid(object value)
    {
        // scope is required for scoped services
        using (var scope = serviceProvider.CreateScope())
        {
            var service = scope.ServiceProvider.GetService<SomeService>();

            return base.IsValid(value);
        }
    }
}


public class AppDependencyResolver
{
    private static AppDependencyResolver _resolver;

    public static AppDependencyResolver Current
    {
        get
        {
            if (_resolver == null)
                throw new Exception("AppDependencyResolver not initialized. You should initialize it in Startup class");
            return _resolver;
        }
    }

    public static void Init(IServiceProvider services)
    {
        _resolver = new AppDependencyResolver(services);
    }

    private readonly IServiceProvider _serviceProvider;

    public object GetService(Type serviceType)
    {
        return _serviceProvider.GetService(serviceType);
    }

    public T GetService<T>()
    {
        return (T)_serviceProvider.GetService(typeof(T));
    }

    private AppDependencyResolver(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }
}

초기화되어야합니다. Startup.cs

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    AppDependencyResolver.Init(app.ApplicationServices);

    // other code
}

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

양식 입력에 대한 종속 사용자 지정 유효성 검사기를 만드시겠습니까?

분류에서Dev

Symfony 구성 요소를 사용하여 사용자 정의 유효성 검사기에 대한 종속성을 구성하는 방법은 무엇입니까?

분류에서Dev

null 속성에 대한 사용자 지정 유효성 검사 서비스

분류에서Dev

속성에 대한 유효성 검사를 통한 사용자 입력 유효성 검사

분류에서Dev

다양한 HTML5 유효성 검사 속성에 대한 사용자 지정 오류 메시지

분류에서Dev

MultipartFile에 대한 사용자 정의 제약 유효성 검사 주석

분류에서Dev

HTML Razor의 단계 속성에 대한 사용자 지정 오류 유효성 검사

분류에서Dev

Rails의 몇 가지 속성에 대한 사용자 정의 유효성 검사기

분류에서Dev

사용자 정의 필터 속성은 종속성 주입

분류에서Dev

특정 패턴 BASH에 대한 사용자 입력 유효성 검사

분류에서Dev

종속성 주입을위한 공용 속성 또는 사용자 지정 이니셜 라이저?

분류에서Dev

@Inject를 사용한 종속성 주입

분류에서Dev

사용자 지정 유효성 검사기를 사용하여 중첩 된 입력에 대한 조건부 jquery 유효성 검사

분류에서Dev

ASP.Net MVC 4 사용자 지정 ValidationAttribute 종속성 주입

분류에서Dev

Angularjs 사용자 지정 필터 및 종속성 주입

분류에서Dev

숫자 키 대신 laravel 유효성 검사를위한 사용자 지정 속성을 설정하는 방법은 무엇입니까?

분류에서Dev

"new"연산자를 사용할 위치에 대한 종속성 주입

분류에서Dev

$ .each ()를 사용한 사용자 지정 JQuery 유효성 검사

분류에서Dev

사용자 정의 sourceSet에 대한 종속성 포함

분류에서Dev

<div> 요소에 대한 사용되지 않는 속성에 대한 HTML 유효성 검사

분류에서Dev

JSR-303 사용자 지정 유효성 검사기에서 종속성을 해결하는 방법

분류에서Dev

보간을 사용하여 입력에 대한 유효성 검사 속성을 동적으로 생성

분류에서Dev

유효성 검사 레코드에 대한 사용자 지정 form_for

분류에서Dev

리소스에 대한 AngularJS 사용자 지정 유효성 검사

분류에서Dev

사용자 지정 유효성 검사 규칙에 대한 Joomla throw 오류

분류에서Dev

CameCase 모델에 대한 Laravel 사용자 지정 요청 유효성 검사

분류에서Dev

클라이언트 측 유효성 검사를 사용하는 사용자 지정 데이터 주석 유효성 검사 속성

분류에서Dev

Laravel 유효성 검사기에서 중첩 된 속성에 대한 사용자 지정 오류 메시지 사용

분류에서Dev

다른 항목에 종속 된 입력 유효성 검사

Related 관련 기사

  1. 1

    양식 입력에 대한 종속 사용자 지정 유효성 검사기를 만드시겠습니까?

  2. 2

    Symfony 구성 요소를 사용하여 사용자 정의 유효성 검사기에 대한 종속성을 구성하는 방법은 무엇입니까?

  3. 3

    null 속성에 대한 사용자 지정 유효성 검사 서비스

  4. 4

    속성에 대한 유효성 검사를 통한 사용자 입력 유효성 검사

  5. 5

    다양한 HTML5 유효성 검사 속성에 대한 사용자 지정 오류 메시지

  6. 6

    MultipartFile에 대한 사용자 정의 제약 유효성 검사 주석

  7. 7

    HTML Razor의 단계 속성에 대한 사용자 지정 오류 유효성 검사

  8. 8

    Rails의 몇 가지 속성에 대한 사용자 정의 유효성 검사기

  9. 9

    사용자 정의 필터 속성은 종속성 주입

  10. 10

    특정 패턴 BASH에 대한 사용자 입력 유효성 검사

  11. 11

    종속성 주입을위한 공용 속성 또는 사용자 지정 이니셜 라이저?

  12. 12

    @Inject를 사용한 종속성 주입

  13. 13

    사용자 지정 유효성 검사기를 사용하여 중첩 된 입력에 대한 조건부 jquery 유효성 검사

  14. 14

    ASP.Net MVC 4 사용자 지정 ValidationAttribute 종속성 주입

  15. 15

    Angularjs 사용자 지정 필터 및 종속성 주입

  16. 16

    숫자 키 대신 laravel 유효성 검사를위한 사용자 지정 속성을 설정하는 방법은 무엇입니까?

  17. 17

    "new"연산자를 사용할 위치에 대한 종속성 주입

  18. 18

    $ .each ()를 사용한 사용자 지정 JQuery 유효성 검사

  19. 19

    사용자 정의 sourceSet에 대한 종속성 포함

  20. 20

    <div> 요소에 대한 사용되지 않는 속성에 대한 HTML 유효성 검사

  21. 21

    JSR-303 사용자 지정 유효성 검사기에서 종속성을 해결하는 방법

  22. 22

    보간을 사용하여 입력에 대한 유효성 검사 속성을 동적으로 생성

  23. 23

    유효성 검사 레코드에 대한 사용자 지정 form_for

  24. 24

    리소스에 대한 AngularJS 사용자 지정 유효성 검사

  25. 25

    사용자 지정 유효성 검사 규칙에 대한 Joomla throw 오류

  26. 26

    CameCase 모델에 대한 Laravel 사용자 지정 요청 유효성 검사

  27. 27

    클라이언트 측 유효성 검사를 사용하는 사용자 지정 데이터 주석 유효성 검사 속성

  28. 28

    Laravel 유효성 검사기에서 중첩 된 속성에 대한 사용자 지정 오류 메시지 사용

  29. 29

    다른 항목에 종속 된 입력 유효성 검사

뜨겁다태그

보관