I have been given a JSON definition something along the lines of..
{
"the.data" : {
"first.name": "Joe",
"last.name": "Smith"
}
}
and i've made a class in c# to add my data too, such as
public class TheData
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class RootObject
{
public TheData TheData { get; set; }
}
Now the web service that i have to send this payload to, is expecting The.Data, and First.Name, as well as Last.Name
How can i 'change' the name definitions? Before transmitting?
Can i somehow override the name?
You can try this. you can use JsonPropertyAttribute to tell Json.Net what the property's corresponding json field is.
public class TheData
{
[JsonProperty("first.name")]
public string FirstName { get; set; }
[JsonProperty("last.name")]
public string LastName { get; set; }
}
public class RootObject
{
[JsonProperty("the.data")]
public TheData TheData { get; set; }
}
You can decorate the values, it will depend on which framework you're using but it'll be something like this:
[JsonProperty(PropertyName = "Person.Name")]
public string PersonName { get; set; }
Related
I'm querying an external service and wanted to deserialize the response into a customer object but the issue is response for each customer may be different. some customer may have Sales entity in the response and few may have Marketing.
The json property for sales entity is SalesId and for marketing is MarketingId. Can you advise whether the model I use to store result is correct or any improvement ? If so, how would I deserialize the response without knowing the correct json property ?
For Customer 66666
{
"customerId": "66666",
"customerName": "test1234",
"dependentEntity": [
{
"SalesId": "3433434",
"SalesPersonName": "343434",
"SaleSource": "StorePurchase"
}
]
}
For Customer 5555
{
"customerId": "55555",
"customerName": "test2",
"dependentEntity": [
{
"MarketingId": "3433434",
"MarketingAppName": "343434",
"MarketingSource": "Online"
}
]
}
Here is the Model I'm thinking but not sure the correct one
public class Customer
{
public string customerId { get; set; }
public string customerName { get; set; }
public IList<T> dependentList { get; set; }
}
public class Dependent
{
[JsonProperty("Id")]
public string Id { get; set; }
public string Name { get; set; }
public string Source { get; set; }
}
You could probably try something like the following one:
public class DependentEntity
{
[JsonProperty("SalesId")]
public string SalesId { get; set; }
[JsonProperty("SalesPersonName")]
public string SalesPersonName { get; set; }
[JsonProperty("SaleSource")]
public string SaleSource { get; set; }
[JsonProperty("MarketingId")]
public string MarketingId { get; set; }
[JsonProperty("MarketingAppName")]
public string MarketingAppName { get; set; }
[JsonProperty("MarketingSource")]
public string MarketingSource { get; set; }
}
public class Customer
{
[JsonProperty("customerId")]
public string CustomerId { get; set; }
[JsonProperty("customerName")]
public string CustomerName { get; set; }
[JsonProperty("dependentEntity")]
public IList<DependentEntity> DependentEntity { get; set; }
}
We have a type for DependentEntity that has both the attributes of Marketing and Sales object. After parsing your input, you could create a logic (checking the attributes) based on which you could check if a DependentEntity is a Marketing or a Sales object.
The above classes was generated using, jsonutils.
If we can assume that the dependentEntity contains only a single type of objects then you can use json.net's schema to perform branching based on the matching schema.
So, lets suppose you have these dependent entity definitions:
public class DependentMarket
{
public string MarketingId { get; set; }
public string MarketingAppName { get; set; }
public string MarketingSource { get; set; }
}
public class DependentSales
{
public string SalesId { get; set; }
public string SalesPersonName { get; set; }
[JsonProperty("SaleSource")]
public string SalesSource { get; set; }
}
...
Then you can use these classes to generate json schemas dynamically:
private static JSchema marketSchema;
private static JSchema salesSchema;
//...
var generator = new JSchemaGenerator();
marketSchema = generator.Generate(typeof(DependentMarket));
salesSchema = generator.Generate(typeof(DependentSales));
And finally you can do the branching like this:
var json = "...";
var semiParsedJson = JObject.Parse(json);
JArray dependentEntities = (JArray)semiParsedJson["dependentEntity"];
JObject probeEntity = (JObject)dependentEntities.First();
if (probeEntity.IsValid(marketSchema))
{
var marketEntities = dependentEntities.ToObject<List<DependentMarket>>();
...
}
else if (probeEntity.IsValid(salesSchema))
{
var salesEntities = dependentEntities.ToObject<List<DependentSales>>();
...
}
else if ...
else
{
throw new NotSupportedException("The provided json format is not supported");
}
i have a HTTPclient and im sending request to a Server.
The response from the server is a JSON. In this Json is also an array.
I want do display the information from the JSON in the consol.
I get all information from the JSON, but i dont get the array displayed in my console.
The JSON looks like this:
{
"Name1": "Karl",
"Name2": "Peter",
"Name3": "Wilhelm",
"PreNames": {
"PreName": "Werner",
"PreName2": "Josef"
}
}
So now my Code so far:
public class PreNames //for Array
{
public string PreName { get; set; }
public string PreName2{ get; set; }
}
public class Names//for JSON
{
public string Name1{ get; set; }
public string Name2{ get; set; }
public string Name3{ get; set; }
}
And my Main:
if (Response().IsSuccessStatusCode)
{
var namesJ= Response().Content.ReadAsAsync<IEnumerable<Names>>().Result;
var preNamesJ= await Response().Content.ReadAsAsync<List<PreNames>>();
foreach (var a in namesJ)
{
Console.WriteLine("Name1: {0}", a.Name1);
foreach(var b in preNamesJ)
{
Console.WriteLine("{0}", b.PreName);
}
}
So in the console are all names displayed, but not the PreNames so i cant get the PreNames from the array in the JSON...
I Hope somebody could help me :)
Add the PreNames property to your Names class and only read one time.
public class Names//for JSON
{
public string Name1{ get; set; }
public string Name2{ get; set; }
public string Name3{ get; set; }
public List<PreNames> PreNames { get; set;}
}
Once you read in the result one time, you can access the elements via the main object
var namesJ= Response().Content.ReadAsAsync<Names>().Result;
foreach(var names in namesJ.PreNames)
{
Console.WriteLine(names.PreName);
}
updated
Since you changed the json and made PreNames just an object instead of an array, simply access the property of related object.
public class Names//for JSON
{
public string Name1{ get; set; }
public string Name2{ get; set; }
public string Name3{ get; set; }
public PreNames PreNames { get; set;}
}
var namesJ= Response().Content.ReadAsAsync<Names>().Result;
Console.WriteLine(namesJ.PreNames.Name);
#Leonc443, Here is a working code
using Newtonsoft.Json; //add this nuget package
using System;
namespace ConsoleApp
{
class Program
{
public static void Main(string[] args)
{
string json = #"{
'Name1': 'Karl',
'Name2': 'Peter',
'Name3': 'Wilhelm',
'PreNames': {
'PreName': 'Werner',
'PreName2': 'Josef'
}
}"; // data received from api
var names = JsonConvert.DeserializeObject<Names>(json);
Console.WriteLine(names.Name1); // Karl
Console.WriteLine(names.Name2); //Peter
Console.WriteLine(names.Name3); //Wilhelm
Console.WriteLine(names.PreNames.PreName); //Werner
Console.WriteLine(names.PreNames.PreName2); // Josef
}
}
public class Names
{
public string Name1 { get; set; }
public string Name2 { get; set; }
public string Name3 { get; set; }
public PreNames PreNames { get; set; }
}
public class PreNames
{
public string PreName { get; set; }
public string PreName2 { get; set; }
}
}
Please let me know if this helps
In case your Json looks like:
{
"Name1": "Karl",
"Name2": "Peter",
"Name3": "Wilhelm",
"PreNames": {
"PreName": "Werner",
"PreName2": "Josef"
}
}
If the PreNames are in the Names, you shuld add a PreNames field to the Names Class.
public class Names
{
public string Name1 { get; set; }
public string Name2 { get; set; }
public string Name3 { get; set; }
public PreNames PreNames { get; set; }
}
Then you can read the inner PreNames:
foreach (var b in a.Prenames) {
Console.WriteLine(b.PreName);
}
But I'm not sure if I understand your question.
I don't have sufficient reputation to comment, so... I'll give it a try.
Edited after proper json updated in Answer.
Change your class Names
public class Names
{
public string Name1 { get; set; }
public string Name2 { get; set; }
public string Name3 { get; set; }
public PreNames PreNames { get; set; }
}
Then deserialize it with JsonConvert
var json = await Response().Content.ReadAsStringAsync();
var names = JsonConvert.DeserializeObject<Names>(json);
Then access data
Console.WriteLine($"Name 1: {names.Name1}");
Console.WriteLine($"Prename 1: {names.PreNames.PreName}");
I have a simple JSON like this:
{
"id": 123,
"name": "BaseName",
"variation": { "name": "VariationName" }
}
Is there a simple way to map it with JSON.NET deserialization to:
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string VariationName { get; set; }
}
I can probably do it with a custom converter, but I hoped there would be a simpler way by annotating the class with attributes which would give instructions to deserialize the variation object just using the one property.
You could set up a class for variation and make VariationName a get-only property
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public Variation variation { get; set; }
public string VariationName { get { return variation.VariationName; } }
}
class variation
{
public string name { get; set; }
}
I have to write a WCF webservice in dot net in nested Json structured below. I know how to write simple json but not sure to make it nested for `results
{
"version": 2,
"results": [{
"company": "ABC Company Inc.",
"city": "Sacramento",
"state": "CA"
}
]
}
What I am doing is :
file1.cs
namespace Test
{
public class file1
{
public class child
{
[DataMember]
public string version { get; set; }
}
public class parent
{
[DataMember]
public string company { get; set; }
[DataMember]
public string city { get; set; }
}
}
}
In file2.svc.cs
public List<file1> method()
{
List<file1.child> result = new List<file1.child>();
List<file1.parent> result1 = new List<file1.parent>();
List<file1> final = new List<file1>();
foreach (DataRow catt1 in dtcategory.Rows)
{
result.Add(new file1.child()
{
version= catt1["version"].ToString(),
});
result1.Add(new file1.parent() {
company= catt1["company"].ToString(),
city= catt1["city"].ToString(),
});
final.Add(new file1()
{
});
}
return Add;
}
Please let me where I am going wrong
Class Structure:
public class class1
{
[DataMember]
public string version {get;set;}
[DataMember]
public List<class2> results {get;set;}
}
public class class2
{
[DataMember]
public string company {get;set;}
[DataMember]
public string city{get;set;}
[DataMember]
public string state {get;set;}
}
Your question is sort of unclear. However, if you are asking "how can I design my classes file1.child and file1.parent so that, when serialized by DataContractJsonSerializer or Json.NET, they produce the JSON shown", then you can do:
public class file1
{
[DataContract]
public class child
{
[DataMember(Name="version")]
public string Version { get; set; }
[DataMember(Name="results")]
public List<parent> Results { get; set; }
}
[DataContract]
public class parent
{
[DataMember(Name="company")]
public string Company { get; set; }
[DataMember(Name="city")]
public string City { get; set; }
[DataMember(Name="state")]
public string State { get; set; }
}
}
Note that, given your class names, parent is contained inside child, which is counterintuitive. You might want to change those names.
My Goal:
Read JSON from site, get values of certain items and display them, after I successfully
pull that off I will want to implement taking in a value like true and set it to false.
For starters I need help figuring out how to read and write the variables. I have read
lots of tutorials and blogs about how to read in the data and parse it but what isn't
explained is where is the value stored?
Like I have this http://elsite.com/.json and it has this:
{
dola: "p9", data:{
house: [{
dola: "p9", data:{
owner: "blah", // string
price: blah, // int
url: "http://www.link.com", // url/string
message: "blahblah",
checked: false
}
},
{
dola: "p9", data:{
owner: "blah", // same as above
I have built this to get the data:
[DataContract]
class container
{
[DataMember(Name = "data")]
public Data1 dataStart { get; set; }
[DataContract]
public class Data1
{
[DataMember(Name = "house")]
public HouseA[] home { get; set; }
[DataContract]
public class HouseA
{
[DataMember(Name = "data")]
public Data2 dataSec { get; set; }
[DataContract]
public class Data2
{
[DataMember(Name = "owner")]
public string own { get; set }
[DataMember(Name = "message")]
public strinng mess { get; set; }
}
}
}
}
I want to use
var blah = from post in container.dataStart.house.data // obviously not the right way to do it
select new MessageItem
{
User = post.own,
Meza = post.mess
}
with
public class MessageItem
{
public string User;
public string Meza;
}
So basically it boils down to I am not COMPLETELY understanding the structure of the arrays and objects.
Anyone able to guide me in the right way to do the from.in.select?
Have you looked at Json.NET http://json.codeplex.com/ which includes LINQ to JSON support
I prefer JavaScriptSerializer (System.Web.Extensions.dll) for this; the following works:
JsonResult obj = new JavaScriptSerializer().Deserialize<JsonResult>(json);
var qry = from house in obj.data.house
let post = house.data
select new MessageItem
{
User = post.owner,
Meza = post.message
};
with:
class JsonResult
{
public string dola { get; set; }
public Data data { get; set; }
public class Data
{
public List<House> house { get; set; }
}
public class House
{
public string dola { get; set; }
public HouseData data { get; set; }
}
public class HouseData
{
public string owner { get; set; }
public int price {get;set;}
public Uri url {get;set;}
public string message {get;set;}
public bool #checked {get;set;}
}
}