how to get data from json [duplicate] - c#

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
How do i parse json?
Please tell me the way to deserialize the json data in asp.net c#.
Actually I have a json data with two objects like:
{
"errstr": "All downloded vedios ",
"errcode": 0,
"result": {
"videos": [
{
"id": "22",
"name": "Ashley",
"price": "0.49",
"size": "3712310"
}
],
"trailer": [
{
"id": "1",
"trailer_name": "charl1",
"status": "1"
},
{
"id": "2",
"trailer_name": "charl2",
"status": "1"
}
]
}
}
Here I have two objects videos and trailer. Please tell me the process to get get these data in my code.

you need to create a class with nested members
for example json file
{
"GeminiURL":"https://gemini.com/Gemini"
,"Language":"en"
,"Log":{"Debug":true,"Info":true,"Warn":true,"FileName":"d:\\temp\\tfsgemini.log"}
}
is serializaed and deserialized with c# class
public class Settings
{
public string GeminiURL;
private LogSettings _log;
public LogSettings Log
{
get { return _log = _log ?? new LogSettings(); }
set { _log = value; }
}
public string Language;
public Settings()
{
// defaule settings can be assigned here;
}
}
public class LogSettings
{
public bool Debug;
public bool Info = true;
public bool Warn = true;
public string FileName;
}
and the deserialization code looks like:
public static T Load(string fileName)
{
T t = new T();
if (File.Exists(fileName))
t = (new JavaScriptSerializer()).Deserialize<T>(File.ReadAllText(fileName));
else
Save(t);
return t;
}

JSON .NET - http://json.codeplex.com/

Related

Deserialize xml list of objects

<ns2:dni>
<ns2:tipoDocumento>
<ns2:pais>
<ns2:codigo>COL</ns2:codigo>
<ns2:nombre>Colombia</ns2:nombre>
</ns2:pais>
<ns2:codigo>CC</ns2:codigo>
</ns2:tipoDocumento>
<ns2:numero>1144040396</ns2:numero>
<ns2:principal>true</ns2:principal>
<ns2:campoExtension>
<ns2:clave>CIUDAD_DCTO</ns2:clave>
<ns2:valor>76001</ns2:valor>
</ns2:campoExtension>
<ns2:campoExtension>
<ns2:clave>DEPARTAMENTO_DCTO</ns2:clave>
<ns2:valor>76</ns2:valor>
</ns2:campoExtension>
<ns2:campoExtension>
<ns2:clave>PAIS_DCTO</ns2:clave>
<ns2:valor>COL</ns2:valor>
</ns2:campoExtension>
<ns2:campoExtension>
<ns2:clave>LUGAR_EXPEDICION</ns2:clave>
<ns2:valor>CALI</ns2:valor>
</ns2:campoExtension>
</ns2:dni>
So im having problems deserializing this xml document so far i've managed to deserialize "tipoDocumento", "numero", and "principal" correctly, problem is when it reaches the "campoExtension" objects, as you can probably see they're not encapsulated in an object just for them and if i try to create a list in the model it stays empty after deserialization, this is what i get:
"dni": {
"tipoDocumento": {
"pais": {
"codigo": "COL",
"nombre": "Colombia"
},
"codigo": "CC"
},
"numero": "1144040396",
"principal": true,
"campoExtension": []
}
and yes it's a json because im turning it into a c# object so i can serialize with newstonsoft after. please help.
this is my Dni Class:
public class Dni
{
public TipoDocumento tipoDocumento;
public string numero;
public bool principal;
public CampoExtension[] campoExtension;
}
So i found the solution what i did was update my dni class to the following:
[XmlRoot("dni")]
public class Dni
{
public TipoDocumento tipoDocumento;
public string numero;
public bool principal;
[XmlElement("campoExtension")]
public List<CampoExtension> campoExtension;
}
now my json looks like this:
"dni": {
"tipoDocumento": {
"pais": {
"codigo": "COL",
"nombre": "Colombia"
},
"codigo": "CC"
},
"numero": "1144040396",
"principal": true,
"campoExtension": [
{
"clave": "CIUDAD_DCTO",
"valor": "76001"
},
{
"clave": "DEPARTAMENTO_DCTO",
"valor": "76"
},
{
"clave": "PAIS_DCTO",
"valor": "COL"
},
{
"clave": "LUGAR_EXPEDICION",
"valor": "CALI"
}
]
},

JSON converting into C# or classes [duplicate]

This question already has answers here:
How to auto-generate a C# class file from a JSON string [closed]
(3 answers)
Closed 4 years ago.
I have the following JSON (not the true data) in the following format, which I am trying to convert into C# equivalent classes. If you noticed that type_1, type_2 these could be in any numbers. which is difficult to put in collection(sort of anonymous). If i remove all type_1, type_2 ... from the JSON it is easy can be converted to classes. Since it in dynamic in nature it is making it difficult.
I have tried http://json2csharp.com/ to get the classes. Problem is, it converts "types" as members, which is not true, it should be a dynamic collection or an array.
This slight different problem
This question has 2 extra problems first "type_1" elements are dynamic and second is these are not in list or an array.
I don't have control over this JSON format which is extra frustration.
{
"type_1": {
"#type": "blob",
"content_type": "image/jpeg",
"digest": "sha1-rCY0Tk8qRqaLfiQXdxYeX9Y+WMI="
},
"type_2": {
"#type": "blob",
"content_type": "image/jpeg",
"digest": "sha1-rCY0Tk8qRqaLfiQXdxYeX9Y+WMI="
},
"type_3": {
"#type": "blob",
"content_type": "image/jpeg",
"digest": "sha1-rCY0Tk8qRqaLfiQXdxYeX9Y+WMI=",
},
"type_4": {
"#type": "blob",
"content_type": "image/jpeg",
"digest": "sha1-rCY0Tk8qRqaLfiQXdxYeX9Y+WMI=",
},
"type_5": {
"#type": "blob",
"content_type": "image/jpeg",
"digest": "sha1-rCY0Tk8qRqaLfiQXdxYeX9Y+WMI=",
},
"References": {
"blob_1": {
"content_type": "image/jpeg",
"digest": "sha1-rCY0Tk8qRqaLfiQXdxYeX9Y+WMI=",
"revpos": 1,
"stub": true
},
"blob_2": {
"content_type": "image/jpeg",
"digest": "sha1-rCY0Tk8qRqaLfiQXdxYeX9Y+WMI=",
"revpos": 1,
"stub": true
}
},
"someproperty1": "somevalue1",
"someproperty2": "somevalue2",
"someproperty3": "somevalue3",
"someproperty4": "somevalue4",
"someproperty5": "somevalue5"
}
I was thinking something like
Filecollection is nothing but that anonymous collection; no luck ;(
public partial class Doc
{
[JsonProperty("references")]
public Dictionary<String, Attachments> Attachments { get; set; }
public List<Dictionary<String, Details>> FileCollections { get; set; }
[JsonProperty("someproperty")]
public String someproperty { get; set; }
[JsonProperty("someproperty2")]
public String someproperty2 { get; set; }
[JsonProperty("someproperty3")]
public String someproperty3 { get; set; }
}
Based on your comments (hopefully, I understand it)...
{
"unknown_a" : {...},
"unknown_b" : {...},
"unknown_c" : {...},
"unknown_d" : {...},
"foo" : true, // known property
"bar" : { // known property
"x" : "xxx",
"y" : "yyy"
}
}
I'm thinking that you want a Dictionary<string, object>?
Then you can do a little bit of your own conversion magic --- for example (just to get the concept out there)
foreach (d in dictionary)
{
switch (d.Key)
{
case "foo": ... // known property
obj.Foo = (bool)d.Value;
break;
case "bar": ... // known property
obj.Bar = (Bar)d.Value;
break;
default: ... // according to your comments, these are known types
try
{
obj.Files.Add((File)d.Value);
}
catch {...}
break;
}
}

Change status value from int to string

I have a status property with int values in array of objects. Below is the output of array of objects.
[
{
"enterpriseServiceId": 1,
"enterpriseServices": {},
"status": 3,
"id": 1,
"createdOn": "2017-12-29T17:58:15.4855946",
"createdBy": "System",
"modifiedOn": "2017-12-29T17:58:15.4855946",
"modifiedBy": "System"
},
{
"enterpriseServiceId": 2,
"enterpriseServices": {},
"status": 1,
"id": 2,
"createdOn": "2017-12-29T17:58:15.4855946",
"createdBy": "System",
"modifiedOn": "2017-12-29T17:58:15.4855946",
"modifiedBy": "System"
}
]
The status property is enum value type. I am trying to convert that to string value so it is easier to read when it is returned in output.
Below is my code that gets the data from sql server database.
ENUM
namespace CoreLibrary.Models.Enums
{
public static class Common
{
public enum Status
{
Active = 1,
InActive,
Completed,
Failed,
InProgress,
Pause,
Resume,
Skip,
Running
}
}
}
Entity Model:
namespace CoreLibrary.Models.Entities
{
public class Deployments : BaseProperties
{
public int EnterpriseServiceId { get; set; }
[ForeignKey("EnterpriseServiceId")]
public virtual EnterpriseServices EnterpriseServices { get; set; }
public Common.Status Status { get; set; }
}
}
Method that retrieves data from database:
[HttpGet("~/api/Deployments/GetWithJoins")]
public JsonResult GetWithJoins()
{
try
{
// includeList for including data from external tables (JOIN Query)
var includeList = new List<Expression<Func<Deployments, object>>>();
includeList.Add(d => d.EnterpriseServices);
IEnumerable<Deployments> result = _repository.GetByIdWithJoins(queryable: includeList).ToList();
return Json(result);
}
catch (Exception ex)
{
var innerException = ex.InnerException == null ? null : ex.InnerException.Message.ToString();
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(new { status = "failed", message = ex.Message.ToString(), innerException = innerException });
}
}
The result variable returns the output I shared at very beginning of this post. I am trying to convert status to return string value instead of int.
I am not sure if thats even possible or it is the right way to output of status int to string value?
I tried online, but I havent found a solution to my requirement. I would appreciate any help you guys can give. :)
When we call JSON(someObject), ASP.NET uses its JavaScriptSerializer to create a JsonResult. The default configuration of the JavaScriptSerializer converts enums to their integer representation.
We can configure the serializer to use a string representation of enums instead. There are details on how to do that here: JSON serialization of enum as string
If that approach does not appeal, then you can use LINQ to map to an anonymous object using Enum.ToString(). Here is an example:
var result = deployments.Select(x =>
{
return new
{
Status = x.Status.ToString(),
x.EnterpriseServiceId
};
});
While the LINQ approach will work, it might lead to maintenance problems in the long-term.

How to parse non-key JSON to C# classes?

I get a Json data from url as follows. But as you see, there are no key names in Json.
For example, "Flame Towers" is place name value but there is no any key name. Likewise, "2017-02-10" is date value, "The Lego Batman Movie 2D" is film name value but it declared as key and ["10:10"] is an array consists film session times.
I tried many class structurs for deserialize it to C# classes using JsonConvert.DeserializeObject<ClassName>(jsonString);
But every time it returns a null object. Also tried parse manually with JObject class and it seemed to me very confused.
So, can anyone help for true class structure parsing with JsonConvert class?
{
{
"Flame Towers": {
"2017-02-10": {
"The Lego Batman Movie 2D": [
"10:10"
],
"Qatil 2D": [
"10:30"
],
"Fifty Shades Darker 2D": [
"10:30",
"11:40",
"12:50",
"14:00",
"15:10",
"16:20",
"17:30",
"18:40",
"19:50",
"21:00",
"22:10",
"23:20",
"00:30",
"01:40"
],
"John Wick: Chapter Two 2D": [
"11:00",
"12:10",
"13:20",
"14:30",
"15:40",
"16:50",
"18:00",
"20:20",
"21:30",
"22:40",
"23:50",
"01:00",
"02:10"
],
"The Lego Batman Movie 3D": [
"11:00",
"12:10",
"13:00",
"14:10",
"15:00",
"17:00",
"19:00"
],
"Ballerina 3D": [
"16:10"
],
"Rings 2D": [
"17:55"
],
"Ağanatiq 2D": [
"19:55"
],
"Resident Evil: The Final Chapter 3D": [
"21:40",
"21:00",
"23:50",
"01:10"
],
"The Great Wall 3D": [
"23:10"
]
}
},
"Metro Park": {
"2017-02-10": {
"John Wick: Chapter Two 2D": [
"10:30",
"12:50",
"15:10",
"17:30",
"19:50",
"22:10",
"00:30"
],
"Ağanatiq 2D": [
"10:00",
"11:50",
"13:40",
"15:30",
"17:20",
"19:10",
"21:00",
"23:00",
"00:50"
],
"The Lego Batman Movie 2D": [
"10:30"
],
"Fifty Shades Darker 2D": [
"11:00",
"13:20",
"15:40",
"18:00",
"20:20",
"02:00"
],
"Hoqqa 2D": [
"11:10",
"12:50",
"14:30",
"16:10",
"17:50",
"19:30",
"21:10",
"22:50",
"00:30",
"02:10"
],
"Naxox 2D": [
"11:20",
"13:10",
"15:00",
"16:50",
"18:40",
"20:30",
"22:20",
"00:10"
],
"The Lego Batman Movie 3D": [
"12:30",
"14:30",
"16:30",
"18:30"
],
"Ballerina 3D": [
"20:30"
],
"Resident Evil: The Final Chapter 3D": [
"22:40",
"00:50"
],
"The Great Wall 3D": [
"22:20",
"02:30"
],
"Притяжение 3D": [
"00:20"
]
}
}
}
}
There is a simple, hacky and speedy way of doing this. Just cut the first and the last { } symbols from the string before serializing.
if (jsonString.StartsWith("{{") && jsonString.EndsWith("}}"))
jsonString = jsonString.Substring(2, jsonString.Length - 4);
JsonConvert.DeserializeObject<ClassName>(jsonString);
It looks like data from a collection of movie theatres and their active shows where the top item "Flame Towers" are the name of the cinema, the "2017-02-10" is the date and under is each show/movie and then their "display" time.
Knowing this, you can create a data structure that matches this.
... Something like this perhaps?
public class Movie : IEnumerable<TimeSpan>
{
public Movie(string name, IReadOnlyList<TimeSpan> runTimes)
{
this.Name = name;
this.RunTimes = runTimes;
}
public string Name { get; }
public IReadOnlyList<TimeSpan> RunTimes { get; }
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<TimeSpan> GetEnumerator()
{
return RunTimes.GetEnumerator();
}
public override string ToString()
{
return "[Movie] " + Name;
}
public static Movie Parse(JProperty data)
{
var name = data.Name;
var runTimes = new List<TimeSpan>();
foreach (var child in data.Values())
{
runTimes.Add(TimeSpan.Parse(child.Value<string>()));
}
return new Movie(name, runTimes);
}
}
public class MovieCollectionDate : IEnumerable<Movie>
{
public MovieCollectionDate(DateTime date, IReadOnlyList<Movie> movies)
{
this.Date = date;
this.Movies = movies;
}
public DateTime Date { get; }
public IReadOnlyList<Movie> Movies { get; }
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<Movie> GetEnumerator()
{
return this.Movies.GetEnumerator();
}
public override string ToString()
{
return "[Date] " + Date + " - " + Movies.Count + " show(s)";
}
public static MovieCollectionDate Parse(JProperty data)
{
var date = DateTime.Parse(data.Name);
var movies = new List<Movie>();
foreach (var upperChild in data.Children<JObject>())
{
foreach (var child in upperChild.Children())
{
movies.Add(Movie.Parse(child as JProperty));
}
}
return new MovieCollectionDate(date, movies);
}
}
public class MovieTheatre : IEnumerable<MovieCollectionDate>
{
public MovieTheatre(string name, IReadOnlyList<MovieCollectionDate> dateAndMovies)
{
this.Name = name;
this.DateAndMovies = dateAndMovies;
}
public string Name { get; }
public IReadOnlyList<MovieCollectionDate> DateAndMovies { get; }
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<MovieCollectionDate> GetEnumerator()
{
return this.DateAndMovies.GetEnumerator();
}
public override string ToString()
{
return "[Theatre] " + Name + " - " + DateAndMovies.Count + " open day(s)";
}
public static MovieTheatre Parse(JProperty data)
{
var name = data.Name;
var movieCollectionDates = new List<MovieCollectionDate>();
foreach (var upperChild in data.Children<JObject>())
{
foreach (var child in upperChild.Children())
{
movieCollectionDates.Add(MovieCollectionDate.Parse(child as JProperty));
}
}
return new MovieTheatre(name, movieCollectionDates);
}
}
public class MovieTheatreCollection : IEnumerable<MovieTheatre>
{
public MovieTheatreCollection(IReadOnlyList<MovieTheatre> movieTheatres)
{
this.MovieTheatres = movieTheatres;
}
public IReadOnlyList<MovieTheatre> MovieTheatres { get; }
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<MovieTheatre> GetEnumerator()
{
return this.MovieTheatres.GetEnumerator();
}
public override string ToString()
{
return "MovieTheatreCollection: Containing " + MovieTheatres.Count + " movie theatre(s)";
}
public static MovieTheatreCollection Parse(JObject data)
{
var theatres = new List<MovieTheatre>();
foreach (var child in data.Children().Cast<JProperty>())
{
theatres.Add(MovieTheatre.Parse(child));
}
return new MovieTheatreCollection(theatres);
}
}
this is obviously not the most elegant way of solving the problem. But seeing as this "key-less" json wouldnt just Deserialize properly without some sort of hack. Creating a data structure that matches your needs (more manual work unfortunately) will at least work ;)
You can use the code above with the following code:
JObject obj = JObject.Parse(... the json string you had above ...)
MovieTheatreCollection movieTheatres = MovieTheatreCollection.Parse(obj);
foreach (var movieTheatre in movieTheatres)
{
Console.WriteLine(movieTheatre);
foreach (var openDay in movieTheatre)
{
Console.WriteLine(" " + openDay);
foreach (var movie in openDay)
{
Console.WriteLine(" " + movie);
foreach (var runtime in movie) Console.WriteLine(" - " + runtime);
}
}
}
Finally, just like 'Just Shadow' mentioned in the answer above, the json is malformed and contains extra curly brackets that needs to be removed or the object wont parse properly.
An ugly, but reasonably compact way to parse this would be:
static void Main(string[] args)
{
var jo = JObject.Parse(File.ReadAllText("data.json").Trim('{').Trim('}'));
foreach (var place in jo)
{
Console.WriteLine($"Place: {place.Key}");
foreach (var dateOrMovie in place.Value.Children<JProperty>())
{
Console.WriteLine($"\tDate: {dateOrMovie.Name}");
var movies = dateOrMovie.Children<JObject>().First().Children<JProperty>();
foreach (var movie in movies)
{
Console.WriteLine($"\t\t{movie.Name}");
foreach (JValue time in movie.Children<JArray>().First())
{
Console.WriteLine($"\t\t\t{time.Value}");
}
}
}
}
}

How to update a nested document in a mongodb with c#

I hope someone can help me to understand how I can update a document in a mongodb.
My problem is that i have a document which contains an array. And in this array there are objects with a specific ID(like you would find in sql database). Now I want to update the data inside those objects if they have the searched id.
A document looks like this
{
"_id": "63dafa72f21d48312d8ca405",
"tasks": [{
"_ref": "63d8d8d01beb0b606314e322",
"data": {
"values": [{
"key": "Deadline",
"value": "2014-10-13"
}]
}
}, {
"_ref": "84dd046c6695e32322d842f5",
"data": {
"values": []
}
}]
}
I did write the method updateProject
public bool updateProject(Project pro, Project dbPro)
{
var collection = db.GetCollection<BsonDocument>("projects");
var filter = Builders<BsonDocument>.Filter.Eq("_id", dbPro.Id);
var update = Builders<BsonDocument>.Update.Set("tasks", pro.Tasks);
var result = collection.UpdateOne(filter, update);
if (result.IsModifiedCountAvailable)
{
if (result.ModifiedCount == 1)
{
return true;
}
}
return false;
}
And thats how a project does look like in c#.
class Project{
public string id;
public List<Task> Tasks;
}
class Task{
public string id;
public List<Value> Values;
}
class Value{
public String key;
public String value;
}
but i cant figure out how i can go deeper to find the searched id.

Categories