JavaScriptSerializer How to Deserialize an identifier with space - c#

I am having exactly the same problem as described here https://stackoverflow.com/questions/12565464/javascriptserializer-deserialize-an-identifier-with-space but as no one answered thought i'd try again,
API created by someone else in the form of
[{"AdvertId":"1234567","Price Original":"500","Sold":"False"}]
Application already uses a JavascriptSerilalization to populate the named properties on many other API's so do not want to change that really, but my class to hold this data can not have a property with a space in it "Price Original", and this can't be removed or replaced with an _ or something. Are there any methods that can be called to translate the string to something different?
Is there any solution to this or have I got to use JSON.net to deserialize, was some bits on DataContracts I read up on and these might be able to help but I can't seems to find out how to get this to work for my code, and would be nice to know that is possible without investigation this path.
Many thanks in advance
Sample Class
Class Sample
{
public int AdvertId { get; set; }
public string Price Original { get; set; }
public bool Sold { get; set; }
}

You can still use built-in types, but you'll need to use DataContractJsonSerializer instead of JavaScriptSerializer, and add the appropriate DataContract and DataMember attributes - the implementation is a bit different, but still pretty straightforward.
One thing - your Sold property is boolean, but your JSON sample has a string there - booleans are valid JSON types, so you can remove the quotes.
Some working code:
JSON:
[{"AdvertId":"1234567","Price Original":"500","Sold":false}]
C#:
var ser = new DataContractJsonSerializer(typeof(Sample[]));
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(JSON))) {
Sample[] s = (Sample[])ser.ReadObject(ms);
}
[DataContract]
public class Sample {
[DataMember]
public int AdvertId { get; set; }
[DataMember(Name = "Price Original")]
public string PriceOriginal { get; set; }
[DataMember]
public bool Sold { get; set; }
}

Related

JSON Getting the value of a list based on the parameter

I have to process a complex JSON-file and I'm hitting some obstacles.
Below you will find a little excerpt from the class which is in XML but which I convert to JSON to be able to process it easier.
<Selection Category="M43002NN">
<ReferendumOptionIdentifier>foo</ReferendumOptionIdentifier>
<ValidVotes>6162</ValidVotes>
<CountMetric Id="M" Type="LevelDepositList">43002</CountMetric>
<CountMetric Id="S4" Type="SeatsToBeFilled">23</CountMetric>
<CountMetric Id="S5" Type="SubstitutesMax">0</CountMetric>
<CountMetric Id="S9" Type="LinguisticRegime">2</CountMetric>
<CountMetric Id="S10" Type="VotesDeposited">6620</CountMetric>
<CountMetric Id="S11" Type="BlankAndInvalidVotes">458</CountMetric>
<CountMetric Id="S12" Type="Alderman">0</CountMetric>
<CountMetric Id="S14" Type="ValidVote_E5">0</CountMetric>
<CountMetric Id="S15" Type="BlankAndInvalidVotes_E5">0</CountMetric>
</Selection>
In the above example I'm trying to extract the value of the CountMetric which has the type "SeatsToBeFilled".
So far I was able to collect the results and to isolate the correct CountMetric but I can't seem to get it's value.
This is my class:
public class TotalSelectionClass
{
[JsonProperty("#Category")]
public string Category { get; set; }
public int ValidVotes { get; set; }
public List<CountMetricClass> CountMetric { get; set; }
}
And this is the CountMetricClass that I use:
public class CountMetricClass
{
[JsonProperty("#Id")]
public string Id { get; set; }
[JsonProperty("#Type")]
public string Type { get; set; }
}
Below is the code that I use to get the desired CountMetric (slightly reduced code for readability-purposes):
var TotalSeats = Selection[0].CountMetric.Where(x => x.Type == "SeatsToBeFilled").First();
This returns the CountMetric-object to me but how do I extract the value from it? So in this case, how do I extract the number 23 from it?
Thank you.
The answer here really depends on the shape of your JSON and, thus, how you're doing your XML -> JSON conversion. You have not provided the JSON form nor asked for help in converting the XML -> JSON so I'll answer based on the information available.
As-is, you can't get the CountMetric value from your CountMetricClass. This is because the value held in the XML (looks like 23 for SeatsToBeFilled) is never read into that object. To get the value, you'll need to
1) check that your XML converter is actually encoding the value from the XML into the JSON to be parsed
2) modify your CountMetricClass so that it's reading from this value field. I've chosen to call this field MetricValue for readability, but you could obviously choose whatever name works best for you. For instance, your new class may take the form of something like:
public class CountMetricClass
{
[JsonProperty("#Id")]
public string Id { get; set; }
[JsonProperty("#Type")]
public string Type { get; set; }
[JsonProperty("#MetricValue")]
public int MetricValue { get; set; }
}
3) once we've successfully read the MetricValue into your CountMetricClass, we can modify your linq expression to get the value by accessing the MetricValue field from the target CountMetric like:
var TotalSeats = Selection[0].CountMetric.Where(x => x.Type == "SeatsToBeFilled").MetricValue;
A little follow-up for those who might run into the same issue.
Based on SIRHAMY's suggestion I had a look at the actual JSON which I was converting from XML.
{"#Id":"S4","#Type":"SeatsToBeFilled","#text":"23"}
As SIRHAMY suggested I created a Text-field in my CountMetricClass
public class CountMetricClass
{
[JsonProperty("#Id")]
public string Id { get; set; }
[JsonProperty("#Type")]
public string Type { get; set; }
[JsonProperty("#Text")]
public string Text { get; set; }
}
After that I could get the value of the text by using:
Selection[0].CountMetric.Where(x => x.Type == "SeatsToBeFilled").First().Text
This will return "23" to me.
Thank you SIRHAMY!

How to get json data using c#?

string json string = {\"GetMyClassListResult\":{\"MyClassList\":[{\"Id\":1,\"Amount\":\"5,00\"},{\"Id\":2,\"Amount\":\"10,00\"},{\"Id\":3,\"Amount\":\"20,00\"},{\"Id\":4,\"Amount\":\"25,00\"}],\"ReturnValues\":{\"ErrorCode\":1,\"ErrorDescription\":\"Successful\"}}}
How do get "Id":1" and "Amount":"5,00" ?
First, you would need to declare a class as following.
class MyClass
{
[JsonProperty(PropertyName = "Id")]
public int Id { get; set; }
[JsonProperty(PropertyName = "Amount")]
public string Amount { get; set; }
}
and then, you can do the following in your method
var Jsonobj = JObject.Parse(json);
var list = JsonConvert.DeserializeObject<MyClass[]>(Jsonobj["GetMyClassListResult"]["MyClassList"].ToString()).ToList<MyClass>();
Hope that helps.
Combining the excellent Json.NET package with LINQ you could use:
var result = JObject.Parse(json)["GetMyClassListResult"]["MyClassList"]
.Select(item => new { Id = item["Id"], Amount = item["Amount"] })
.First();
result has the properties Id and Amount corresponding to the first item in the JSON array with values 1 and "5,00".
If instead you wanted an array of all items, just replace First() with ToArray().
So you have straight json and you're trying to convert it into an object to get some meaningful values?
I personally prefer working with classes where I can. I will throw my raw json into a json to C# converter. I like JsonUtils personally. (I have no affiliation, just a great free service.) There are some others out there, but it seems to be the most robust.
If you throw your raw json into there, you get the following classes:
public class MyClassList
{
public int Id { get; set; }
public string Amount { get; set; }
}
public class ReturnValues
{
public int ErrorCode { get; set; }
public string ErrorDescription { get; set; }
}
public class GetMyClassListResult
{
public IList<MyClassList> MyClassList { get; set; }
public ReturnValues ReturnValues { get; set; }
}
public class Example
{
public GetMyClassListResult GetMyClassListResult { get; set; }
}
Alright. Now that we have our models, we can deserialize the json. The most popular library for manipulating json is Newtonsoft.Json, which is available on NuGet or direct download.
You'll need to add a reference to that dll if you choose to download it; Nuget will auto-reference it when you install it.
At the top of your class file, you'll need to add
using Newtonsoft.Json;
along with your other using statements.
In your method you'll call JsonConvert.Deserialize<List<Example>>(json), which will give you your collection in POCOs.
Since there is only one object in the collection you can call .First() on the collection and then access the two values via the Id and Amount properties. You will need to make sure that System.Linq is in your using statements as well.
Full code:
var json = #"{\"GetMyClassListResult\":{\"MyClassList\":[{\"Id\":1,\"Amount\":\"5,00\"},{\"Id\":2,\"Amount\":\"10,00\"},{\"Id\":3,\"Amount\":\"20,00\"},{\"Id\":4,\"Amount\":\"25,00\"}],\"ReturnValues\":{\"ErrorCode\":1,\"ErrorDescription\":\"Successful\"}}}";
var collection = JsonConvert.Deserialize<List<Example>>(json);
var x = collection.First();
var amount = x.Amount;
var id = x.Amount;
You're then free to manipulate or work with those variables as you see fit. :)
first of all you need a class where you will de-serialize this string to your class object.
you need a class which will contain Id and Amount variable.
after that you can de-serialize this string to the object then you can access any data you want.

How to map a class properties in dynamodb without using attribute in .net

I am very new in dynamodb. I am following http://www.rkconsulting.com/blog/persistence-model-framework-with-aws-dynamodb
step by step tutorial for connecting and CRUD operation in dynamodb and it`s works fine.
In that tutorial they using attribute mapping for map class properties
[DynamoDBTable("Dinosaur")]
public class Dinosaur
{
[DynamoDBHashKey]
public string Id { get; set; }
[DynamoDBProperty(AttributeName = "Name")]
public string Name { get; set; }
[DynamoDBProperty(AttributeName = "HeightMetres")]
public double HeightMetres { get; set; }
[DynamoDBProperty(AttributeName = "WeightKG")]
public double WeightKg { get; set; }
[DynamoDBProperty(AttributeName = "Age")]
public int Age { get; set; }
[DynamoDBProperty(AttributeName = "Characteristics")]
public List<string> Characteristics { get; set; }
[DynamoDBProperty(AttributeName = "Photo", Converter = typeof(ImageConverter))]
public Image Photo { get; set; }
[DynamoDBIgnore]
public int IgnoreMe { get; set; }
}
My question is there any way to map class properties without using attribute ?
like as mongoDb
public class Employee
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
}
we can write this in this way in a separate class
BsonClassMap.RegisterClassMap<Employee>(cm => {
cm.AutoMap();
cm.IdMemberMap.SetRepresentation(BsonType.ObjectId);
});
Is it possible in dynamodb ?
In the latest version of the .NET SDK you don't have to put in the attribute tags, it will see all read/write properties and upload the attributes as the same name. You would only have to use the [DynamoDBProperty(...)] if you want the attribute name in DynamoDB to be something other than the .NET object name.
So in your case you could simply remove that attribute for all properties except photo (which needs the converter, you could remove the AttributeName part of it) and WeightKg (because the capitalization is different) and you would get the same result.
I see this is a little bit older question now, so it may not have been that way in older versions (not sure) but I'm using 3.3.0.0 of the SDK and it does work that way. You have probably moved on but answering for others that may come upon this thread as I did...
There is no way, the default "strongly typed" client relies on attributes.
If you have time to do the plumbing yourself - there is nothing stopping your from doing your own implementation of the POC to Dynamo mapping though. Amazon client api (AWSSDK.DynamoDBv2) exposes the raw class AmazonDynamoDBClient which handles all the API calls and the DynamoDBConext is just implementation of IDynamoDBContext interface - which exposes all the "strongly typed" operations. So you can make your own implementation and take different mapping approach in it.
Also you can make a feature request for this:
https://github.com/aws/aws-sdk-net/issues

Parsing versioned JSON

I have objects represented by two different Jsons:
JSON v1:
{
"names":[{"name":John},{"name":Eve}],
"version": 1
}
JSON v2:
{
"names":[{"name":"John", "age":22},{"name":"Eve", "age":35}],
"version": 2
}
Now I have class which can parse the first version of Json:
[JsonObject("Class")]
public class PeopleEntity
{
public string name{ get; set; }
}
public class People
{
public List<PeopleEntity> names{ get; set; }
public string version{ get; set; }
}
And this is how it is parsed:
result = JsonConvert.DeserializeObject<People>(json_data, new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.Ignore
});
Now, the problem is, that the request for parsing the second version of JSON came. What would be the best solution to handle this?
I have an idea to make list of interfaces (because of the attribute name, which is always there) and make multiple implementations of it, one for each version.
I don't see any need for interfaces to solve this.
If you want to deserialize both versions of JSON into the same type you could add a nullable age property to PersonEntity like this:
[JsonObject("Class")]
public class PeopleEntity {
public string name { get; set; }
public int? age { get; set; }
}
Notice the ? following the int type which means that property can be null. Using Json.NET, if you deserialize v1 JSON into this class the name will be populated as expected and the age will remain null.
Alternatively, since you know which version of JSON is being deserialized up front, you could have a different type for each version. Use you're existing PeopleEntity type for v1 and create a derived class that adds an age property for v2.

deserialize POCO array with JsonFX

I want to simply read some JSON data from a URL, then turn that into an collection of POCO classes, but I can't seem to figure out what I'm doing wrong.
Here is a sample of the JSON data, as it is fetched from the URL:
[
{
"Name":"Together As One Run",
"Location":"Parkville, MO",
"ScheduledAt":"\/Date(1334984400000)\/",
"URL":"http://www.runningintheusa.com/Race/View.aspx?RaceID=36667"
},
{
"Name":"Lean Green Running Machine 5K Run/Walk and 1 Mile Run",
"Location":"Springfield, MO",
"ScheduledAt":"\/Date(1335589200000)\/",
"URL":"http://www.runningintheusa.com/Race/View.aspx?RaceID=53945"
},
{
"Name":"Festival of Miles",
"Location":"St. Louis, MO",
"ScheduledAt":"\/Date(1338440400000)\/",
"URL":"http://www.runningintheusa.com/Race/View.aspx?RaceID=53901"
},
{
"Name":"Miles Against Melanoma",
"Location":"Saint Charles, MO",
"ScheduledAt":"\/Date(1338613200000)\/",
"URL":"http://www.runningintheusa.com/Race/View.aspx?RaceID=53939"
}
]
I can get this data with WebClient just fine.
I'm setting up my JsonFX reader like this:
var json = new JsonReader(new DataReaderSettings(new PocoResolverStrategy()));
Here is my POCO class:
public class Race {
public String Name { get; set; }
public String Location { get; set; }
public DateTime ScheduledAt { get; set; }
public String URL { get; set; }
}
I have tried to deserialize JSON data in several ways, and nothing seems to work:
//reader is an instance of StreamReader
var content = reader.ReadToEnd();
//nope
//var output = json.Read<Race>(content);
//nope
//var output = json.Read<Race[]>(content);
This has got to be a simple thing to do, I just can't find a solution. I spent about 30 mins. googling to no avail. Any help would be appreciated!
I've never used JsonFX but you can try Json.Net or built-in JavaScriptSerializer. Both work without any problem.
var jObj1 = JsonConvert.DeserializeObject<Race[]>(jsonstr);
var jobj2 = new JavaScriptSerializer().Deserialize<Race[]>(jsonstr);
edit oops, didn't read the title. Why are you using jsonfx?
maybe try a list?
var output = json.Read<List<Race>>(input);
Here is a valid example of how to get it done with JSON.Net.
You're going to want to use JSON.NET. It's faster than any of the built in classes and does a much better job of serializing dictionaries.
using Nuget
> Install-Package Newtonsoft.Json
List<Race> deserializedRaces = JsonConvert.DeserializeObject<List<Race>>(jsonString);
I bet you need to specify the datacontract and datamember attributes on your custom type for jsonFX to recognize it.
using System.Runtime.Serialization;
[DataContract]
public class Race {
[DataMember]
public String Name { get; set; }
[DataMember]
public String Location { get; set; }
[DataMember]
public DateTime ScheduledAt { get; set; }
[DataMember]
public String URL { get; set; }
}
You probably need to tell it to try parsing your date as a Microsoft-style date time:
var jsonReader = new JsonReader(
new DataReaderSettings(
new PocoResolverStrategy(),
new MSAjaxDateFilter()));

Categories