4

I am working on 2 web applications; A & B. now i have a shared class named CRUDOutput as follow on both web applications:-

public class CRUDOutput
{
    public Operation4 operation { get; set; }
}
public class Operation4
{
    public Result result { get; set; }
    public string name { get; set; }
}
public class Result
{
    public string status { get; set; }
    public string message { get; set; }

}

now inside web application A i am returning the following:-

[HttpPost]
public ActionResult CreateResource(CreateResource cr)
{
    List<CRUDOutput> co = new List<CRUDOutput>();
            co.Add(JsonConvert.DeserializeObject<CRUDOutput>(crudoutput));
            co.Add(JsonConvert.DeserializeObject<CRUDOutput>(crudoutput2));

    return Json(JsonConvert.SerializeObject(co));
}

now from web application B, i am calling the action method as follow:-

try
{
    using (WebClient wc = new WebClient()) 
    {
        string url = "https://localhost:44302/" + "Home/CreateResource";
        Uri uri = new Uri(url);
        wc.Headers.Add(HttpRequestHeader.ContentType, "application/json");

        output = wc.UploadString(uri,  data);
    }
}
catch (WebException e)
{
}
List<CRUDOutput> result = JsonConvert.DeserializeObject<List< CRUDOutput>>(output);

but i will get the following exception when i tried to deserialize the output:-

Error converting value "[{"operation":{"result":{"status":"Success","message":"Resource has been added successfully to ......"},"name":"CREATE RESOURCE"}},{"operation":{"result":{"status":"Failed","message":"Account addition "},"name":"ADD ACCOUNTS"}}]" to type 'System.Collections.Generic.List`1[S.ViewModels.CRUDOutput]'. Path '', line 1, position 464.

now the JSON return from web application A will be as follow:-

"\"[{\\\"operation\\\":{\\\"result\\\":{\\\"status\\\":\\\"Success\\\",\\\"message\\\":\\\"Resource 123 rfrf has been added successfully \\\"},\\\"name\\\":\\\"CREATE RESOURCE\\\"}},{\\\"operation\\\":{\\\"result\\\":{\\\"status\\\":\\\"Failed\\\",\\\"message\\\":\\\"Account addition \\\"},\\\"name\\\":\\\"ADD ACCOUNTS\\\"}}]\""

so can anyone advice why i am unable to deserialize to a list of objects?

John John
  • 1
  • 72
  • 238
  • 501

1 Answers1

7

The output as you've pasted is encoded as JSON twice. Compare the difference between:

"\"[{\\\"operation\\\":{\\\"result\\\":{\\\"status\\\":\\\"Success\\\",\\\"message\\\":\\\"Resource 123 rfrf has been added successfully \\\"},\\\"name\\\":\\\"CREATE RESOURCE\\\"}},{\\\"operation\\\":{\\\"result\\\":{\\\"status\\\":\\\"Failed\\\",\\\"message\\\":\\\"Account addition \\\"},\\\"name\\\":\\\"ADD ACCOUNTS\\\"}}]\""

and

"[{\"operation\":{\"result\":{\"status\":\"Success\",\"message\":\"Resource 123 rfrf has been added successfully \"},\"name\":\"CREATE RESOURCE\"}},{\"operation\":{\"result\":{\"status\":\"Failed\",\"message\":\"Account addition \"},\"name\":\"ADD ACCOUNTS\"}}]"

This happens because you're encoding the result as Json twice. Replace:

return Json(JsonConvert.SerializeObject(result));

with

return Json(result);    // This encodes as JSON automatically
Richard
  • 29,854
  • 11
  • 77
  • 120
  • so you mean MVC will do the serialization for me ? – John John Jun 08 '16 at 13:12
  • 1
    Yes, it will. The `Json` method takes an object, not a string. – Richard Jun 08 '16 at 13:14
  • so will there be any benefit of using JSON.net ? as seems mvc will do the job out of the box? or JSON.net will do things which MVC can not do out of the box ? – John John Jun 08 '16 at 13:18
  • 1
    MVC uses json.net under the covers. – Richard Jun 08 '16 at 13:19
  • @Richard This is a common point of confusion. ASP.NET MVC actually does *not* use Json.Net under the covers; it uses JavaScriptSerializer, apparently for backward compatibility reasons. (See the source code for [JsonResult](https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/JsonResult.cs).) ASP.NET Web API on the other hand, *does* use Json.Net. To get MVC to also use Json.Net, see [this question](http://stackoverflow.com/questions/23348262/using-json-net-to-return-actionresult). – Brian Rogers Jun 08 '16 at 14:26
  • @BrianRogers so in my case if i want to return an object using JavaScriptSerializer from my action method what are the approaches i can follow? – John John Jun 10 '16 at 10:17
  • 1
    @johng If you want to use `JavaScriptSerializer`, then just use `Json(result)` as Richard showed you in his answer above. – Brian Rogers Jun 10 '16 at 14:27
  • @BrianRogers sorry i meant if i want to return Json.Net from my action method ..how i can do so ? second point will the returned json differ if i serialize it using json.net or javascriptserializer ? i think both will/should just serialize exactly the same json object... i mean since i am deserializing using json.net ,,, will it cause any problem if i serialize using other library or just say return Json(result) – John John Jun 10 '16 at 14:51
  • @johnG 1. To use Json.Net in MVC there are two approaches; both are covered here: [Using JSON.NET to return ActionResult](http://stackoverflow.com/q/23348262/10263). 2. The two serializers are mostly interoperable, but there are some differences. The biggest difference is how they treat dates. JavaScriptSerializer serializes dates like `"\/Date(1465582440724)\/"`, whereas Json.Net serializes them like `"2016-06-10T13:14:00.724082-05:00"` by default. Json.Net does have a `DateFormatHandling` setting that allows it to use the JavaScriptSerializer format though, if you need to. – Brian Rogers Jun 10 '16 at 18:26