liddiard / google-diff-match-patch

Automatically exported from code.google.com/p/google-diff-match-patch
Apache License 2.0
4 stars 1 forks source link

JS to C# deserialization is inconsistant #83

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
So I have this code....

    internal class Program {
        private static void Main(string[] args) {
        // Thisis the string produced by the JS implementation
            var json =
                "[{\"diffs\":[[0,\"Welcome to Orchard!\"],[1,\"kk\"],[0,\"Welcome to Orchard!\"]],\"start1\":0,\"start2\":0,\"length1\":38,\"length2\":40}]";
            var ent = JsonConvert.DeserializeObject<List<Patch>>(json);
            Console.WriteLine("working");
            Console.ReadKey();
        }
    }

    public class Patch {
        public List<Diff> diffs = new List<Diff>();
        public int start1;
        public int start2;
        public int length1;
        public int length2;
    }

    public class Diff {
        public Operation operation;
        public string text;
    }

    public enum Operation {
        DELETE,
        INSERT,
        EQUAL
    }

The JSON string is produced by the client. I have verified that the JSON string 
is okay by doing 

$.parseJSON('[{\"diffs\":[[0,\"Welcome to Orchard!\"],[1,\"kk\"],[0,\"Welcome 
to Orchard!\"]],\"start1\":0,\"start2\":0,\"length1\":38,\"length2\":40}]')
In the browser and an object is produced.

The problem with the above code is that when deserializing this to the C# 
implementation it throws a deserialization issue

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 
'ConsoleApplication2.Diff' because the type requires a JSON object (e.g. 
{"name":"value"}) to deserialize correctly.

To fix this error either change the JSON to a JSON object (e.g. 
{"name":"value"}) or change the deserialized type to an array or a type that 
implements a collection interface (e.g. ICollection, IList) like List<T> that 
can be deserialized from a JSON array. JsonArrayAttribute can also be added to 
the type to force it to deserialize from a JSON array.

Path '[0].diffs[0]', line 1, position 12.
The problem is to do with the diff object and the way it is being represented 
in JSON...

If I build up the object locally and serialize it I get a different JSON 
string...
var diffs = new List<Diff>();
diffs.Add(new Diff { operation = Operation.DELETE, text = "Welcome to Orchard!" 
});
diffs.Add(new Diff { operation = Operation.INSERT, text = "llkjkljkljlkj" });
diffs.Add(new Diff { operation = Operation.DELETE, text = "Welcome to Orchard!" 
});
List<Patch> patches = new List<Patch>() {new Patch{start1 = 0, start2 = 0, 
length1 = 38, length2 = 51, diffs = diffs}};
var stringOut = JsonConvert.SerializeObject(patches);
var ent = JsonConvert.DeserializeObject<List<Patch>>(stringOut);

            /*
             [{"diffs":[
             * {"operation":0,"text":"Welcome to Orchard!"},
             * {"operation":1,"text":"llkjkljkljlkj"},
             * {"operation":0,"text":"Welcome to Orchard!"}
             * ],
             * "start1":0,
             * "start2":0,
             * "length1":38,
             * "length2":51}]
             */

            //Console.WriteLine("working");

Original issue reported on code.google.com by jetski5...@gmail.com on 10 Feb 2013 at 11:41