C# Newton.Json deserialize - c#

I would like to read a xml and convert json and then convert that json to an C# object.
Bare in mind that i could use linq to initialize the objects, i know that.
But what i want to a achieve is read the xml convert it to json and from the converted string Deserialize to object. I'm not being able to initialize correctly the object.
What am i missing?
public class Cash
{
public string Amount { get; set; }
}
public class POSLog
{
public string MajorVersion { get; set; }
public string MinorVersion { get; set; }
public string FixVersionive { get; set; }
public Cash Cashx { get; set; }
}
public class Program
{
public static void Main(string[] args)
{
try
{
XmlDocument xml = new XmlDocument();
xml.LoadXml("<POSLog MajorVersion=\"6\" MinorVersion=\"0\" FixVersion=\"0\"><Cash Amount = \"100\"></Cash></POSLog>");
string json = JsonConvert.SerializeObject(xml.InnerXml);
POSLog deserializedProduct = JsonConvert.DeserializeObject<POSLog>(json);
Console.WriteLine("Major Version" + deserializedProduct.MajorVersion);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}

You can't serialize a string containing xml into json and expect it to deserialize into a POSLog. Deserialized your xml into a POSLog before you continue.

According to documentation :
Converting between JSON and XML with Json.NET
Conversion Rules
Elements remain unchanged.
Attributes are prefixed with an # and should be at the start of the object.
Single child text nodes are a value directly against an element, otherwise they are accessed via #text.
The XML declaration and processing instructions are prefixed with ?.
Character data, comments, whitespace and significant whitespace nodes are accessed via #cdata-section, #comment, #whitespace and #significant-whitespace respectively.
Multiple nodes with the same name at the same level are grouped together into an array.
Empty elements are null.
If the XML created from JSON doesn't match what you want, then you will need to convert it manually. The best approach to do this is to load your JSON into a LINQ to JSON object like JObject or JArray and then use LINQ to create an XDocument.
With that in mind the following unit test created to solve your problem passes.
[TestClass]
public class JsonToXmlTests : MiscUnitTests {
[TestMethod]
public void Xml_Should_Convert_To_JSON_And_Object() {
string xml = "<POSLog MajorVersion=\"6\" MinorVersion=\"0\" FixVersion=\"0\"><Cash Amount = \"100\"></Cash></POSLog>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.None, true);
//Attributes are prefixed with an # and should be at the start of the object.
jsonText = jsonText.Replace("\"#", "\"");
POSLog actual = JsonConvert.DeserializeObject<POSLog>(jsonText);
actual.Should().NotBeNull();
actual.MajorVersion.Should().Be("6");
actual.MinorVersion.Should().Be("0");
actual.FixVersion.Should().Be("0");
actual.Cash.Should().NotBeNull();
actual.Cash.Amount.Should().Be("100");
}
public class Cash {
public string Amount { get; set; }
}
public class POSLog {
public string MajorVersion { get; set; }
public string MinorVersion { get; set; }
public string FixVersion { get; set; }
public Cash Cash { get; set; }
}
}

The problem is you're deserializing the wrong thing.
You have to first deserialize to POSLog from XML and then serialize the POSLog as json.
void Main()
{
try
{
string xmlDoc = "<POSLog MajorVersion=\"6\" MinorVersion=\"0\" FixVersion=\"0\"><Cash Amount = \"100\"></Cash></POSLog>";
XmlSerializer xser = new XmlSerializer(typeof(POSLog));
POSLog fromXml = xser.Deserialize(new StringReader(xmlDoc)) as POSLog;
string json = JsonConvert.SerializeObject(fromXml);
POSLog fromJson = JsonConvert.DeserializeObject<POSLog>(json);
Console.WriteLine("MajorVersion=" + fromJson.MajorVersion);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
// Define other methods and classes here
public class Cash
{
public string Amount { get; set; }
}
public class POSLog
{
[XmlAttribute]
public string MajorVersion { get; set; }
[XmlAttribute]
public string MinorVersion { get; set; }
[XmlAttribute]
public string FixVersionive { get; set; }
public Cash Cashx { get; set; }
}

Related

Deserializing a JSON to c# object when key contains dollar($)(Metadata)

So i'm getting a response like this
{"$id":"1","success":true,"errors":{"$id":"2","$values":[]}}
how can i convert this into to a c# object, tried using this(http://json2csharp.com/) tool to make an output but it doesn't make sense
this is what i'm getting
x
public class Errors
{
public string __invalid_name__$id { get; set; }
public List<object> __invalid_name__$values { get; set; }
}
public class RootObject
{
public string __invalid_name__$id { get; set; }
public bool success { get; set; }
public Errors errors { get; set; }
}
I'm kinda new to c#, any inputs would be deeply appreciated, i basically need access to success key variable
You need to add [JsonProperty] attribute to every property that key name started with dollar $
public class Errors
{
[JsonProperty("$id")]
public string id { get; set; }
[JsonProperty("$values")]
public List<object> values { get; set; }
}
public class RootObject
{
[JsonProperty("$id")]
public string id { get; set; }
public bool success { get; set; }
public Errors errors { get; set; }
}
Because the $ indicates metadata, not an actual data field. so you have to modify your JsonSerializerSettings to ignore MetadataPropertyHandling.
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;
And finally deserialize your json to above class objects.
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(json, settings);
Here I created a sample console app for demonstration purpose that shows how above code will work.
class program
{
public static void Main()
{
string json = File.ReadAllText(#"Path to your json file");
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(json, settings);
Console.WriteLine("id: " + rootObject.id);
Console.WriteLine("success: " + rootObject.success);
Console.WriteLine("errors.id: " + rootObject.errors.id);
Console.WriteLine("errors.values: " + string.Join(",", rootObject.errors.values));
Console.ReadLine();
}
}
Output:
Well, What you can do is
public class Errors
{
[JsonProperty(PropertyName = "$id")]
public string id { get; set; }
[JsonProperty(PropertyName = "$values")]
public List<object> values { get; set; }
}
public class RootObject
{
[JsonProperty(PropertyName = "$id")]
public string id { get; set; }
public bool success { get; set; }
public Errors errors { get; set; }
}
You need your object attributes to match you json string ($id instead of _invalid_name_$id), then you can use:
JsonConvert.DeserializeObject<RootObject>(jsonString);
Here is a simple class to serialize json string from object or to object (T). May de/serialize array(list) of objects.
public class HelperSerializer<T> where T: class
{
public static string WriteFromObject(T source)
{
using (var ms = new MemoryStream()) {
var ser = new DataContractJsonSerializer(typeof(T));
ser.WriteObject(ms, source);
byte[] json = ms.ToArray();
return Encoding.UTF8.GetString(json, 0, json.Length);
}
}
// Deserialize a JSON stream to an object.
public static T ReadToObject(string json)
{
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var ser = new DataContractJsonSerializer(typeof(T));
return ser.ReadObject(ms) as T;
}
}
}
Use persons = HelperSerializer<List<Person>>.ReadToObject(json);
and var json = HelperSerializer<List<Person>>.WriteFromObject(persons);

Read Error when loading JSON array in Newtonsoft C#

I'm using the Newtonsoft JSON parser in C#. The JSON seems to be formatted correctly but I'm getting a read error that doesn't make sense. The JSON should deserialize and load into the class instance automatically.
Class:
class FilterMatrix {
public int ID { get; set; }
public int ParentID { get; set; }
}
Deserializing code:
string fileName = #"C:\Users\accounts.json";
FilterMatrix kernel = JsonConvert.DeserializeObject<FilterMatrix>(File.ReadAllText(fileName));
JSON file contents:
{"Features":[{"ID":0,"ParentID":0},{"ID":0,"ParentID":0}]}
Error:
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: {. Path 'Features', line 1, position 14.'
Well, at least the structure of the JSON needs to match your class hierarchy. Working example:
class Program
{
static void Main(string[] args)
{
var root = JsonConvert.DeserializeObject<Root>(File.ReadAllText("file.json"));
}
}
public class Root
{
public List<FilterMatrix> Features { get; set; }
}
public class FilterMatrix
{
public int ID { get; set; }
public int ParentID { get; set; }
}
Thanks, Gene.
I basically came up with this as I saw your post. It never donned on me to have multiple classes within a class. I guess I assumed an array of classes would be automatically made :-/
JSON script:
{"Features":[{"ID":0,"ParentID":0},{"ID":0,"ParentID":0}]}
Deserialization:
kernel = JsonConvert.DeserializeObject<FilterMatrix>(File.ReadAllText(fileName));
My classes:
class FilterMatrix {
private List<Feature> features = new List<Feature>();
public List<Feature> FeaturesList
{
get { return features; }
set { features = value; }
}
}
class Feature {
public int ID { get; set; }
public int ParentID { get; set; }
}
I access elements by their index:
kernel.FeaturesList[0].ID

Getting json value from httpclient post request

I am trying to get the modhash value from a returned json string, I have set my getter/setter
public string mod_hash { get; set; }
I am using httclient, how can I get the json value of mod_hash
To post data:
/
Try with the below one.
To deserialize,you need to create the proper class structure for the json string. As per your json string, i have created here. Try and let us know if you have still issues.
public class RootObject
{
public Json json { get; set; }
}
public class Json
{
public List<object> errors { get; set; }
public Data data { get; set; }
}
public class Data
{
public bool need_https { get; set; }
public string modhash { get; set; }
public string cookie { get; set; }
}
And to test if it is correct or not here i have the program to get the "modhash" property value from your json string.
class Program
{
static void Main(string[] args)
{
string jsonstring = #"{ ""json"": {""errors"": [],""data"": { ""need_https"": true, ""modhash"": ""valuehereremoved"",""cookie"": ""valuehereremoved"" } } }";
var serializer = new JavaScriptSerializer();
var jsonObject = serializer.Deserialize<RootObject>(jsonstring);
Console.WriteLine("modhash : " + jsonObject.json.data.modhash);
Console.Read();
}
}
OUTPUT
Hope it solves your problem.

Deserialize CSV string to an C# Object

I have a response from Jira API, require to be deserialized into data model:
com.atlassian.greenhopper.service.sprint.Sprint#40675167[id=10151,rapidViewId=171,state=CLOSED,name=Sprint 37.1,startDate=2015-07-30T16:00:22.000+03:00,endDate=2015-08-13T16:00:00.000+03:00,completeDate=2015-08-13T14:31:34.343+03:00,sequence=10151]
This is actually the information of current sprint for issue.
I need to deserialize it to a model like:
public class Model
{
public string name { get; set; }
...
}
I have already removed all non-required information, like com.atlassian.greenhopper.service.sprint.Sprint#40675167 using Regex pattern \[(.*?)\] so I have brackets and all inside.
Now I stopped completely trying to find the a way to convert this string to a data model.
Found the following thread at the Atlassian Answers page and there appears to be no JSON representation of that inner Object. As shown in the example from that thread:
customfield_10007:[
"com.atlassian.greenhopper.service.sprint.Sprint#a29f07[rapidViewId=<null>,state=CLOSED,name=NORD - Sprint 42,startDate=2013-07-29T06:47:00.000+02:00,endDate=2013-08-11T20:47:00.000+02:00,completeDate=2013-08-14T15:31:33.157+02:00,id=107]",
"com.atlassian.greenhopper.service.sprint.Sprint#769133[rapidViewId=<null>,state=ACTIVE,name=NORD - Sprint 43,startDate=2013-08-14T15:32:47.322+02:00,endDate=2013-08-23T15:32:47.322+02:00,completeDate=<null>,id=117]"
],
The response is indeed a JSON array, but the array itself contains CSV's, so you can make use of the following to parse that:
public class DataObject
{
public string id { get; set; }
public string rapidViewId { get; set; }
public string state { get; set; }
public string name { get; set; }
public string startDate { get; set; }
public string endDate { get; set; }
public string completeDate { get; set; }
public string sequence { get; set; }
}
public class Program
{
private const string sampleStringData =
#"[id=10151,rapidViewId=171,state=CLOSED,name=Sprint 37.1,startDate=2015-07-30T16:00:22.000+03:00,endDate=2015-08-13T16:00:00.000+03:00,completeDate=2015-08-13T14:31:34.343+03:00,sequence=10151]";
static void Main(string[] args)
{
var dataObject = new DataObject();
string[][] splitted;
var sampleWithNoBrackets = sampleStringData.Substring(1,sampleStringData.Length-2);
splitted = sampleWithNoBrackets.Split(',').Select(p => p.Split('=')).ToArray();
dataObject.id = splitted[0][1];
dataObject.rapidViewId = splitted[1][1];
dataObject.state = splitted[2][1];
dataObject.name = splitted[3][1];
dataObject.startDate = splitted[4][1];
dataObject.endDate = splitted[5][1];
dataObject.completeDate = splitted[6][1];
dataObject.sequence = splitted[7][1];
Console.ReadKey();
}
}
Here's the output for the above:

How to deserialize XML string fragment?

I have an object that has some properties that are XML string fragments. I want to take those and further deserialize them into objects for easier use. How can I do that using the .NET XML Serializer?
Here's an example of the XML string fragment:
<Addr1></Addr1>
<Addr2></Addr2>
<Addr3></Addr3>
<Addr4></Addr4>
<City></City>
<State></State>
<PostalCode></PostalCode>
<Country></Country>
So far my attempts have resulted in this exception:
<Addr1 xmlns=''> was not expected.
If you want to deserialize the fragments into objects I assume you have a strongly typed object so you could just create a helper method to add a root element using the type name of the object you are trying to deserialize
Example:
public T DeserializeFragment<T>(string xmlFragment)
{
// Add a root element using the type name e.g. <MyData>...</MyData>
var xmlData = string.Format("<{0}>{1}</{0}>", typeof(T).Name, xmlFragment);
var mySerializer = new XmlSerializer(typeof(T));
using (var reader = new StringReader(xmlData))
{
return (T)mySerializer.Deserialize(reader);
}
}
Usage:
public class MyData
{
public string Addr1 { get; set; }
public string Addr2 { get; set; }
public string Addr3 { get; set; }
public string Addr4 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
}
string fragment = #"<Addr1>2</Addr1>
<Addr2>2</Addr2>
<Addr3>2</Addr3>
<Addr4>2</Addr4>
<City>2</City>
<State>2</State>
<PostalCode>2</PostalCode>
<Country>2</Country>";
var result = DeserializeFragment<MyData>(fragment);

Categories