2

This sound very simple. But I can't find how to do it.

I've receiving a bad json from an api. the actual json is inside a string

Instead of

[{\"ProductId\":1,\"ProductName\":\"abuka\",\"Rate\":6.00,\"Quantity\":10.000},{\"ProductId\":2,\"ProductName\":\"abuka\",\"Rate\":6.00,\"Quantity\":10.000},{\"ProductId\":3,\"ProductName\":\"abuka\",\"Rate\":6.00,\"Quantity\":10.000}]

I'm receiving

"[{\"ProductId\":1,\"ProductName\":\"abuka\",\"Rate\":6.00,\"Quantity\":10.000},{\"ProductId\":2,\"ProductName\":\"abuka\",\"Rate\":6.00,\"Quantity\":10.000},{\"ProductId\":3,\"ProductName\":\"abuka\",\"Rate\":6.00,\"Quantity\":10.000}]"

When I try

JsonConvert.DeserializeObject<List<Product>> (jsonString)

I get error Error converting to System.Collections.Generic.List

How can I extract it into a valid JSON string before deserialising?

4
  • Are the backslashes definitely there, or are you seeing this in the debugger? Commented May 23, 2017 at 10:48
  • 3
    You can always go back to the creator of the API and ask them to create valid outputs. I'm sure there is some documentation somewhere as to what is valid json (and escaping quotes is probably not valid). Back up your research with links to various sites that will not decode the API output. Commented May 23, 2017 at 10:49
  • @JonSkeet Not from debugger. This is how I get the response. I copied and pasted it here from response's raw data in Rest client Commented May 23, 2017 at 10:54
  • Right. It would be helpful to create a minimal reproducible example. (That's what I've been doing when trying to put together an answer...) Commented May 23, 2017 at 10:54

2 Answers 2

7

If you've got a value which is "a string serialized as JSON", then just deserialize that first. Assuming your string genuinely starts and ends with a double quote, you should be fine to call JsonConvert.DeserializeObject<string> to do that unwrapping:

using System;
using System.IO;
using Newtonsoft.Json;

public class Model
{
    public string Foo { get; set; }
}

public class Test
{
    static void Main()
    {
        string json = "\"{\\\"foo\\\": \\\"bar\\\"}\"";
        Console.WriteLine($"Original JSON: {json}");        
        string unwrappedJson = JsonConvert.DeserializeObject<string>(json);
        Console.WriteLine($"Unwrapped JSON: {unwrappedJson}");
        Model model = JsonConvert.DeserializeObject<Model>(unwrappedJson);
        Console.WriteLine($"model.Foo: {model.Foo}");
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

Thanks Jon Skeet. Referring to your answer, the users who are not using "Newtonsoft.Json" in the application but the Web API which gives the data uses "Newtonsoft.Json" for them below one might be helpful.

Example :

In WEB API - "Newtonsoft.Json" used

The application(might be MVC/ASP.NET WebForms) which consumes WEB API, doesn't use "Newtonsoft.Json". So, they can reference to "System.Web.Extensions" and use using System.Web.Script.Serialization to desialize the json data.

using System.Collections.Generic;
using System.Web.Script.Serialization;

namespace DesrializeJson1ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string jsonstring = "\"[{\\\"ProductId\\\":1,\\\"ProductName\\\":\\\"abuka\\\",\\\"Rate\\\":6.00,\\\"Quantity\\\":10.000},{\\\"ProductId\\\":2,\\\"ProductName\\\":\\\"abuka\\\",\\\"Rate\\\":6.00,\\\"Quantity\\\":10.000},{\\\"ProductId\\\":3,\\\"ProductName\\\":\\\"abuka\\\",\\\"Rate\\\":6.00,\\\"Quantity\\\":10.000}]\"";
            var serializer = new JavaScriptSerializer();
            var jsonObject = serializer.Deserialize<string>(jsonstring);
            List<Product> lstProducts = serializer.Deserialize<List<Product>>(jsonObject);
            foreach(var item in lstProducts)
            {
                Console.WriteLine("ProductId :" + item.ProductId);
                Console.WriteLine("ProductName :" + item.ProductName);
                Console.WriteLine("Rate :" + item.Rate);
                Console.WriteLine("Quantity :" + item.Quantity);
                Console.WriteLine("--------------------------");
            }
            Console.Read();
        }
    }
    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public double Rate { get; set; }
        public double Quantity { get; set; }
    }

}

OUTPUT

enter image description here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.