c# - iconfiguration - net core configuration options




Ermitteln Sie, wann ungültige JSON-Schlüssel/Wert-Paare in einer.NET MVC-Anforderung gesendet werden (2)

Ich habe einen Client mit einer MVC-Anwendung, die rohe JSON-Anforderungen akzeptiert. Der ModelBinder ordnet eingehende Schlüssel / Wert-Paare den Eigenschaften des Controller-Modells zu, kein Problem.

Das Problem ist, dass sie einen Fehler ausgeben wollen, wenn sie ein ungültiges Schlüssel / Wert-Paar senden, und für das Leben von mir kann ich die rohen eingehenden Daten nicht finden.

Wenn ich beispielsweise ein Modell mit einer String-Eigenschaft MName aber in ihrer JSON-Anfrage "MiddleName":"M" sende, wird der ModelBinder diesen ungültigen Schlüssel werfen und die MName Eigenschaft leer lassen. Das wirft keinen Fehler und ModelState.IsValid gibt true .

Ich weiß, dass ich ein [Required] -Attribut für die Eigenschaft [Required] könnte, aber das ist auch nicht richtig, da für diese Eigenschaft möglicherweise Nullwerte vorhanden sind und immer noch nicht das Problem der Erkennung von Schlüssel / Wert-Paaren auftritt. t gehören.

Dies ist keine Frage der Überbuchung; Ich versuche nicht zu verhindern, dass ein eingehender Wert an das Modell gebunden wird. Ich versuche zu erkennen, wenn ein eingehender Wert im Modell nichts zugeordnet wurde.

Da die Werte als application / json in den Anfragetext eingehen, habe ich nicht einmal Glück, die rohen Anfragedaten aufzurufen, mitzählen oder aufzählen zu lassen. Ich kann Name / Wert-Paare von ModelState.Keys aber das schließt nur die Felder ein, die erfolgreich zugeordnet wurden. Keiner dieser Schlüssel befindet sich in der Sammlung Request[] .

Und ja, das ist in ASP.NET MVC 5, nicht WebApi. Behandelt WebAPI dies anders?

Irgendwelche Ideen?

Beispiel:

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

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

naja du kannst sowas ausprobieren wie

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

Sie können JSON-Daten lesen, die in der Anforderung vom Request.InputStream gesendet und an ein Objekt deserialisiert wurden. Sie können dann die Property-Namen, die gebucht wurden, mit den Eigenschaftsnamen Ihres Modells vergleichen

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

Wenn invalidProperties Werte enthält, können Sie den Fehler String.Join() (und möglicherweise String.Join() , um die Liste der Namen der ungültigen Eigenschaften und die Liste der tatsächlichen Modelleigenschaftsnamen in die Fehlernachricht aufzunehmen, die an den Client zurückgegeben wird).