根据查询字符串

时间:2018-12-04 20:17:36

标签: asp.net-core

问题:我们正在从旧系统升级,因此解决方案受到限制。如果存在特定的查询字符串,我试图路由到未经授权的控制器。如果不存在,则将用户路由到授权控制器。这是在ASP.Net Core 2.1上。

是否可以将控制器设置为基于查询字符串进行路由?我尝试过

[/ home / [action]?query = {query}]->由于“?”而导致运行时错误

[/ home / [action] / {query}]->映射到/ home / index / 1(不是我所需要的)

感谢您的帮助!

编辑:或者,是否可以有一个独立于查询参数的控制器动作?

公共Iactionresult Index(){}

公共Iactionresult索引([FromQuery]字符串查询){}

路由似乎无法区分这两者。

1 个答案:

答案 0 :(得分:1)

您可以使用IActionConstraintIParameterModelConvention接口。简而言之,创建这样的IActionConstraint:

public class RequiredFromQueryActionConstraint : IActionConstraint
{
    private readonly string _parameter;

    public RequiredFromQueryActionConstraint(string parameter)
    {
        _parameter = parameter;
    }

    public int Order => 999;

    public bool Accept(ActionConstraintContext context)
    {
        if (!context.RouteContext.HttpContext.Request.Query.ContainsKey(_parameter))
        {
            return false;
        }

        return true;
    }
}

如果在请求的查询字符串中找不到匹配的参数,则它将从Accept方法返回false。

比这样创建RequiredFromQueryAttribute类:

public class RequiredFromQueryAttribute : FromQueryAttribute, IParameterModelConvention
{
    public void Apply(ParameterModel parameter)
    {
        if (parameter.Action.Selectors != null && parameter.Action.Selectors.Any())
        {
            parameter.Action.Selectors.Last().ActionConstraints.Add(new RequiredFromQueryActionConstraint(parameter.BindingInfo?.BinderModelName ?? parameter.ParameterName));
        }
    }
}

比您可以用以下属性修饰必需的查询字符串参数:

[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("{id}")]
    public string Get(int id, [RequiredFromQuery]string foo, [RequiredFromQuery]string bar)
    {
        return id + " " + foo + " " + bar;
    }
}

从现在开始,只有以下URL GET api/values/5?foo=a&bar=b会进入上述操作,所有其他参数组合将导致状态为404的响应,您最终可以将其替换为所需的状态

您可以在此链接https://www.strathweb.com/2016/09/required-query-string-parameters-in-asp-net-core-mvc/

中找到更多信息。