Json.NET and name/value array serialization - json

Is there a way to serialize the attributes property below with a name/value property in .NET? I can't seem to find a good way to serialize the class to the attributes property with values like, sport, venue, city, province, and others.
{
"uid": "uuid",
"object": "live_event",
"title": "Event Name",
"event_start": "2022-10-10T12:00:00:000Z",
"timezone": "America/Denver",
"external_id": "some_external_user_generated_id",
"container_uid": "02f8270a-8662-45b3-898a-c915a68cdf87",
"description": "Description of the event",
"short_description": "Short description of the event",
"attributes": [
{ "sport": "Soccer" },
{ "venue": "New Park" },
{ "city": "Calgary" },
{ "province": "Alberta" },
{ "teams": ["teamA", "teamB"] }
]
}
Class
public class CreateEventRequest : VidFlexRequest, ISaveEventRequest
{
[JsonProperty("uid", NullValueHandling = NullValueHandling.Ignore)]
public string UId { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("event_start")]
public string EventStart { get; set; }
[JsonProperty("timezone")]
public string TimeZone { get; set; }
[JsonProperty("external_id")]
public string ExternalId { get; set; }
[JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
public string Description { get; set; }
[JsonProperty("short_description", NullValueHandling = NullValueHandling.Ignore)]
public string ShortDescription { get; set; }
}

The easiest ( but not the best) way would be define your attributes property
as
[JsonProperty("attributes")]
public Dictionary<string,object>[] Attributes { get; set; }
the better way is to use JsonConstructor
public class CreateEventRequest
{
[JsonProperty("uid", NullValueHandling = NullValueHandling.Ignore)]
public string UId { get; set; }
.....
public List <KeyValuePair<string,object>> Attributes { get; set; }
[JsonConstructor]
public CreateEventRequest(JArray attributes)
{
Attributes= attributes.Select(a => new KeyValuePair<string, object>(
((JObject)a).Properties().First().Name,((JObject)a).Properties().First().Value )).ToList();
}
}

Related

Parsing json to generic list in C#

I have Json Like value name pair. I need to convert to Generic list.
{
"options": {
"32": "S",
"4": "SM",
"33": "M",
"34": "L",
"35": "XL",
"37": "XXL",
"38": "XXXL"
}
}
My class like
public class Options
{
public int optionId { get; set; }
public string OptionName { get; set; }
}
How to convert json to List<Options>
First convert your json to Dictionary<string, string> and then convert it to your model like this:
public class OptionDictionary
{
public Dictionary<string, string> Options { get; set; }
}
public class Options
{
public int OptionId { get; set; }
public string OptionName { get; set; }
}
var list = JsonConvert.DeserializeObject<OptionDictionary>(json).Options.Select(x=>new Options(){OptionId = int.Parse(x.Key), OptionName = x.Value}).ToList();

Nullable reference in JSON does noet become null when PUT request

I am making a rest API on my exercise, and I have chosen for a very simple approach, I have three entities: Chapter, Theme, Priority. One chapter may have 0 or 1 theme and 0 or 1 priority.
So they are looking like this in JSON format.
CHAPTER:
{
"id": 4,
"title": "De centrale limietstelling",
"isFinished": false,
"priority": {
"id": 1,
"title": "Zeer belangerijk zeker instuderen",
"color": "#F1128D"
},
"theme": {
"id": 1,
"title": "Onderzoekstechnieken"
},
"date": null
}
THEME:
{
"id": 2,
"title": "Ontwerpen 3"
}
PRIORITY:
{
"id": 1,
"title": "Zeer belangerijk zeker instuderen",
"color": "#F1128D"
}
I can delete priority and then in the Chapter the priorities of this id are set to null as expected.
but when i edit any chapter with PUT request and set for example Theme to null:
{
"id": 4,
"title": "De centrale limietstelling",
"isFinished": false,
"priority": null,
"theme": null,
"date": null
}
have a 204 responce.
but when i open these chapter again i see that priority and theme are not set to null, but remain th e same as it was.
to clarify my entities these are the code of chapter, theme and prio:
public class Chapter
{
public int Id { get; set; }
public string Title { get; set; }
public bool IsFinished { get; set; }
public Priority? Priority { get; set; }
public Theme? Theme { get; set; }
public DateTime? Date { get; set; }
public Chapter()
{
IsFinished = false;
}
}
public class Theme
{
public int Id { get; set; }
public string Title { get; set; }
}
public class Priority
{
public int Id { get; set; }
public string Title { get; set; }
public string Color { get; set; }
}
I Also need to make use of DTO:
public class ChapterDTO
{
[Required]
public string Title { get; set; }
public Priority? Priority { get; set; }
public Theme? Theme { get; set; }
[DataType(DataType.Date)]
public DateTime? Date { get; set; }
public ChapterDTO()
{
}
}
public class PriorityDTO
{
[Required]
public string Title { get; set; }
public string Color { get; set; }
}
public class ThemeDTO
{
[Required]
public string Title { get; set; }
}
And this is my mapping to DB
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Chapter>().HasOne(e => e.Priority).WithMany().OnDelete(DeleteBehavior.SetNull).IsRequired(false);
builder.Entity<Chapter>().HasOne(e => e.Theme).WithMany().OnDelete(DeleteBehavior.SetNull).IsRequired(false);
}
how do I make it possible to store the null reference to theme and subject in Chapter?
Kind regard, ilya

Why can't my .NET Core controller parse my JSON?

So in my angular frontend I am sending this JSON to my backend.
[
{
"AccountingDate": 20171130,
"RegistrationNo": 3951,
"IDKT": "34HS991016",
"OriginalIDKT": "test",
"CounterAccountIDKT": "34HS980876",
"Text": "006-Hest prov-Ytd NOV17",
"ProjectCode": "078",
"Currency": "DKK",
"Balance": 1
},
{
"AccountingDate": 20171130,
"RegistrationNo": 3951,
"IDKT": "34JR991016",
"OriginalIDKT": "test",
"CounterAccountIDKT": "34JR980876",
"Text": "006-Hest prov-Ytd NOV18",
"ProjectCode": "078",
"Currency": "DKK",
"Balance": 1
}
]
My .NET Core controller method looks like the following:
[HttpPost]
public IActionResult Post([FromBody] AccountBookKeeping[] request)
{
return Ok(request);
}
But when debugging the request object will be null. This is my problem.
My AccountBookKeeping model looks like:
using System;
namespace GFSUploadAPI
{
public class AccountBookKeeping
{
public int AccountingDate { get; set; }
public string RegistrationNo { get; set; }
public string Currency { get; set; }
public string IDKT { get; set; }
public string OriginalIDKT { get; set; }
public string CounterAccountIDKT { get; set; }
public string ProjectCode { get; set; }
public float Balance { get; set; }
public string Text { get; set; }
}
}

Xamarin Refit - Newtonsoft.Json.JsonSerializationException

I have some problems with JSON Serialization.
When I try to deserialize my JSON Object, it returns me this error :
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Project.Models.BookModel' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
My problem here is that I have to deserialize my object in two different ways : In a JSON array(e.g.[1,2,3]) to extract "_id", "user" and "name", and then in a JSON array(e.g.["name":"value"]) to extract "books". And I don't know how to do it. Or more precisely, I don't know if it's posible with Refit.
Here is my JSON :
[
{
"_id": "5c014a1e43b6804ed7b642b2",
"__v": 0,
"user": "5c014a1d43b6804ed7b642b1",
"name": "Favoris",
"books": [
{
"_id": "5a8f12e16a16fa06d1f5b0cb",
"title": "Harry Potter et la Chambre des Secrets",
"author": {
"_id": "5a8f12e16a16fa06d1f5b0bd",
"name": "J K Rowling",
"__v": 0
},
"literaryGenre": "Juvenile Fiction",
"isbn": 9781781101049,
"externalImage": "...",
"__v": 0,
"content": {
"brief": "test1"
}
},
{
"_id": "5a8f12e16a16fa06d1f5b0d0",
"title": "Harry Potter et la Coupe de Feu",
"author": {
"_id": "5a8f12e16a16fa06d1f5b0bd",
"name": "J K Rowling",
"__v": 0
},
"literaryGenre": "Juvenile Fiction",
"isbn": 9781781101063,
"externalImage": "...",
"__v": 0,
"content": {
"brief": "test2"
}
}
]
}
]
Here is my code :
public async void ViewLibrary()
{
IProjectApi response = ProjectRepository.Instance.ProjectApi;
List<LibraryModel> library = await response.GetLibrary("5c014a1d43b6804ed7b642b1");
this.LibraryItems = library;
}
And my object LibraryModel :
public class LibraryModel
{
public string _id { get; set; }
public string user { get; set; }
public string name { get; set; }
public BookModel books { get; set; }
}
And my method GetLibrary :
[Get("/api/library/user/{UserId}")]
Task<List<LibraryModel>> GetLibrary(string UserId);
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
'Project.Models.BookModel' because the type requires a JSON object
(e.g. {"name":"value"})
In json result your BookModel returning multiple records, so it should be defined as List<BookModel>.
In LibraryModel try using public List<BookModel> books { get; set; }.
Implement these classes anywhere in your code and try to deserialize your json with these classes.
public class Author
{
public string _id { get; set; }
public string name { get; set; }
public int __v { get; set; }
}
public class Content
{
public string brief { get; set; }
}
public class Book
{
public string _id { get; set; }
public string title { get; set; }
public Author author { get; set; }
public string literaryGenre { get; set; }
public object isbn { get; set; }
public string externalImage { get; set; }
public int __v { get; set; }
public Content content { get; set; }
}
public class RootObject
{
public string _id { get; set; }
public int __v { get; set; }
public string user { get; set; }
public string name { get; set; }
public List<Book> books { get; set; }
}

Trouble deserializing Json from REST service

I'm having the hardest time deserializing a json string.
I was using the RestSharp api which worked great if I specified the RootElement on the request. I then moved to Hammock for the OAuth functionality, but the deserialization isn't working so easily.
I've tried using DataContractJsonSerializer
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List));
var member = (List)ser.ReadObject(response.ContentStream);
but this gives me an InvalidCastException.
I tried JsonConvert
var members = JsonConvert.DeserializeObject<List<Member>>(response.Content);
but I get the exception: Cannot deserialize JSON object into type 'System.Collections.Generic.List`1[Member]'.
RestSharp took care of this easily when calling ExecuteAsync. Client.ExecuteAsync<List<Member>>(request, (response) =>
I'm at my wits end. Maybe I need a Hammock equivalent to RestSharp's RootElement property?? Is it just that my Json is difficult to convert?
Here is my Member object
public partial class Member
{
public string State { get; set; }
public string Joined { get; set; }
public string lat { get; set; }
public string Zip { get; set; }
public string Bio { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string Id { get; set; }
public string Link { get; set; }
public string Country { get; set; }
public string Visited { get; set; }
public string Photo_url { get; set; }
public string lon { get; set; }
}
here is the Json:
{
"results": [
{
"zip": "11111",
"lon": "-122.22000122070312",
"photo_url": "http: //photos1.aaaaa.com/photos/member/1/6/c/e/member_4469838.jpeg",
"link": "http: //www.aaaa.com/members/7804365",
"state": "AA",
"lang": "en_US",
"city": "MyCity",
"country": "us",
"id": "7804365",
"visited": "Sat Feb 19 02: 36: 40 EST 2011",
"topics": [
{
"id": 3340,
"urlkey": "pickupsoccer",
"name": "Pick-up Soccer"
},
{
"id": 468,
"urlkey": "dads",
"name": "Dads"
},
{
"id": 20557,
"urlkey": "coed-soccer",
"name": "Coed Soccer"
},
{
"id": 148421,
"urlkey": "windowsphone",
"name": "Windows Phone"
}
],
"joined": "Thu Aug 07 15: 32: 06 EDT 2008",
"bio": "",
"name": "aaa bbbb",
"other_services": {
"linkedin": {
"identifier": "http: //www.bbb.com/in/zzzzz"
}
},
"lat": "47.790000915527344"
}
],
"meta": {
"lon": "",
"count": 1,
"link": "https: //api.aaaaa.com/members",
"next": "",
"total_count": 1,
"url": "https: //api.aaaaa.com/members?relation=self&order=name&offset=0&format=json&page=800",
"id": "",
"title": "Members",
"updated": "Fri Sep 10 13: 08: 07 EDT 2010",
"description": "API method",
"method": "Members",
"lat": ""
}
}
UPDATE
Adding a wrapper object for my Member class that encapsulates the entire json result fixed this.
public partial class Members
{
public List<Member> results { get; set; }
public object meta { get; set; }
}
Then I can can deserialize using the following:
var members = JsonConvert.DeserializeObject<Members>(jsonstring);
There are about three problem areas in your JSON data:
The way it is presented here, it contains a lot of backslashes and double quotes at the beginnging and end that don't work in JSON. It's difficult to tell from your question whether this is an artifact of copying it from the VisualStudio debugger or is really a problem in the data.
The transmitted data is not a list of Member instance but rather an object containing both a list of member instances and some additional meta information. So you need to introduce an additional class with a the two members results and meta.
Your class Member uses properties starting with an uppercase letter while the JSON data uses all lowercase letters. You can either change the property names or uses data DataMember annoation:
So the solution could be:
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(JsonResponse));
JsonResponse jsonResponse = (JsonResponse)ser.ReadObject(response.ContentStream);
with the following class definitions:
[DataContract]
public partial class Member
{
[DataMember(Name = "state")]
public string State { get; set; }
[DataMember(Name = "joined")]
public string Joined { get; set; }
[DataMember(Name = "lat")]
public string Lat { get; set; }
[DataMember(Name = "zip")]
public string Zip { get; set; }
[DataMember(Name = "bio")]
public string Bio { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "state")]
public string City { get; set; }
[DataMember(Name = "city")]
public string Id { get; set; }
[DataMember(Name = "link")]
public string Link { get; set; }
[DataMember(Name = "country")]
public string Country { get; set; }
[DataMember(Name = "visited")]
public string Visited { get; set; }
[DataMember(Name = "photo_url")]
public string PhotoUrl { get; set; }
[DataMember(Name = "lon")]
public string Lon { get; set; }
}
[DataContract]
public class Meta
{
[DataMember(Name = "lon")]
public string Lon { get; set; }
[DataMember(Name = "count")]
public int Count { get; set; }
[DataMember(Name = "link")]
public string Link { get; set; }
[DataMember(Name = "next")]
public string Next { get; set; }
[DataMember(Name = "total_count")]
public int TotalCount { get; set; }
}
[DataContract]
public class JsonResponse
{
[DataMember(Name = "results")]
public List<Member> Results { get; set; }
[DataMember(Name = "meta")]
public Meta Meta { get; set; }
}
In our project we r using Hammok for this, you can try to modify your class like this:
[DataContract]
public partial class Member
{
[DataMember(Name="zip")]
public string Zip { get; set; }
[DataMember(Name="photo_url")]
public string Photo_url { get; set; }
//Etc.
}
try using Json.net.
i found DataContractJsonSerializer too fetureless.
json.net provides great functionality.
it can be found at this link
http://json.codeplex.com/
it contains the .dll files and documentatio as well.
for web Documentation
http://james.newtonking.com/projects/json/help/