2012-06-14 6 views
10

Zum Beispiel, wenn ich die folgenden json Texte:Unterschiede erkennen zwischen zwei JSON-Dateien in C#

object1{ 
    field1: value1; 
    field2: value2; 
    field3: value3; 
} 

object1{ 
    field1: value1; 
    field2: newvalue2; 
    field3: value3; 
} 

ich etwas in C# müssen, dass die Dateien liest und zeigt den Unterschied. h. es kann das folgende Objekt zurückgeben:

differences { 
    object1: { field: field2, old_value: value2, new_value: newvalue2} 
} 

Gibt es einige API oder Vorschläge, dies zu tun?

+0

Nicht dass ich bewusst bin. Aber wenn du einen schreibst, poste hier einen Link dazu. :) –

Antwort

4

Ich empfehle Sie Weakly-Typed JSON Serialization verwenden und eine Routine schreiben, die JsonObject wie folgt verwendet:

String JsonDifferenceReport(String objectName, 
          JsonObject first, 
          JsonObject second) 
{ 
    if(String.IsNullOrEmpty(objectName)) 
    throw new ArgumentNullException("objectName"); 
    if(null==first) 
    throw new ArgumentNullException("first"); 
    if(null==second) 
    throw new ArgumentNullException("second"); 
    List<String> allKeys = new List<String>(); 
    foreach(String key in first.Keys) 
    if (!allKeys.Any(X => X.Equals(key))) allKeys.Add(key); 
    foreach(String key in second.Keys) 
    if (!allKeys.Any(X => X.Equals(key))) allKeys.Add(key); 
    String results = String.Empty; 
    foreach(String key in allKeys) 
    { 
    JsonValue v1 = first[key]; 
    JsonValue v1 = second[key]; 
    if (((null==v1) != (null==v2)) || !v1.Equals(v2)) 
    { 
     if(String.IsNullOrEmpty(results)) 
     { 
     results = "differences: {\n"; 
     } 
     results += "\t" + objectName + ": {\n"; 
     results += "\t\tfield: " + key + ",\n"; 
     results += "\t\toldvalue: " + (null==v1)? "null" : v1.ToString() + ",\n"; 
     results += "\t\tnewvalue: " + (null==v2)? "null" : v2.ToString() + "\n"; 
     results += "\t}\n"; 
    } 
    } 
    if(!String.IsNullOrEmpty(results)) 
    { 
    results += "}\n"; 
    } 
    return results; 
} 

Ihre Wahl, ob Berichte innerhalb JsonValue v1 und v2 rekursiv zu bekommen, anstatt nur ihre String-Darstellung unter Verwendung, wie ich hier tat .

Wenn Sie wollten rekursiv gehen, könnte es die oben wie folgt ändern:

if ((null==v1) || (v1.JsonType == JsonType.JsonPrimitive) 
    || (null==v2) || (v2.JsonType == JsonType.JsonPrimitive)) 
    { 
    results += "\t\tfield: " + key + ",\n"; 
    results += "\t\toldvalue: " + (null==v1) ? "null" : v1.ToString() + ",\n"; 
    results += "\t\tnewvalue: " + (null==v2) ? "null" : v2.ToString() + "\n"; 
    } 
    else 
    { 
    results + JsonDifferenceReport(key, v1, v2); 
    } 

-Jesse

1

Aus irgendeinem Grund habe ich nicht in der Lage war JsonObject in meinem Web-API-Projekt zu verwenden. Ich benutzte JSON.Net und unten ist meine Methode, um diff zu bekommen. Es wird Array von Unterschieden geben.

private static string GetJsonDiff(string action, string existing, string modified, string objectType) 
    { 
     // convert JSON to object 
     JObject xptJson = JObject.Parse(modified); 
     JObject actualJson = JObject.Parse(existing); 

     // read properties 
     var xptProps = xptJson.Properties().ToList(); 
     var actProps = actualJson.Properties().ToList(); 

     // find differing properties 
     var auditLog = (from existingProp in actProps 
      from modifiedProp in xptProps 
      where modifiedProp.Path.Equals(existingProp.Path) 
      where !modifiedProp.Value.Equals(existingProp.Value) 
      select new AuditLog 
      { 
       Field = existingProp.Path, 
       OldValue = existingProp.Value.ToString(), 
       NewValue = modifiedProp.Value.ToString(), 
       Action = action, ActionBy = GetUserName(), 
       ActionDate = DateTime.UtcNow.ToLongDateString(), 
       ObjectType = objectType 
      }).ToList(); 

     return JsonConvert.SerializeObject(auditLog); 
    } 
Verwandte Themen