问题:我们正在从旧系统升级,因此解决方案受到限制。如果存在特定的查询字符串,我试图路由到未经授权的控制器。如果不存在,则将用户路由到授权控制器。这是在ASP.Net Core 2.1上。
是否可以将控制器设置为基于查询字符串进行路由?我尝试过
[/ home / [action]?query = {query}]->由于“?”而导致运行时错误
[/ home / [action] / {query}]->映射到/ home / index / 1(不是我所需要的)
感谢您的帮助!
编辑:或者,是否可以有一个独立于查询参数的控制器动作?
公共Iactionresult Index(){}
公共Iactionresult索引([FromQuery]字符串查询){}
路由似乎无法区分这两者。
答案 0 :(得分:1)
您可以使用IActionConstraint
和IParameterModelConvention
接口。简而言之,创建这样的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/
中找到更多信息。