c# example Déterminer quand des paires clé/valeur JSON invalides sont envoyées dans une requête.NET MVC




créer un fichier json python (2)

Eh bien, vous pouvez essayer quelque chose comme

  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 ;
}

J'ai un client avec une application MVC qui accepte les demandes JSON brutes. Le ModelBinder mappe les paires clé / valeur entrantes aux propriétés du modèle de contrôleur, sans problème.

Le problème est qu'ils veulent lancer une erreur lorsqu'ils envoient une paire clé / valeur invalide, et pour la vie de moi je ne peux pas trouver les données entrantes brutes.

Par exemple, si j'ai un modèle avec une propriété de chaîne MName mais dans leur requête JSON qu'ils envoient "MiddleName":"M" , ModelBinder lancera cette clé non valide et laissera la propriété MName vide. Cela ne ModelState.IsValid pas d'erreur et ModelState.IsValid renvoie true .

Je sais que je pourrais lancer un attribut [Required] sur la propriété, mais ce n'est pas correct non plus, car il peut y avoir des valeurs nulles pour cette propriété, et n'obtient toujours pas le problème de détection des paires clé / valeur t appartenir.

Ce n'est pas une question de sur-affichage; Je n'essaie pas d'empêcher une valeur entrante de se lier au modèle. J'essaie de détecter quand une valeur entrante ne correspond à rien dans le modèle.

Puisque les valeurs arrivent en application / json dans le corps de la requête, je n'ai même pas de chance d'accéder, de compter ou d'énumérer, les données brutes de la requête. Je peux tirer des paires nom / valeur de ModelState.Keys mais cela inclut uniquement les champs qui ont été mappés avec succès. Aucune de ces clés n'est dans la collection Request[] .

Et oui, c'est dans ASP.NET MVC 5, pas WebApi. Est-ce que WebAPI gère cela différemment?

Des idées?

Exemple:

application / json: {"FName": "Joe", "MName": "M", "LName": "Coup"}

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)
    }
}

Answer #1

Vous pouvez lire les données json qui ont été envoyées dans la requête depuis Request.InputStream et les désérialiser vers un objet. Vous pouvez ensuite comparer les noms de propriété qui ont été publiés avec les noms de propriété de votre modèle

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();

Si invalidProperties contient des valeurs, vous pouvez alors lancer votre erreur (et peut-être utiliser String.Join() pour inclure la liste des noms de propriété non valides et la liste des noms de propriétés du modèle dans le message d'erreur renvoyé au client).