5

I'm trying to write a web API that includes the newtonsoft JSON.net components.

My code is pretty straight-forward:

     public object GetJsonFile(int id = 1) {
        using (StreamReader r = new StreamReader(myJsonFile)) {
            string json;

        //    todo: build logic to only grab latest when an id is supplied
        json = r.ReadToEnd();

        object jsonObject = JsonConvert.DeserializeObject(json);
        return jsonObject;
       }

When testing the page, I get the dreaded "Type 'Newtonsoft.Json.Linq.JToken' is a recursive collection data contract which is not supported. Consider modifying the definition of collection 'Newtonsoft.Json.Linq.JToken' to remove references to itself." error.

I've done my share of digging, and everyone seems to recommend to un-check "Reuse types in all referenced assemblies", but that only seems to be used in the case of Service References, which my project does not use. I did find the place to do this, but seeing I don't have a service to reference, I cannot configure it.

I'm not that at home in Visual Studio, so please go easy on me ;)

SchmitzIT
  • 9,227
  • 9
  • 65
  • 92
  • Which line is throwing this exception? This one `JsonConvert.DeserializeObject`? Or, Was the error in client-side call? I think Json.NET's DeserializeObject can deserialize the nested object as well. Only default DataContractSerializer got the issue. – Michael Sync Feb 17 '16 at 23:31
  • Hi @MichaelSync. It doesn't even enter the code (I set breakpoints), so I don't have a line number to show. It starts compiling, and then just throws the exception. – SchmitzIT Feb 18 '16 at 10:37
  • We have to make sure that you are actually showing us the code that has problem. Are you running your WCF project from Visual Studio? Or, Do you run both client-side and WCF project together from VS? I would suggest that you run your WCF project from VS and put the breakpoint at the first line of the function and let me know if it enter the code. If it doesn't hit the first line of the code then the exception that you get is from different method. – Michael Sync Feb 19 '16 at 10:01
  • I suspect this might be the problem : http://stackoverflow.com/questions/12069176/getting-recursive-collection-data-contract-when-referencing-a-wcf-service-with. Hope that helps. – mojorisinify Feb 21 '16 at 21:18
  • @MichaelSync That's exactly what I tried prior to posting. It just threw the error without ever entering my functions. I've since reverted to properly deserializing the json into objects. Thanks for your help anyway! – SchmitzIT Feb 22 '16 at 13:33
  • @mojorisinify - I tried that link, but the solution offered there didn't help. I didn't install anything using nuget, and the answer by Nir kind of expects there to be an actual service reference, which I do not have. Thanks anyway, though. – SchmitzIT Feb 22 '16 at 13:35

2 Answers2

2

I never managed to figure out how to sidestep this. What I did end up doing was to create the entities in the JSON as classes, and let JSON.NET deserialize the JSON into that.

SchmitzIT
  • 9,227
  • 9
  • 65
  • 92
2

Use Json.Net Settings to serialize with the proper settings:

For your web.api controller InvalidDataContract exception use:

        public static void Register(HttpConfiguration config)
        {
            config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings()
            {
                Formatting = Formatting.Indented,
                TypeNameHandling = TypeNameHandling.Auto,
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                NullValueHandling = NullValueHandling.Ignore,
                ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore

        }; 

Your Json.Net default settings for JsonConvert usage:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
                {
                    Formatting = Formatting.Indented,
                    TypeNameHandling = TypeNameHandling.Auto,
                    ContractResolver = new CamelCasePropertyNamesContractResolver(),
                    NullValueHandling = NullValueHandling.Ignore,
                    ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore

            };
Greg
  • 105
  • 6