0

I am trying to change Newtonsoft.Json.Linq to new System.Text.Json on my previous solution I use JObject.Parse(jsonstring) to convert a json string to a Json Object and return it to a OpenApi V3 UI With JObject.Pase I am able to transfor this:

JObject.Parse(Regex.Unescape($"{{{System.Environment.NewLine}\t\"Name\": \"{Name}\",{System.Environment.NewLine}\t\"Version\": \"{Version}\",{System.Environment.NewLine}\t\"Platform\": \"{Platform}\"{((IsPuppetAgentServiceControllerRequired == false) ? String.Empty : $",{System.Environment.NewLine}\t\"IsPuppetAgentServiceControllerRequired\": true")}{((AgentUrl == null) ? String.Empty : $",{System.Environment.NewLine}\t\"AgentUrl\": \"{AgentUrl}\"")}{getModules()}{getModuleSources()}{getEnvironments()}}}"));

to this

enter image description here However I can't do the same with JsonDocument.Parse(jsonstring). Do you know how can I achieve this? This issue is affecting the JsonSerializer.Deserialize as it seems that it does not support JObject type

Using as reference the string in JObject.Parse(......) above, the output using JsonDocument.Parse is enter image description here

Just to be clear the string that I am sending in JObject.Parse and JsonDocument.Parse is the same and it is:

{\n\t"Name": "xxxx",\n\t"Version": "V1",\n\t"Platform": "xxxx",\n\t"Modules": {\n\t\t"Module1": {},\n\t\t"Module2": {\n\t\t\t"property1": "value1",\n\t\t\t"property2": "value2",\n\t\t}\n\t},\n\t"ModuleSources": {\n\t\t"modulesource1": {\n\t\t\t"url": "http://www.example.com"\n\t\t},\n\t\t"modulesource2": {\n\t\t\t"url": "http://www.example.com"\n\t\t}\n\t},\n\t"Environments": ["env1","env2"]\n}

It is well formed, otherwise JObject.Parse should not be able to parse it properly and provide me the output shown above

Adding a Code tests:

Working

/// <response code="200">The request has succeeded.</response>
/// <response code="400">The server can not find a current representation for the target resource or is not willing to disclose that one exists.</response>
/// <response code="500">Internal Server Error</response>
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public JObject Get()
{
     String str = $"{{{System.Environment.NewLine}\t\"Name\": \"name_xxxx\",{System.Environment.NewLine}\t\"Version\": \"vesion_xxxx\",{System.Environment.NewLine}\t\"Platform\": \"platform_xxxx\",{System.Environment.NewLine}\t\"AgentUrl\": \"https://www.example.com\",{System.Environment.NewLine}\t\"Modules\":{{{System.Environment.NewLine}\t\t\"module1\":{{}},{System.Environment.NewLine}\t\t\"module2\":{{{System.Environment.NewLine}\t\t\t\"property1\": \"value1\",{System.Environment.NewLine}\t\t\t\"property2\": \"value2\"}}{System.Environment.NewLine}\t}},{System.Environment.NewLine}\t\"ModuleSources\":{{{System.Environment.NewLine}\t\t\t\"modulesource1\":{{{System.Environment.NewLine}\t\t\t\t\"url\": \"https://www.example.com\"}},{System.Environment.NewLine}\t\t\t\"modulesource2\":{{{System.Environment.NewLine}\t\t\t\t\"url\": \"https://www.example.com\"}}{System.Environment.NewLine}\t}},{System.Environment.NewLine}\t\"Environments\":[\"env1\", \"env2\"]{System.Environment.NewLine}}}";
     return JObject.Parse(str);
}

This with JObject.Parse works but with JsonDocument.Parse doesn't The string when debugging is the same as described above enter image description here

Looking it in the text viewer of visual studio while debugging enter image description here

NotWorking

/// <response code="200">The request has succeeded.</response>
/// <response code="400">The server can not find a current representation for the target resource or is not willing to disclose that one exists.</response>
/// <response code="500">Internal Server Error</response>
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public JsonDocument Get()
{
     String str = $"{{{System.Environment.NewLine}\t\"Name\": \"name_xxxx\",{System.Environment.NewLine}\t\"Version\": \"vesion_xxxx\",{System.Environment.NewLine}\t\"Platform\": \"platform_xxxx\",{System.Environment.NewLine}\t\"AgentUrl\": \"https://www.example.com\",{System.Environment.NewLine}\t\"Modules\":{{{System.Environment.NewLine}\t\t\"module1\":{{}},{System.Environment.NewLine}\t\t\"module2\":{{{System.Environment.NewLine}\t\t\t\"property1\": \"value1\",{System.Environment.NewLine}\t\t\t\"property2\": \"value2\"}}{System.Environment.NewLine}\t}},{System.Environment.NewLine}\t\"ModuleSources\":{{{System.Environment.NewLine}\t\t\t\"modulesource1\":{{{System.Environment.NewLine}\t\t\t\t\"url\": \"https://www.example.com\"}},{System.Environment.NewLine}\t\t\t\"modulesource2\":{{{System.Environment.NewLine}\t\t\t\t\"url\": \"https://www.example.com\"}}{System.Environment.NewLine}\t}},{System.Environment.NewLine}\t\"Environments\":[\"env1\", \"env2\"]{System.Environment.NewLine}}}";
     return JsonDocument.Parse(str);
}
DanielV
  • 2,076
  • 2
  • 40
  • 61
delucaezequiel
  • 483
  • 2
  • 9
  • 26
  • 2
    *However I can't do the same with `JsonDocument.Parse(jsonstring)`* - why not? What is the problem? As long as `jsonstring` is well-formed you should be able to parse it with `JsonDocument.Parse()`. If it doesn't work, might you please [edit] your question to include a [mcve] demonstrating the problem? If you can share the value of that large `Regex.Unescape( ... )` expression, it's more likely we will be able to help. – dbc Oct 20 '20 at 21:39
  • I just added the output of JsonDocument.Parse and the string as it is shown in debugger mode including the escaped characters. – delucaezequiel Oct 21 '20 at 15:53
  • 1
    Might you please [edit] your question to share the JSON string in a more usable format -- either as a raw string without escaping (which you can get by typing `Debug.WriteLine(jsonString)` in the immediate window), or as a c# string literal that can be used in code? I tried copying your string literal into some code and it doesn't compile and I'm not sure how to fix it, see https://dotnetfiddle.net/Y2eyzk – dbc Oct 21 '20 at 17:21
  • I just added two lines of code with a working Json string manually generated. As instead of getting it from a file, I write it manually I remove the tabs in the environments array only – delucaezequiel Oct 21 '20 at 18:25
  • Both `JObject.Parse(str)` and `JsonDocument.Parse(str)` generate equivalent results, The only difference is in formatting of the output after they are re-serialized to strings. See https://dotnetfiddle.net/erw7uE, which shows that `Assert.IsTrue(JToken.DeepEquals(obj, JToken.Parse(doc.RootElement.ToString())));` passes successfully. Still not sure what your problem is. – dbc Oct 21 '20 at 19:10
  • Hi: I just replace the json output as code by images (Image 1 and Image 2). The issue that I have is the output that is displayed in OpenApi V3 / Swagger as response when using JsonDocument.Parse – delucaezequiel Oct 21 '20 at 20:14
  • 1) Please include your code and JSON as **text** rather than as a screenshot. For why, see [*Discourage screenshots of code and/or errors*](https://meta.stackoverflow.com/a/307500) and [*Why not upload images of code on SO when asking a question*](https://meta.stackoverflow.com/a/285557). 2) *The issue that I have is the output that is displayed in OpenApi V3 / Swagger as response when using JsonDocument.Parse* then might you please [edit] your question to explain your precise issue and how to reproduce it -- i.e. provide a [mcve]? – dbc Oct 21 '20 at 20:23
  • If you are using `System.Text.Json` instead of Json.NET in asp.net core (i.e. you haven't called [`AddNewtonsoftJson()`](https://stackoverflow.com/a/55666898/3744182)), you can return free-form JSON by doing `using var doc = JsonDocument.Parse(str); return doc.RootElement.Clone();` The returned element must be cloned as explained in [this answer](https://stackoverflow.com/a/58273914/3744182) to [Converting newtonsoft code to System.Text.Json in .net core 3. what's equivalent of JObject.Parse and JsonProperty](https://stackoverflow.com/q/58271901/3744182). – dbc Oct 21 '20 at 23:26
  • [Modifying a JSON file using System.Text.Json](https://stackoverflow.com/q/58997718/3744182) might also apply. Or, since you already have a valid, well-formed JSON string, couldn't you just return it as shown e.g. [here](https://stackoverflow.com/q/48336680/3744182)? – dbc Oct 21 '20 at 23:27

1 Answers1

1

It took me some time, but I finally find the solution. I just had to remove / comment the old NewtonsoftJson controller on ConfigureService function in Startup.cs. It seems that with the two controller in place, the second one .AddJsoOption..... was not taking effect

public void ConfigureServices(IServiceCollection services)
{
     services.AddControllers();
     //services.AddControllers().AddNewtonsoftJson();
     services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true);
     ...

Once I remove the Json was properly displayed on OpenApi / Swagger.

As a side note, if you don't want to display the rootElement just change the function as follows:

/// <response code="200">The request has succeeded.</response>
/// <response code="400">The server can not find a current representation for the target resource or is not willing to disclose that one exists.</response>
/// <response code="500">Internal Server Error</response>
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public JsonElement Get()
{
     String str = $"{{{System.Environment.NewLine}\t\"Name\": \"name_xxxx\",{System.Environment.NewLine}\t\"Version\": \"vesion_xxxx\",{System.Environment.NewLine}\t\"Platform\": \"platform_xxxx\",{System.Environment.NewLine}\t\"AgentUrl\": \"https://www.example.com\",{System.Environment.NewLine}\t\"Modules\":{{{System.Environment.NewLine}\t\t\"module1\":{{}},{System.Environment.NewLine}\t\t\"module2\":{{{System.Environment.NewLine}\t\t\t\"property1\": \"value1\",{System.Environment.NewLine}\t\t\t\"property2\": \"value2\"}}{System.Environment.NewLine}\t}},{System.Environment.NewLine}\t\"ModuleSources\":{{{System.Environment.NewLine}\t\t\t\"modulesource1\":{{{System.Environment.NewLine}\t\t\t\t\"url\": \"https://www.example.com\"}},{System.Environment.NewLine}\t\t\t\"modulesource2\":{{{System.Environment.NewLine}\t\t\t\t\"url\": \"https://www.example.com\"}}{System.Environment.NewLine}\t}},{System.Environment.NewLine}\t\"Environments\":[\"env1\", \"env2\"]{System.Environment.NewLine}}}";
     return JsonDocument.Parse(str).RootElement;
}
delucaezequiel
  • 483
  • 2
  • 9
  • 26