user2178604
user2178604

Reputation: 33

Consuming asp.net web.api json not working

I'm trying to consume my web api which returns JSON format from my asp.net mvc web application. As my JSON format has root node (the way i filled with oledb dataset). I'm keep getting the following error.

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List'1[FileAttributes]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'SearchData', line 1, position 14.

Here is the code sample

string Baseurl = "http://localhost:62602/";
client.BaseAddress = new Uri(Baseurl);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage Res = await client.GetAsync("api/FileSearch/?searchTerm=" + searchTerm );
if (Res.IsSuccessStatusCode)
{
    var fsResponse = Res.Content.ReadAsStringAsync().Result;
    List<FileAttributes> fileAttribultes = JsonConvert.DeserializeObject<List<FileAttributes>>(fsResponse);
}

And then following some ideas, I used JSON.Parse and SelectToken to remove root node, but this time the List<FileAttributes> returns data but with null values

JToken jtok = JObject.Parse(fsResponse).SelectToken("SearchData");
List<FileAttributes> fileAttribultes = JsonConvert.DeserializeObject<List<FileAttributes>>(fsResponse);

Here is my FileAttributes class

public class FileAttributes
{
    public string Name { get; set; }
    public string Header { get; set; }
    public string Title { get; set; }
 }

I appreciate if anyone check whats wrong in the deserialization of JSON part with root node and whats the right way to do it?

Copied from POSTMAN output

{ "SearchData": [ { "SYSTEM.NAME": "FILE NAME 1" , "SYSTEM.HEADER": "HEADER 1", "SYSTEM.TITLE": "TITLE 1", }, { "SYSTEM.NAME": "FILE NAME 1" , "SYSTEM.HEADER": "HEADER 1", "SYSTEM.TITLE": "TITLE 1", }, { "SYSTEM.NAME": "FILE NAME 1" , "SYSTEM.HEADER": "HEADER 1", "SYSTEM.TITLE": "TITLE 1", }] }

Upvotes: 2

Views: 578

Answers (1)

Nkosi
Nkosi

Reputation: 247521

Based on the JSON the object model needs to be updated to match. Which also need to include JsonProperty attribute to match up the JSON keys to the properties of the class.

public class FileAttributes {
    [JsonProperty("SYSTEM.NAME")]
    public string Name { get; set; }
    [JsonProperty("SYSTEM.HEADER")]
    public string Header { get; set; }
    [JsonProperty("SYSTEM.TITLE")]
    public string Title { get; set; }
}

public class RootObject {
    public IList<FileAttributes> SearchData { get; set; }
}

Then update the call to the service accordingly

string Baseurl = "http://localhost:62602/";
client.BaseAddress = new Uri(Baseurl);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync("api/FileSearch/?searchTerm=" + searchTerm );
if (response.IsSuccessStatusCode) {
    var json = await response.Content.ReadAsStringAsync();
    RootObject result = JsonConvert.DeserializeObject<RootObject>(json);
    var fileAttribultes = result.SearchData; 
    //...
}

Upvotes: 1

Related Questions