确定何时在 .NET MVC 请求中发送无效的 JSON 键/值对



我有一个客户端,其中包含一个接受原始JSON请求的MVC应用程序。 模型绑定器将传入的键/值对映射到控制器模型属性,没有问题。

问题是他们想在发送无效的键/值对时抛出错误,而我一生都找不到原始传入数据。

例如,如果我有一个具有字符串属性的模型MName但他们在 JSON 请求中发送"MiddleName":"M",ModelBinder 将抛弃这个无效键并将MName属性留空。 这不会引发错误,ModelState.IsValid返回true

我知道我可以在属性上抛出一个[Required]属性,但这也不对,因为该属性可能有空值,并且仍然无法检测到不属于的键/值对的问题。

这不是过度发布的问题;我并没有试图阻止传入值绑定到模型。我正在尝试检测传入的值何时未映射到模型中的任何内容。

由于这些值在请求正文中作为应用程序/json 进入,因此我什至没有运气访问、计数或枚举原始请求数据。 我可以从ModelState.Keys中提取名称/值对,但这仅包括成功映射的字段。这些密钥都不在Request[]集合中。

是的,这是在MVC 5 ASP.NET,而不是WebApi。WebAPI 处理这个问题有什么不同吗?

有什么想法吗?

例:

应用程序/JSON : { "FName":"乔", "MName":"M", "唰唰唰":"吹" }

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()在返回给客户端的错误消息中包含无效属性名称的列表和实际模型属性名称的列表(。

你可以尝试类似的东西

public ActionResult Save(object commingJson)
{
PersonModel person = new PersonModel();
try{
person.FName = commingJson.FName;
person.LName = commingJson.LName ;
}
catch(Exception)
{
//Binding Failed invalid json
}
int countInObject = GetAttrCount(commingJson);
int countInModel = GetAttrCount(person);
if(countInObject != countInModel )
{
//Json have more or less value then model  
}
if(ModelState.IsValid) // returns true
// do things
return View(person)
}

public int GetAttrCount(obecjct countObject) 
{
Type type = typeof(countObject);
int attributeCount = 0;
foreach(PropertyInfo property in type.GetProperties())
{
attributeCount += property.GetCustomAttributes(false).Length;
}
return attributeCount ;
}

最新更新