简体   繁体   English

使用 ASP.NET MVC 属性路由验证和传递控制器级参数

[英]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.我有一个 ASP.NET controller ,其中每个方法都有一个共享参数。 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) (我知道 controller 上的验证参数无效,但我只想应用一次)

[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)
    {
    }
}

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:现在您可以将过滤器应用于您的 controller 或特定操作:

[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.有关更多信息,请参阅本教程

As Hooman Bahreini said, you could customize a action filter that inherits ActionFilterAttribute and use it as a attribute on the controller.In Asp.net core, ActionArguments replaces ActionParameters正如 Hooman Bahreini 所说,您可以自定义一个继承ActionFilterAttribute的动作过滤器,并将其用作 controller 上的属性。在 Asp.net 核心中, ActionArguments替换了ActionParameters

public class ValidateNameParameterAttribute: ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.ActionArguments.ContainsKey("name"))
        {
            string name = filterContext.ActionArguments["name"] as string;

            if(name!=null && name.Length>10)
            {
                filterContext.Result = new BadRequestObjectResult("The length of name must not exceed 10");
            }
        }
    }
}

For more details on Filters in ASP.NET Core, you could refer to here .有关 ASP.NET 内核中滤波器的更多详细信息,您可以参考此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM