【发布时间】:2019-04-22 06:44:14
【问题描述】:
如何验证和捕获 System.Web.Http.ApiController 类的集合类型转换(JSON 字符串数组到 C# 长集合)(如果可能,在模型初始化之前)?
我想验证并捕获 JSON 数组中的任何非数字元素,以作为错误的请求响应返回(可能以某种方式带有数据注释)。
当包含非数字 JSON 元素(要转换为长集合)时,它们无法解析并在模型传递给 ApiController 方法之前被剥离。鉴于以下类,有效输入应仅包含“PerferredNutTypes”和“GeographyIDs”的数值。
类
public class SquirrelController : ApiController
{
[HttpPost]
[Route("api/squirrels/search")]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(SquirrelsResponse))]
public HttpResponseMessage Squirrels(SquirrelsRequest model)
{
// model already parsed by the time breakpoint reaches here and non-convertable elements already stripped
...
...
...
SquirrelsResponse results = Targeting.SearchForSquirrels(model);
return Request.CreateResponse(HttpStatusCode.OK, results);
}
}
public class SquirrelsRequest
{
public SquirrelsRequest() {}
public List<long> PreferredNutTypes { get; set; } = new List<long>();
public GeographySearch geographySearch { get; set; } = new GeographySearch();
}
public class GeographySearch
{
public GeographySearch() {}
public BooleanOperator Operator { get; set; } = BooleanOperator.OR;
public List<long> GeographyIDs { get; set; } = new List<long>();
}
public enum BooleanOperator
{
AND,
OR
}
示例:
//"Toronto" sould be an invalid input when converting from JSON string array to c# long collection.
{
"PreferredNutTypes": [34,21],
"GeographySearch": {
"Operator": 1,
"GeographyIDs": ["Toronto"]
},
}
// This is what the model currently looks like in public HttpResponseMessage Squirrels(SquirrelsRequest model)
new SquirrelsRequest()
{
PreferredNutTypes = new List<long>() { 34, 21 },
GeographySearch = new GeographySearch()
{
Operator = 1
GeographyIDs = new List<long>()
}
}
期望:
我尝试过的事情:
System.Web.Http.Controllers.HttpActionContext actionContext.ModelState.["model.GeographySearch.GeographyIDs[0]"].Errors[0].Exception.Message => "Error converting value \"sonali7678687\" to type 'System.Int64'. Path 'subjectSearch.writingAbout[0]', line 6, position 36."
System.Web.Http.Controllers.HttpActionContext actionContext.ModelState.["model.GeographySearch.GeographyIDs[0]"].Errors[0].Exception.InnerException.Message => "Input string was not in a correct format."
...肯定有更好的验证方式吗?
更新 1: 改写问题以使解释和意图更清楚。
【问题讨论】:
-
ModelState错误告诉你想要是无效的(即在你给出的例子中,它告诉你GeographyIDs的第一个值是无效的)所以它不清楚你在期待什么或想做。 -
我认为您可以从
Request["GeographySearch.GeographyId"]获取当前值,但如果结果不为空,我将只查看ModelState.Where(m => m.Errors.Count > 0)并返回通用Response.StatusCode = 404以保持简单。跨度>
标签: c# asp.net asp.net-mvc data-annotations asp.net-apicontroller