我有一个带有接受原始 JSON 请求的 MVC 应用程序的客户端。 ModelBinder 将传入的键/值对映射到 Controller 模型属性,这没问题。
问题是他们想在发送无效的键/值对时抛出错误,而我终究找不到原始传入数据。
例如,如果我有一个带有字符串属性 MName
的模型,但在他们的 JSON 请求中他们发送了 "MiddleName":"M"
,ModelBinder 将抛出这个无效 key 并将 MName
属性留空。这不会引发错误并且 ModelState.IsValid
返回 true
。
我知道我可以在属性上添加一个 [Required]
属性,但这也不对,因为该属性可能有 null 值,但仍然无法到达检测不属于的键/值对的问题。
这不是过度发布的问题;我并不是要阻止传入值绑定(bind)到模型。我正在尝试检测传入值何时未映射到模型中的任何内容。
由于请求正文中的值以 application/json 的形式出现,我什至无法访问原始请求数据,更不用说计数或枚举了。我可以从 ModelState.Keys
中提取名称/值对,但这只包括成功映射的字段。 Request[]
集合中没有这些键。
是的,这是在 ASP.NET MVC 5 中,而不是 WebApi。 WebAPI 对此有何不同的处理方式吗?
有什么想法吗?
示例:
应用程序/json: { "FName":"乔", "MName":"M", "LName":"吹"
public class PersonModel
{
public string FName { get; set; }
public string LName { get; set; }
}
public class PersonController() : Controller
{
public ActionResult Save(PersonModel person)
{
if(ModelState.IsValid) // returns true
// do things
return View(person)
}
}
最佳答案
您可以从 Request.InputStream
读取请求中发送的 json 数据并反序列化为对象。然后,您可以将发布的属性名称与模型的属性名称进行比较
public ActionResult Save(PersonModel person)
{
// Get the models property names
var modelProperties = person.GetType().GetProperties().Select(x => x.Name);
// Read the InputStream
StreamReader reader = new StreamReader(Request.InputStream);
reader.BaseStream.Position = 0;
string jsonText = reader.ReadToEnd();
// Deserialize to object and read property names
JavaScriptSerializer serializer = new JavaScriptSerializer();
object jsonObject = serializer.DeserializeObject(jsonText);
IDictionary<string, object> dictionary = jsonObject as IDictionary<string, object>;
var jsonProperties = jsonObject.Keys;
// Get the json property names which do not match the model property names
List<string> invalidProperties = jsonProperties.Except(modelProperties, StringComparer.OrdinalIgnoreCase).ToList();
如果 invalidProperties
包含值,那么您可以抛出错误(并且可能使用 String.Join()
来包含无效属性名称列表和返回给客户端的错误消息中的实际模型属性名称)。
关于c# - 确定何时在 .NET MVC 请求中发送无效的 JSON 键/值对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45364402/