-2

I am using C#

in my code, I call API

This API returns a string.

But the problem is when I read the API it comes with backslashes and quotations.

So if the returned value is Black\White's colors

It becomes "\"Black\\\\White's colors\""

or empty string is "\"\""

I wonder if there is a way to parse string the in a right way.

here is my code

        HttpClient client = new HttpClient();
        client.DefaultRequestHeaders.Accept.Add(
        new MediaTypeWithQualityHeaderValue("application/json"));

        string str = client.GetStringAsync(url).Result;
asmgx
  • 7,328
  • 15
  • 82
  • 143
  • 2
    It's JSON -- use a json library, like `Newtonsoft.Json` or `System.Text.Json` and call `JsonSerializer.Deserialize(await client.GetStringAsync(url));` – Andy May 23 '21 at 03:00
  • @Andy Deserializing of this value doesnt work. It needs to be a proper JSON object for deserialization to work.. – Jawad May 23 '21 at 03:02
  • @Jawad -- what are you talking about? A simple `string` is a perfectly acceptable type for JSON. – Andy May 23 '21 at 03:03
  • @Andy `JsonConvert.DeserializeObject("\"Black\\\\White's\" colors");` produces the error: `Additional text encountered after finished reading JSON content: c. Path '', line 1, position 17.'` – Jawad May 23 '21 at 03:04
  • @Jawad -- it works fine in `Newtonsoft.Json`. Meh, this is why i stay away from System.Text.Json. – Andy May 23 '21 at 03:04
  • @Andy is there another type i can use to get a pure text instead of "application/json"? – asmgx May 23 '21 at 03:05
  • @Andy my bad. it works with JSON.Net but the string OP has is not valid. – Jawad May 23 '21 at 03:06
  • @Andy and Jawad I think there is additional char has got in the text here is the correct output "\"Black\\\\White's colors\"" – asmgx May 23 '21 at 03:10
  • @asmgx Use Andy's first comment and deserialize like he mentioned. that works. – Jawad May 23 '21 at 03:11
  • to get that line to work, add `using System.Text.Json;` to the top of your file. – Andy May 23 '21 at 03:12
  • @Andy then what? – asmgx May 23 '21 at 03:14
  • look at my first comment.. do that... `JsonSerializer.Deserialize(await client.GetStringAsync(url));` -- if you don't want to use `await` i guess you can do `JsonSerializer.Deserialize(client.GetStringAsync(url).Result);`, but I don't like using `.Result`. – Andy May 23 '21 at 03:14
  • Does this answer your question? [How can I parse JSON with C#?](https://stackoverflow.com/questions/6620165/how-can-i-parse-json-with-c) – Akshay G May 23 '21 at 04:42

1 Answers1

0

Like this

    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Accept.Add(
    new MediaTypeWithQualityHeaderValue("application/json"));

    string str = await client.GetStringAsync(url);

    //choose this if using NewtonsoftJson 
    string parsedWithNewtonsoft = JsonConvert.DeserializeObject<string>(str);

    //choose this if using STJ
    string parsedWithSystemTextJson = JsonSerializer.Deserialize<string>(str);

Choose one of the last two lines according to your preferred installed Json parser (manage nuget packages for the project and install either newtonsoft or system.text.json)

Don't use Result; use async proper (which means you have to make your method calls async all the way up the chain). If you strive to turn all your async calls synchronous then your app will spend a lot of tine sitting around doing nothing, waiting for network io to finish, when that time could be put to doing other useful work

Also, HttpClient is not supposed to be created anew every time you want to use it. Either configure your DI with services.AddHttpClient(); passing in options as necessary or if you aren't using DI/not writing a service of your own, you can get some ideas on how to use HttpClientFactory to manufacture HttpClients for you form this question - you may even be able to configure the default request headers as part of the manufacture so you don't need to set them in code

Finally, I should point out that I think there's a chance you're doing a lot more work than you need to if your API you're using publishes a swagger document; if it does you can use a tool like AutoRest (or the "add rest client" feature of visual studio, which uses AR), NSwag, WebApiClientGen etc and tell it "here is the api I want to use" and it'll make everything you need to call the api and return c# objects; you don't need to code any of this low level stuff, pushing data around and parsing responses, yourself

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
  • I am getting this error when i try to call the function that calls the API : Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'string' – asmgx May 23 '21 at 07:20
  • More issues of converting System.Threading.Tasks.Task' to 'string, any other way? – asmgx May 23 '21 at 07:52
  • If Task async pattern isn't your bag, then you could simplistically look at it like "if you have a Task and you want x, await the Task". If you're getting that then your code is lacking an `await` call. Did you remove it from `string str = await client.GetStringAsync(url);` ? Put it back. If you get more errors about the method not being declared as async, then declare the method as async (and rename it to have an Async suffix). If you then get more errors because the method that calls it does not await it, then await it (and make that method async, and so on all the way up the chain) – Caius Jard May 23 '21 at 08:26
  • If any method is declared as `void` it should be redeclared as returning Task. If any method returns X it should be redeclared as returning Task – Caius Jard May 23 '21 at 08:33