0

I am trying to deserialze this json stream:

[{"id":11,"title":"xyz","image":{"url":"/uploads/xxx/yyy/11/pic_1234.jpg"},"target":1}]

This is the simplified fragment of the code I am using to deserialze the stream:

public class Template
{
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "title")]
    public string Title { get; set; }       

    [JsonProperty(PropertyName = "image")]    
    public string Image { get; set; }      

    [JsonProperty(PropertyName = "target")]
    public string Target { get; set; }
}

string url = @"http://my-url-here";

IList<Template> templates = new List<Template>();

using (var webClient = new WebClient())
{                
    var json = webClient.DownloadString(url);
    templates = JsonConvert.DeserializeObject<List<Template>>(json);           
    ...              
}

JsonConvert.DeserializeObject throws an exception parsing image field:

...Unexpected character encountered while parsing value: {. Path '[0].image',...

This is the full exception:

Newtonsoft.Json.JsonReaderException occurred HResult=0x80131500 Message=Unexpected character encountered while parsing value: {. Path '[0].image', line 1, position 171. Source=Newtonsoft.Json StackTrace: at Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType) at Newtonsoft.Json.JsonTextReader.ReadAsString() at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value) at Promociones.JsonApi.GetTemplates() in C:\xxxxx...\Program.cs:line 19

Raul Lopez
  • 19
  • 4
  • 2
    Please post the FULL error, including stack. – JuanR Nov 17 '17 at 15:17
  • ... and also the content of `json` – Rico Suter Nov 17 '17 at 15:18
  • url when json try to parse it its just string... Not image .. So its obvious it will throw that error. – nikunjM Nov 17 '17 at 15:18
  • 1
    You have `Image` as a `string` but in the json it's an object. – 001 Nov 17 '17 at 15:19
  • 1
    Within the `Template` `Image` is just a string but within json it is object with url property... – Johnny Nov 17 '17 at 15:19
  • Read the error, read [ask], show your research, don't hand-craft JSON DTOs if you don't know what you're doing but let tools generate them. – CodeCaster Nov 17 '17 at 15:25
  • @CodeCaster I'm not sure I agree that this is a duplicate of the question you linked. While the error is nearly the same, the cause of the problem is not. In the other question, the problem was the OP did not pass a JSON string to `DeserializeObject` (he passed a file path instead). In this question, the OP did not have a correct model (he used a string where he needed another class). I'm not sure that the linked duplicate would have necessarily helped answer this one. – Brian Rogers Nov 17 '17 at 15:59
  • @Brian yeah the second answer contains the answer to the root cause. I chose that duplicate because the error message matches _and_ a highly upvoted answer answers the question. We get tens of _"How to parse JSON"_ questions per day. Perhaps we need a new canonical duplicate. – CodeCaster Nov 17 '17 at 16:04

2 Answers2

4

In the JSON fragment, the image property is not a string, but an object that contains the url string property.

Therefore, you should have the following model:

public class Image
{
    [JsonProperty(PropertyName = "url")]
    public string Url { get; set; }
}

public class Template
{
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "title")]
    public string Title { get; set; }

    [JsonProperty(PropertyName = "image")]
    public Image Image { get; set; }

    [JsonProperty(PropertyName = "target")]
    public string Target { get; set; }
}
Cristian Lupascu
  • 39,078
  • 16
  • 100
  • 137
0

In Your JSon Stream You have part

"image": {"url":"/uploads/xxx/yyy/11/pic_1234.jpg"}

and it means that You try to deserialize not string but an object which could be described as

public class ImagePath {
     [JsonProperty(PropertyName = "url")]
     public string Url { get; set; }
}

and In Your deserialized class

[JsonProperty(PropertyName = "image")]    
public ImagePath Image { get; set; }     
paqao
  • 81
  • 4