2

I have the following endpoint in my controller, and I would like to create a custom validation for attribute passed from query.

[ApiController]
public class SampleController : ControllerBase
{
    [HttpGet]
    [Route("api/user")]
    public IActionResult GetUsersByLevel(
        [BindRequired, ValidLevelFromQuery(Name = "level")] string level)
    {
        ...
    }
}

My desired outcome is that I create a custom FromQuery attribute, which in this sample I describe as ValidLevelFromQuery. The custom attribute would check the value of level and would only accept "A", "B", and "C", on any other value, the response to the client will be a BadRequest.

Currently I am doing the validation after I have read the value in the action. My goal is have this check earlier in the request pipeline.

I would like to avoid using IValidatableObject if possible.

3
  • You can create a custom attribute and have your logic there, and then add the attribute to your parameter, like BindRequired. Commented May 2, 2020 at 0:23
  • stackoverflow.com/questions/52977418/… might be helpful Commented May 2, 2020 at 0:26
  • Thanks, managed to draw a solution based on your suggestions. Commented May 11, 2020 at 17:48

1 Answer 1

4

You can use ActionFilter to achieve this.

Please refer to the following code:

        [HttpGet]
        [Route("api/user")]
        [ValidLevelFromQuery]
        public IActionResult GetUsersByLevel(
           [BindRequired] string level)
        {
            return Ok();
        }

ValidLevelFromQuery method:

public class ValidLevelFromQueryAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// Validates Level automaticaly
        /// </summary>
        /// <param name="context"></param>
        /// <inheritdoc />
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (context.ActionArguments.ContainsKey("level"))
            {
                string[] allowedGroup = new string[] { "A", "B", "C" };
                if (!allowedGroup.Contains(context.ActionArguments["level"]))
                {
                    context.Result = new BadRequestObjectResult("The level is not allowed");
                }
            }
        }

Here is the test result:

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Found a solution based on Aspram's comments, which is exactly what you have answered. Thanks for taking the time to answer and will accept your answer so others can see it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.