2017-10-16 3 views
0

Ich poste diese Frage nach dem Lesen der verfügbaren Beiträge. Ich habe einen ASP.NET-Web-API-Controller mit folgenden Methoden.JSON String Deserialisierung zu benutzerdefinierten Objekt

[DataContract] 
public class CustomPerson 
{ 
    [DataMember] 
    public ulong LongId { get; set; } 
} 

[DataContract] 
public class Employee : CustomPerson 
{ 
    [DataMember] 
    public string Name { get; set; } 

    [DataMember] 
    public string Address { get; set; } 
} 

dann in der Steuerung

public class CustomController : ApiController 
{ 
    [HttpPost] 
    [ActionName("AddEmployee")] 
    public bool AddEmployee(Employee empInfo) 
    { 
     bool bIsSuccess = false; 

     // Code loginc here 
     bIsSuccess = true; 

     return bIsSuccess; 
    } 

    [HttpPost] 
    [ActionName("AddEmployeeCustom")] 
    public async Task<bool> AddEmployeeCustom() 
    { 
     string rawRequest = await Request.Content.ReadAsStringAsync(); 
     bool bIsSuccess = false; 

     // Code loginc here 

     try 
     { 
      Employee emp = JsonConvert.DeserializeObject<Employee>(rawRequest); 
     } 
     catch (Exception ex) 
     { } 

     return bIsSuccess; 
    } 
} 

Wenn ich die folgende Anforderung über Seife AddEmployee nennen ui das individuelle Objekt ohne Fehler also der leere Wert für LongId empfangen wird

ignoriert
{ 
    "Name": "test1", 
    "Address": "Street 1", 
    "LongId": "" 
} 

Wenn ich die AddEmployeeCustom-Methode aufruft, löst die Laufzeit die Ausnahme aus:

Error converting value "" to type 'System.UInt64'. Path 'LongId', line 4, position 14. 

Eine Option, die ich lese, ist die eingehende Zeichenfolge in JObject konvertieren und dann Objekt der Employee-Klasse erstellen, aber ich versuche zu verstehen und das Verhalten der Standard-Request-Handling-Mechanismus nachzuahmen, wenn die eingehende Anfrage automatisch vom Controller behandelt und deserialisiert wird zu Mitarbeiterobjekt

+2

Ihre Änderung Aufruf ' LongId 'zu einem' ulong? ' – Jonesopolis

+1

' LongId' erwartet eine Zahl und keine leere Zeichenkette – user12345

+1

Welcher 'long' Wert sollte' 'LongId" entsprechen: "" '? – Sinatr

Antwort

0

Das Problem ist, dass Ihr JSON nicht für Ihr Modell gültig ist.

In der ersten Methode AddEmployee passiert der Prozess namens Model Binding. MVC übernimmt die Aufgabe, Post-Inhalt in das Objekt zu konvertieren. Es scheint tolerant zu sein, Fehlpaarungen zu unterscheiden und Ihnen die leere Zeichenfolge zu vergeben.

Im zweiten Fall versuchen Sie, es selbst zu tun, und versuchen Sie einfach, Deserialisierung auszuführen, ohne Eingabedaten zu überprüfen. Newtonsoft JSON versteht keine leere Zeichenfolge und stürzt ab.

Wenn Sie noch ungültige JSON akzeptieren müssen können Sie durch die Implementierung von benutzerdefinierten Konverter Standard Deserialisierung zu überschreiben

public class NumberConverter : JsonConverter 
{ 
    public override bool CanWrite => false; 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(ulong) == objectType; 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var value = reader.Value.ToString(); 

     ulong result; 
     if (string.IsNullOrEmpty(value) || !ulong.TryParse(value, out result)) 
     { 
      return default(ulong); 
     } 

     return result; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Und dann Ihre benutzerdefinierten Konverter-Instanz angeben, wenn deserialize

return JsonConvert.DeserializeObject<Employee>(doc.ToJson(), new NumberConverter()); 
Verwandte Themen