0

I'm generating a JSON string from a class input. I don't know why but....It's generating different outputs (different projects), but with the same input (generated classes from Web Service Reference). i.e.:

1st project generates:

"{\"authToken\":{\"Token\":\"4f49f29e951d8d4f7e5b1f26aaf924771c9ed5fdfe6a23021d6720f2f5deead7==\",\"UserInfo\":{\"Email\":\"YS00982@mail.com\",\"Locked\":false,\"Phone\":null,\"UserLogin\":\"YS00982\",\"UserName\":\"YS00982 \"}},\"interactionModel\":{\"Description\":\"description\",\"Solicitor\":\"ry13578\",\"Title\":\"title\",\"Urgency\":\"3\"}}"

2nd project generates:

"{\r\n  \"authToken\": {\r\n    \"token\": \"4f49f29e951d8d4f7e5b1f26aaf924771c9ed5fdfe6a23021d6720f2f5deead7==\",\r\n    \"userInfo\": {\r\n      \"email\": \"YS00982@mail.com\",\r\n      \"locked\": false,\r\n      \"userLogin\": \"YS00982\",\r\n      \"userName\": \"YS00982 \"\r\n    }\r\n  },\r\n  \"interactionModel\": {\r\n    \"description\": \"description\",\r\n    \"solicitor\": \"ry13578\",\r\n    \"title\": \"title\",\r\n    \"urgency\": \"3\"\r\n  }\r\n}"

There are two main differences: uppercase in the first character (token vs Token) and also "\r\n" added to my json.

AFAIK I didn't configure anything in the Newtonsoft, so I don't know why does it behave in different way in each project. Does anyone know the reason?

Sample code:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Formatting = Formatting.Indented,
            NullValueHandling = NullValueHandling.Ignore,
        };
HttpClient client = new HttpClient();
                client.BaseAddress = new Uri("https://ws.domain.com/BackEndService/");
                StringContent c = new StringContent($"{{ \"userLogin\": \"YS00982\", \"password\": \"pass\"}}", Encoding.UTF8, "application/json");
                HttpResponseMessage r = await client.PostAsync("service.svc/Authenticate", c);
            string d = await r.Content.ReadAsStringAsync();
            string token = string.Empty;
            D authres = JsonConvert.DeserializeObject<D>(d);

            if (authres.d.success)
            {
                AuthToken authToken = new AuthToken();
                authToken = authres.d.Data;
                var model = new InteractionModel
                {
                    Description = "description",
                    Title = "title",
                    Solicitor = "ry13578",
                    Urgency = "3"
                };

                object obj = new
                {
                    authToken = authToken,
                    interactionModel = model
                };
                string json = JsonConvert.SerializeObject(obj, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None, ContractResolver = null });
                Console.WriteLine(json);
                StringContent cc = new StringContent(json, Encoding.UTF8, "application/json");

                r = await client.PostAsync("CAUMobileService.svc/CreateInteraction", cc);

                d = await r.Content.ReadAsStringAsync();

                Console.WriteLine(d);
            }

Best regards

shinjidev
  • 383
  • 1
  • 6
  • 21
  • I would suggest reducing each project to a [mcve] - once you have two pieces of code you expect to behave equivalently, we'll be in a much better position to explain the differences. It would also help if you'd provide the actual JSON, rather than the debugger-escaped version of the string. – Jon Skeet Feb 19 '18 at 18:05
  • In both cases I copied the output of the debugger. And also, In both projects I'm using the same piece of code without changes. I was thinking if this is a Newtonsoft configuration. – shinjidev Feb 19 '18 at 18:09
  • 2
    Yes, I'm saying *don't* copy it out of the debugger, because we're seeing an escaped version instead of the actual string. And I strongly suspect that while the code you're *looking at* is the same, there's a difference somewhere else... and if you reduce each of the projects to a [mcve] by gradually removing irrelevant parts (and hard-coding data) you'll find that difference. Without seeing any of your code, we've basically got no chance to help you. – Jon Skeet Feb 19 '18 at 18:11
  • Thank you @JonSkeet I will add my code of both projects. – shinjidev Feb 19 '18 at 18:12
  • Do you have an actual problem with this? Because they look compatible/interchangeable. And do write a [mcve] (2x). And elaborate on the platform, version of the Newtonsoft package etc. – H H Feb 19 '18 at 18:13
  • Please only do so *after* you've reduced them to minimal (but still complete) examples. – Jon Skeet Feb 19 '18 at 18:13
  • In the absence of any demo code, I can only guess that your two projects have different global `JsonSerializerSettings`. See [How to set custom JsonSerializerSettings for Json.NET in MVC 4 Web API?](https://stackoverflow.com/q/13274625) or [JsonSerializerSettings and Asp.Net Core](https://stackoverflow.com/q/35772387) or (for a console app) [Set default global json serializer settings](https://stackoverflow.com/q/21815759). – dbc Feb 19 '18 at 18:38
  • Yes!!!It looks like the JsonSerializerSettings was configured in other place with this: ContractResolver = new CamelCasePropertyNamesContractResolver(). But now, how can I avoid that in my particular serialization? BTW, I'm asking that, because the endpoint service is case sensitive. – shinjidev Feb 19 '18 at 19:46
  • @shinjidev - I can't answer that without a [mcve] showing the framework you are using and how you are returning your object currently. Is it Web API? MVC Core? Something else? You can attach `DefaultNamingStrategy` to your objects as shown [here](https://stackoverflow.com/a/40687963/3744182) but there might be other methods depending on your framework. – dbc Feb 19 '18 at 19:52
  • I have added sample code that generates that problem. In the line of "string json" I'm trying to override the DefaultSettings. Is there any way to do it? Best regards – shinjidev Feb 19 '18 at 19:55

1 Answers1

2

You appear to be using two separate JsonSerializerSettings instances. The default settings is configured to use camel casing via the ContractResolver:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        Formatting = Formatting.Indented,
        NullValueHandling = NullValueHandling.Ignore,
    };

The second instance doesn't specify the ContractResolver:

string json = JsonConvert.SerializeObject(obj, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None, ContractResolver = null });

The ContractResolver is where the casing will be controlled. The Formatting = Formatting.None will eliminate the newlines in your JSON.

Eric
  • 1,737
  • 1
  • 13
  • 17
  • Yes, I modified that line because I needed to eliminate the newlines. Now, I don't know how to "override" the CamelCasePropertyNameContractResolver. – shinjidev Feb 19 '18 at 20:09
  • 1
    Try setting the ContractResolver = new DefaultContractResolver() for Pascal casing. – Eric Feb 19 '18 at 20:13