Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
302 views
in Technique[技术] by (71.8m points)

c# - Validating and passing controller-level parameters with ASP.NET MVC attribute routing

I have an ASP.NET controller where every single method will have a shared parameter. With attribute routing, I can add this parameter in the controller's route.

However, I still need to add that parameter along with a validation attribute in every single method. Is there a way for me to do the validation in one place or avoid having to pass it in to every single method?

This is the current working code:

[ApiController]
[Route("[controller]/{name}")]
public class ExampleController : ControllerBase
{
    [HttpGet]
    public string Sample([StringLength(10)][FromRoute]string name)
    {
    }

    [HttpGet]
    [Route("defaults")]
    public string GetDefaults([StringLength(10)][FromRoute]string name)
    {
    }

    [HttpGet]
    [Route("objects/{id}")]
    public string Sample([StringLength(10)][FromRoute]string name, [FromRoute]string id)
    {
    }
}

Is it possible to get something close to this? (I know the validation parameter on the controller is invalid, but I'd like to just have to apply it once)

[ApiController]
[StringLength(10)]
[Route("[controller]/{name}")]
public class ExampleController : ControllerBase
{
    [HttpGet]
    public string Sample()
    {
    }

    [HttpGet]
    [Route("defaults")]
    public string GetDefaults()
    {
    }

    [HttpGet]
    [Route("objects/{id}")]
    public string Sample([FromRoute]string id)
    {
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can do this using a custom action filter to validate the name parameter:

public class ValidateNameParameterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.ActionParameters.ContainsKey(name))
        {
            // the trick is to get the parameter from filter context
            string name = filterContext.ActionParameters[name] as string;

            // validate name

            if (/*name is not valid*/)
            {
                // you may want to redirect user to error page when input parameter is not valid
                filterContext.Result = new RedirectResult(/*urlToRedirectForError*/);
            }

            base.OnActionExecuted(filterContext);
        }
    }
}

Now you can apply the filter to your controller, or specific actions:

[ApiController]
[Route("[controller]/{name}")]
[ValidateNameParameter] // <-- execute this for all actions in the controller
public class ExampleController : ControllerBase
{
    [HttpGet]
    public string Sample([StringLength(10)][FromRoute]string name)
    {
    }

    [HttpGet]
    [Route("defaults")]
    public string GetDefaults([StringLength(10)][FromRoute]string name)
    {
    }

    [HttpGet]
    [Route("objects/{id}")]
    // [ValidateNameParameter] // <-- execute for this specific action
    public string Sample([StringLength(10)][FromRoute]string name, [FromRoute]string id)
    {
    }
}

See this tutorial for more information.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...