Setting JSON object name in WCF REST - c#

I am sending JSON:
[
{
"Description": "A kud ces bolje",
"ItemID": 1,
"Name": "Banane",
"NewPrice": 91.99,
"OldPrice": 161.99,
"SaleEnds": "9/1/2013",
"SaleStarts": "9/1/2012"
},
{
"Description": "Rastu na stablu",
"ItemID": 2,
"Name": "Kruske",
"NewPrice": 93.99,
"OldPrice": 117.99,
"SaleEnds": "9/1/2013",
"SaleStarts": "9/1/2012"
},
]
But I want to have a name so that it looks like
"Some_Name":[
{
"Description": "A kud ces bolje",
"ItemID": 1,
"Name": "Banane",
"NewPrice": 91.99,
"OldPrice": 161.99,
"SaleEnds": "9/1/2013",
"SaleStarts": "9/1/2012"
},
{
"Description": "Rastu na stablu",
"ItemID": 2,
"Name": "Kruske",
"NewPrice": 93.99,
"OldPrice": 117.99,
"SaleEnds": "9/1/2013",
"SaleStarts": "9/1/2012"
},
]
I return List<Item>:
[OperationContract]
[WebGet(UriTemplate = "/items/{id}", ResponseFormat = WebMessageFormat.Json)]
List<ItemService> GetItems(string id);
and the Item is:
[DataContract]
public class ItemService
{
[DataMember]
public int ItemID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public Decimal OldPrice { get; set; }
[DataMember]
public Decimal NewPrice { get; set; }
[DataMember]
public string SaleStarts { get; set; }
[DataMember]
public string SaleEnds { get; set; }
}

You can't name the JSon data itself. You would need a small wrapper class containing the name:
class Wrapper { public Some_Name List<ItemService> {get;set;}
Wrap your list in the wrapper and return the wrapper.
The resulting JSon would be somehting like:
{
"Some_Name":[
{
"Description": "A kud ces bolje",
"ItemID": 1,
"Name": "Banane",
"NewPrice": 91.99,
"OldPrice": 161.99,
"SaleEnds": "9/1/2013",
"SaleStarts": "9/1/2012"
},
{
"Description": "Rastu na stablu",
"ItemID": 2,
"Name": "Kruske",
"NewPrice": 93.99,
"OldPrice": 117.99,
"SaleEnds": "9/1/2013",
"SaleStarts": "9/1/2012"
},
]}

Related

Getting error deserialising JSON to List<T>

I want to deserialize this json to a List of Product objects but i get this error:
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[ShoppingList.Product]' 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) 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.
This is my code:
{
"records": [
{
"id": "60",
"name": "Rolex Watch",
"description": "Luxury watch.",
"price": "25000",
"category_id": "1",
"category_name": "Fashion"
},
{
"id": "48",
"name": "Bristol Shoes",
"description": "Awesome shoes.",
"price": "999",
"category_id": "5",
"category_name": "Movies"
},
{
"id": "42",
"name": "Nike Shoes for Men",
"description": "Nike Shoes",
"price": "12999",
"category_id": "3",
"category_name": "Motors"
}
]
}
public class Product
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public decimal price { get; set; }
public int category_id { get; set; }
public string category_name { get; set; }
}
public async Task<List<Product>> GetProductsAsync()
{
Products = new List<Product>();
var uri = new Uri("https://hostname/api/product/read.php");
try
{
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
Products = JsonConvert.DeserializeObject<List<Product>>(content);
}
}
catch (Exception )
{
throw;
}
return Products;
}
Your Json is not a List<Product>, its an object with a single property called records which is a List<Product>.
So your actual C# model is this:
public class RootObject
{
public List<Product> records { get; set; }
}
And you deserialize like this:
RootObject productsRoot = JsonConvert.DeserializeObject<RootObject>(content);
The issue is that your response JSON you've provided is an object which contains a list, but you are trying to deserialize the data into a straight list. I think all you need to do is add a second class which contains the list into your code, then deserialize using that list.
public class Product
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public decimal price { get; set; }
public int category_id { get; set; }
public string category_name { get; set; }
}
public class RootProduct
{
public List<Product> Products {get;set;}
}
Then you change your deserialization portion from List to
RootProduct response = JsonConvert.DeserializeObject<RootProduct>(content);
The usage would then simply be products. response.Products to access the list of items.
The problem is your json structure. Below is an example of a json array - notice i removed the property "records".
[
{
"id": "60",
"name": "Rolex Watch",
"description": "Luxury watch.",
"price": "25000",
"category_id": "1",
"category_name": "Fashion"
},
{
"id": "48",
"name": "Bristol Shoes",
"description": "Awesome shoes.",
"price": "999",
"category_id": "5",
"category_name": "Movies"
},
{
"id": "42",
"name": "Nike Shoes for Men",
"description": "Nike Shoes",
"price": "12999",
"category_id": "3",
"category_name": "Motors"
}
]
Given this data
[
{
"id": "60",
"name": "Rolex Watch",
"description": "Luxury watch.",
"price": "25000",
"category_id": "1",
"category_name": "Fashion"
},
{
"id": "48",
"name": "Bristol Shoes",
"description": "Awesome shoes.",
"price": "999",
"category_id": "5",
"category_name": "Movies"
},
{
"id": "42",
"name": "Nike Shoes for Men",
"description": "Nike Shoes",
"price": "12999",
"category_id": "3",
"category_name": "Motors"
}
]
And this class definition
public class Order
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public string price { get; set; }
public string category_id { get; set; }
public string category_name { get; set; }
}
The code to convert it from JSON to a C# List<Order> is:
public static List<Order> Map(string json)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<List<Order>>(json);
}

AspnetCore datacontract serialize in JSON with the name namespace of the keys of my dictionary

I tried to send a Dictionary.
This is the structure of my Dictionary:
var gridsAndCountriesByShipper = new Dictionary<Organisation, List<Grid>>();
And this is the class which the namespace appears instead of the object value:
namespace ez.webservice.PublicRestApi.DTO.References
{
[DataContract(Name = "organisation", Namespace = "")]
public class Organisation
{
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(Name = "longName")]
public string LongName { get; set; }
[DataMember(Name = "shortName")]
public string ShortName { get; set; }
}
}
Finally this is the result when I send this object:
return Ok(gridsAndCountriesByShipper);
{
"ez.webservice.PublicRestApi.DTO.References.Organisation": [
{
"owner": {
"$id": "1",
"id": 2,
"longName": null,
"shortName": "Test"
},
"calendar": {
"id": 3,
"name": null,
"dotNetName": null,
"mySqlName": null,
"offset": 0
},
"country": {
"id": 13,
"name": "France",
"alpha2": "FR",
"alpha3": "FRA",
"grids": [],
"logo": {
"id": 13,
"name": "France",
"shortName": "FR"
}
},
"countryFlag": null,
"flag": "",
"granularity": "DAY",
I didn't find a solution.
Your Organisation doesn't override ToString() method and the default behavior is to return the class name with namespace

Web Api; Entity Framework; Data returns recursive

im facing a problem with probably selfreference Looping:
Model:
public class ProtectedAccount
{
public int Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime Created { get; private set; }
public DateTime? Changed { get; set; }
public bool Disabled { get; set; }
public virtual ICollection<ProtectedAccountMember> Members { get; set; }
public virtual ProtectedAccountType Type { get; set; }
}
public class ProtectedAccountMember
{
public int Id { get; set; }
[StringLength(300)]
public string Name { get; set; }
[Index]
public virtual ProtectedAccount ProtectedAccount { get; set; }
}
Controller:
[ResponseType(typeof(ProtectedAccount))]
[Route("ProtectedAccounts/{id}/Members")]
[HttpGet]
public IHttpActionResult GetProtectedAccountMembers(int id)
{
var protectedAccount = db.ProtectedAccounts.Find(id);
if (protectedAccount == null)
{
return NotFound();
}
return Ok(protectedAccount.Members.ToList());
}
the data wich i receive for an GET seems to Loop recursive through all navigations:
[
{
"ProtectedAccount": {
"Members": [
{
"Id": 2,
"Name": "XXX, XX",
},
{
"Id": 3,
"Name": "XX, XX",
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXX",
},
"Id": 1,
"Name": "test",
},
{
"ProtectedAccount": {
"Members": [
{
"Id": 1,
"Name": "test",
},
{
"Id": 3,
"Name": "XX, XX",
"SamAccountName": "XX",
"Disabled": false
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXXX",
},
"Id": 2,
"Name": "XX, XX",
},
{
"ProtectedAccount": {a
"Members": [
{
"Id": 1,
"Name": "test",
"SamAccountName": "XXX",
"Disabled": false
},
{
"Id": 2,
"Name": "XX, XX",
"SamAccountName": "XX",
"Disabled": false
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXX",
},
"Id": 3,
"Name": "XX, XX",
}
]
There is only one "ProtectedAccount" in the database. DO i have to use DTO to overcome this issue? I tried some configuration via the json formatsettings but didnt get any better results.
From your code, you are only returing the protectedAccount.Members, hence you could do a projection query as below
var results = ctx.ProtectedAccountMembers
.Where(member => member.ProtectedAccount.Id == protectedAccount.Id)
.Select(member => new { member.Id, member.Name }).ToList();

JSON Deserialization C#

I'm trying to parse out some information I've retrieved from RottenTomatoes that's in a JSON format
{
"cast": [
{
"id": "162655641",
"name": "Tom Hanks",
"characters": [
"Woody"
]
},
{
"id": "162655909",
"name": "Tim Allen",
"characters": [
"Buzz Lightyear"
]
},
{
"id": "162655020",
"name": "Joan Cusack",
"characters": [
"Jessie the Cowgirl"
]
},
{
"id": "162672460",
"name": "Ned Beatty",
"characters": [
"Lots-o'-Huggin' Bear",
"Lotso"
]
},
{
"id": "162657445",
"name": "Richard Kind",
"characters": [
"Bookworm"
]
},
{
"id": "162654813",
"name": "Erik von Detten",
"characters": [
"Sid"
]
},
{
"id": "770713272",
"name": "James Anthony Cotton",
"characters": []
}
],
"links": {
"rel": "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122.json"
}
}
I'm just trying to get this code to work but I'm getting an InvalidOperationException and this error
"Type 'System.String' is not supported for deserialization of an array."
Here's my code in main
string json = File.ReadAllText("json.txt");
CastInfo castMember = new JavaScriptSerializer().Deserialize<CastInfo>(json);
Here are my classes
public class CastInfo
{
public List<CustomCastInfo> cast { get; set; }
}
public class CustomCastInfo
{
public string id { get; set; }
public string name { get; set; }
public List<string> characters { get; set; }
}
And advice? And I realize I need to do something about the "links" in the bottom, but even when I delete that it still doesn't work.
I just tried running this with the json you provided and it worked fine.
using System.Collections.Generic;
using System.IO;
using System.Web.Script.Serialization;
namespace JsonDeserialization
{
class Program
{
static void Main(string[] args)
{
string json = File.ReadAllText("json.txt");
CastInfo castMember = new JavaScriptSerializer().Deserialize<CastInfo>(json);
}
}
public class CastInfo
{
public List<CustomCastInfo> cast { get; set; }
}
public class CustomCastInfo
{
public string id { get; set; }
public string name { get; set; }
public List<string> characters { get; set; }
}
}

SerializationException: End element 'caption' from namespace '' expected

I'm trying to deserialize a json string and I'm getting the error End element 'caption' from namespace '' expected. Found element 'created_time' from namespace ''. when calling
InstagramObject test = (InstagramObject) instagramObject.ReadObject(instagramWebResponse.GetResponseStream());
The json from Instagram returns many elements but there are only a few that I need. My DataContract will be posted below.
Basically I need {data:[{caption: string, link: string, images: {...}}]}
Here's an example of the json...
{
"data": [{
"comments": {
"data": [],
"count": 0
},
"caption": {
"created_time": "1296710352",
"text": "Inside le truc #foodtruck",
"from": {
"username": "kevin",
"full_name": "Kevin Systrom",
"type": "user",
"id": "3"
},
"id": "26621408"
},
"likes": {
"count": 15,
"data": [{
"username": "mikeyk",
"full_name": "Mike Krieger",
"id": "4",
"profile_picture": "..."
}, {...subset of likers...}]
},
"link": "http://instagr.am/p/BWrVZ/",
"user": {
"username": "kevin",
"profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_3_75sq_1295574122.jpg",
"id": "3"
},
"created_time": "1296710327",
"images": {
"low_resolution": {
"url": "http://distillery.s3.amazonaws.com/media/2011/02/02/6ea7baea55774c5e81e7e3e1f6e791a7_6.jpg",
"width": 306,
"height": 306
},
"thumbnail": {
"url": "http://distillery.s3.amazonaws.com/media/2011/02/02/6ea7baea55774c5e81e7e3e1f6e791a7_5.jpg",
"width": 150,
"height": 150
},
"standard_resolution": {
"url": "http://distillery.s3.amazonaws.com/media/2011/02/02/6ea7baea55774c5e81e7e3e1f6e791a7_7.jpg",
"width": 612,
"height": 612
}
},
"type": "image",
"filter": "Earlybird",
"tags": ["foodtruck"],
"id": "22721881",
"location": {
"latitude": 37.778720183610183,
"longitude": -122.3962783813477,
"id": "520640",
"street_address": "",
"name": "Le Truc"
}
}]
}
and here's my DataContract...
[DataContract]
public class InstagramObject {
[DataMember(Name = "data")]
public IEnumerable<InstagramData> instagramData { get; set; }
}
[DataContract]
public class InstagramData {
[DataMember(Name = "images")]
public List<InstagramImage> instagramImages { get; set; }
[DataMember(Name = "caption")]
public string caption { get; set; }
[DataMember(Name = "link")]
public string link { get; set; }
}
[DataContract]
public class InstagramImage {
[DataMember(Name = "low_resolution")]
public InstagramImageInfo lowResolutionImage { get; set; }
[DataMember(Name = "thumbnail")]
public InstagramImageInfo thumbnail { get; set; }
[DataMember(Name = "standard_resolution")]
public InstagramImageInfo standardResolution { get; set; }
}
[DataContract]
public class InstagramImageInfo {
[DataMember(Name = "url")]
public string url { get; set; }
[DataMember(Name = "width")]
public int width { get; set; }
[DataMember(Name = "height")]
public int height { get; set; }
}
In the data contract caption is declared as a string, but in the JSON caption is a record with various fields - caption should be declared to be an object with a compatible structure:
[DataContract]
public class InstagramCaption {
[DataMember(Name = "text")]
public string Text {get; set;}
}
. . .
[DataMember(Name = "caption")]
public InstagramCaption caption { get; set; }
. . .
No need to declare those clases If you want to go with Json.Net + Linq
var obj = (JObject)JsonConvert.DeserializeObject(json);
var result = obj["data"]
.Select(x => new {
Caption = (string)x["caption"]["text"],
Link = (string)x["link"],
Images = x["images"].Children()
.Select(y=>(string)y.First()["url"]).ToArray()
})
.ToArray();

Categories