假设你在MVC控制器中有一个简单的方法......
HTTP GET http://my-server/api/12321312?includeNonActive=thisIsNotABooleanValue
如果将无效值(非布尔值)传递给Boolean.TryParse()
查询字符串参数,有没有办法让MVC自动返回HTTP 400?
return BadRequest("wtf")
当然,我可以接受'includeNonActive'的字符串类型,使用bind 127.0.0.1 192.168.20.37
port 6379
dir .
和bind 127.0.0.1 192.168.20.140
port 16379
sentinel monitor redis-cluster 192.168.20.37 6379 2
,但这在Swagger中看起来很难看。
答案 0 :(得分:1)
如果将无效值(非布尔值)传递给'includeNonActive'查询字符串参数,有没有办法让MVC自动返回HTTP 400?
当然,您可以为此构建一个动作过滤器。
notification
然后使用过滤器:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class EnsureBooleanQueryParameterAttribute : ActionFilterAttribute
{
public EnsureBooleanQueryParameterAttribute(string parameterName)
{
if (string.IsNullOrEmpty(parameterName))
throw new ArgumentException($"'{nameof(parameterName)}' is required.");
this.ParameterName = parameterName;
}
public string ParameterName { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var attribute = (EnsureBooleanQueryParameterAttribute)filterContext.ActionDescriptor
.GetCustomAttributes(typeof(EnsureBooleanQueryParameterAttribute), true)
.FirstOrDefault();
// The attribute exists on the current action method
if (attribute != null)
{
string param = filterContext.HttpContext.Request.QueryString[attribute.ParameterName];
bool result;
// If the query string value is present and not boolean
if (!string.IsNullOrEmpty(param) && !bool.TryParse(param, out result))
{
filterContext.Result = new HttpStatusCodeResult(400,
"Invalid boolean query string value for '{attribute.ParameterName}'.");
}
}
}
}
您可以将此作为起点,添加可用于指定数据类型的[Route("{id}", Name = "GetById")]
[HttpGet]
[ProducesResponseType(typeof(SomeType), (int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(string), (int)HttpStatusCode.Unauthorized)]
[ProducesResponseType(typeof(string), (int)HttpStatusCode.Forbidden)]
[ProducesResponseType(typeof(string), (int)HttpStatusCode.BadRequest)]
[ProducesResponseType(typeof(string), (int)HttpStatusCode.ServiceUnavailable)]
[EnsureBooleanQueryParameter("includeNonActive")]
public async Task<IActionResult> Get(string id, bool? includeNonActive = false)
{
// some stuff
}
参数和Enum
参数,以指示该值是否必须存在于URL。
答案 1 :(得分:0)
我没有说明我使用的是MVC Core,因此我必须更改一些内容才能让它适合我。这是我的版本。
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class BooleanQueryStringParameterTypeValidatorAttribute : ActionFilterAttribute
{
public BooleanQueryStringParameterTypeValidatorAttribute(string parameterName)
{
if(string.IsNullOrWhiteSpace(parameterName))
throw new ArgumentException($"'{nameof(parameterName)}' is required.");
this.ParameterName = parameterName;
}
protected string ParameterName { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if(!filterContext.HttpContext.Request.QueryString.HasValue)
return;
ControllerActionDescriptor actionDescriptor = filterContext.ActionDescriptor as ControllerActionDescriptor;
var attribute = actionDescriptor.MethodInfo.GetCustomAttributes(typeof(BooleanQueryStringParameterTypeValidatorAttribute), true).FirstOrDefault() as BooleanQueryStringParameterTypeValidatorAttribute;
// The attribute exists on the current action method
if(attribute != null)
{
Dictionary<string, StringValues> queryString = QueryHelpers.ParseNullableQuery(filterContext.HttpContext.Request.QueryString.Value);
if(queryString != null && queryString.ContainsKey(attribute.ParameterName))
{
bool result;
// If the query string value is present and not boolean
if(!string.IsNullOrEmpty(queryString[attribute.ParameterName]) && !bool.TryParse(queryString[attribute.ParameterName], out result))
{
filterContext.Result = new BadRequestObjectResult($"Invalid boolean query string value for '{attribute.ParameterName}'.");
}
}
}
}
}