0

I'm creating a web service that generates random personal data (hence the inclusion of a counter in the code below) using a combination of a third party web service and methods. However, when I specified the content type as

application/json

, the result contains escape backslashes.

From what I've read, this is probably a result of the serialization used but despite trying several solutions, I can't solve the issue.

Data Model

public class Response
{
    public string name { get; set; }
    public string surname { get; set; }
    public string address { get; set; }
    public string telephone { get; set; }
    public string email { get; set; }
    public string dateOfBirth { get; set; }
    public string sex { get; set; }
    public string countryOfBirth { get; set; }
    public string currency { get; set; }
}

Method

public class DatasetServices
    {
        public string GenerateDataset()
        {
            int counter = 3;

            StringBuilder result = new StringBuilder();

            for (int i = 0; i < counter; i++)
            {
                try
                {
                    Dataset dataset = new Dataset();
                    Dataset.Item item = new Dataset.Item();

                    string apiKey = "KEY";
                    HttpWebRequest apiRequest = WebRequest.Create("URI" + apiKey) as HttpWebRequest;

                    string apiResponse = "";
                    using (HttpWebResponse response = apiRequest.GetResponse() as HttpWebResponse)
                    {
                        StreamReader reader = new StreamReader(response.GetResponseStream());
                        apiResponse = reader.ReadToEnd();
                    }

                    Response responseObject = JsonConvert.DeserializeObject<Response>(apiResponse);

                    item.name = responseObject.name;
                    item.surname = responseObject.surname;
                    item.address = responseObject.address;
                    item.city = GenerateCity();
                    item.telephone = responseObject.telephone;
                    item.email = responseObject.email;
                    item.dateOfBirth = responseObject.dateOfBirth;
                    item.sex = responseObject.sex;
                    item.maritalStatus = GenerateMaritalStatus();
                    item.nationality = responseObject.countryOfBirth;
                    item.countryOfBirth = responseObject.countryOfBirth;
                    item.grossAnnualIncome = GenerateGrossAnnualIncome();
                    item.currency = responseObject.currency;

                    var json = JsonConvert.SerializeObject(item);

                    result.Append(json);

                }
                catch (Exception)
                {
                    if (i == counter)
                    {
                        throw;
                    }
                }
            }
            string output = result.ToString();
            return output;

            throw new ArgumentOutOfRangeException("The generation counter was equal to zero.");
        }

Controller

        [HttpGet]
        public ActionResult<IEnumerable> OutputDataset()
        {
            Response.ContentType = "application/json";
            return datasetServices.GenerateDataset();
        }

Result

"{\"name\":\"Sibby\",\"surname\":\"Packman\",\"address\":\"59 Aberg Alley\",\"city\":\"San Javier\",\"telephone\":\"6322049027\",\"email\":\"spackman0@chicagotribune.com\",\"dateOfBirth\":\"10/22/1987\",\"sex\":\"Female\",\"maritalStatus\":\"Single\",\"nationality\":\"RU\",\"countryOfBirth\":\"RU\",\"grossAnnualIncome\":71000,\"currency\":\"RUB\"}{\"name\":\"Mariska\",\"surname\":\"Worrell\",\"address\":\"927 Green Ridge Point\",\"city\":\"Frisco\",\"telephone\":\"5668115189\",\"email\":\"mworrell0@php.net\",\"dateOfBirth\":\"10/1/1998\",\"sex\":\"Female\",\"maritalStatus\":\"Single\",\"nationality\":\"GT\",\"countryOfBirth\":\"GT\",\"grossAnnualIncome\":24000,\"currency\":\"GTQ\"}{\"name\":\"Eleonore\",\"surname\":\"Follan\",\"address\":\"3876 Colorado Avenue\",\"city\":\"Mont-Dore\",\"telephone\":\"4004483706\",\"email\":\"efollan0@jalbum.net\",\"dateOfBirth\":\"3/6/1992\",\"sex\":\"Female\",\"maritalStatus\":\"Married\",\"nationality\":\"CN\",\"countryOfBirth\":\"CN\",\"grossAnnualIncome\":50000,\"currency\":\"CNY\"}"

Hav31ock
  • 51
  • 1
  • 8
  • 1
    What makes you think the result contains backslashes? Are you sure it's not just Visual Studio displaying a string to you? – DavidG Jan 30 '19 at 17:09
  • Apologies for not including the results. I've updated my question with it. Meanwhile, the backslashes are also included when viewing the response as JSON in ReadyAPI. – Hav31ock Jan 30 '19 at 17:14
  • 1
    What you have posted is a string containing valid JSON. We would need to know more about your system to determine if this is valid or not. – DavidG Jan 30 '19 at 17:14
  • I'm using Visual Studio Community 15.9.6 and .Net Framework 4.7.03056. Please advise what other information you're after. – Hav31ock Jan 30 '19 at 18:15
  • Is that really the complete response of the Api call? I suspect that a [ and ] are missing. – fredrik Jan 30 '19 at 18:45
  • Yeah, that's all there is. Something's definitely not right. – Hav31ock Jan 30 '19 at 18:47
  • Output dataset returns an enumeration. That will probably be a list of string hence you have the escaped string... make it return a simple string and you should get better results. – fredrik Jan 30 '19 at 19:20
  • Gave it a go but the result's identical. – Hav31ock Jan 30 '19 at 19:34
  • `OutputDataSet()` returns [`ActionResult`](https://github.com/aspnet/Mvc/blob/master/src/Microsoft.AspNetCore.Mvc.Core/ActionResultOfT.cs) but `GenerateDataset()` returns a `string`. The only reason that happens to work is that `string` implements `IEnumerable`, which means basically your method returns an enumeration of objects which could be anything but happen to be chars. ... – dbc Jan 30 '19 at 20:14
  • That's an odd things to do and I'm surprised it works at all, but the result seems to be a duplicate of [JSON.NET Parser *seems* to be double serializing my objects](https://stackoverflow.com/q/25559179/3744182). And the solution should be the same -- declare that your method returns an `ActionResult>` for some appropriate `T` (here ` `Dataset.Item` apparently?) and let the framework do the serialization. Don't do it yourself. – dbc Jan 30 '19 at 20:16
  • Makes sense as I suspected that the serialization was the cause. However, declaring that the method returns ActionResult> presents another problem: Converting the result from StringBuilder. – Hav31ock Jan 30 '19 at 20:44
  • 1
    Don't create a `StringBuilder` at all; don't serialize anything manually at all. Simply make `datasetServices.GenerateDataset();` return a `List`, then return a `ActionResult>` from `OutputDataset()` and let the framework do the work. – dbc Jan 30 '19 at 20:55
  • That did the trick. Thank you for your help. – Hav31ock Jan 31 '19 at 08:33

1 Answers1

0

Here's the solution to the problem, as kindly posted by dbc.

That's an odd things to do and I'm surprised it works at all, but the result seems to be a duplicate of JSON.NET Parser seems to be double serializing my objects. And the solution should be the same -- declare that your method returns an ActionResult> for some appropriate T (here ` Dataset.Item apparently?) and let the framework do the serialization. Don't do it yourself.

Hav31ock
  • 51
  • 1
  • 8