我有一个简单的 Web API,它使用验证属性执行一些基本验证。如果请求不满足验证要求,我会从中提取错误消息ModelStateDictionary
并将其作为字典返回给调用者,其中键是出现错误的属性的路径,消息指示问题所在。
问题是,给定某些输入,错误消息ModelStateDictionary
通常包含我不想返回给客户端的信息(例如转换器尝试将 JSON 映射到的对象的全名(包括命名空间)) .
是否可以区分验证错误(由 Validation Attributes / IValidatableObject 实现生成)和尝试将无效 JSON 映射到某个对象而生成的错误?
例如:
我的模型
public class Order
{
[Required]
public Customer Customer { get; set; }
}
public class Customer
{
[Required]
public string Name { get; set; }
}
我的操作方法
public IActionResult Post(Order order)
{
if (!ModelState.IsValid)
{
var errors = GetErrors(ModelState);
return BadRequest(errors);
}
return Ok();
}
private Dictionary<string, string> GetErrors(ModelStateDictionary modelState)
{
var errors = new Dictionary<string, string>();
foreach (var error in modelState)
{
string message = null;
if (error.Value.Errors.Any(e => e.Exception != null))
{
message = "Unable to interpret JSON value.";
}
else
{
message = string.Join(". ", string.Join(". ", error.Value.Errors.Select(e => e.ErrorMessage)));
}
errors.Add(error.Key, message);
}
return errors;
}
我的示例输入:
- 缺少所需数据
{
"Customer": {
"Name": null // name is required
}
}
因为Customer.Name
用 装饰RequiredAttribute
,这会生成以下错误消息:
{
"Customer.Name": "The Name field is required."
}
这可以返回给调用者,所以这里没有问题。
- JSON 值不映射到 .Net 对象类型
{
"Customer": 123 // deserializing will fail to map this value to a Customer object
}
由于将值反序列化为123
对象Customer
失败,因此会生成以下错误消息:
{
"Customer": "Error converting value 123 to type 'MyProject.Models.Customer'. Path 'Customer', line 2, position 19."
}
这不能返回给调用者,因为它包含映射到的对象的完整命名空间路径。在这种情况下,应该使用通用的东西(例如"Bad JSON value.")作为错误消息。
谁能帮我找到隐藏这些错误消息的解决方案,这些错误消息包含不应返回给调用者的信息?
从上面的代码中可以看出,我认为我可以检查ModelEntry.Exception
属性并使用它来确定是否需要对调用者屏蔽错误消息,但在我的两个示例中都是 null。
解决方案可能是检查错误消息是否以 开头Error converting value
,如果是,则屏蔽来自调用者的消息。这似乎不是很健壮,我不确定这在现实世界的例子中有多可靠。