C# object to xml serialization - c#

I have json string which is deserialized into c# class object, now I am trying serialize it into xml and writing same to the xml file. It does not have any errors or exceptioins but unable to write on xml file. The class has array of objects
Below is my code:
This is class:
public class WorkspaceRootObject
{
public WorkspaceRootObject()
{
}
public string id { get; set; }
public string name { get; set; }
public string description { get; set; }
public string contextId { get; set; }
}
This is serialization:
//deserializing json
wso= JsonConvert.DeserializeObject <List<WorkspaceRootObject>>(finalResponse);
Console.WriteLine("after deserializing...");
FileStream fs = new FileStream("D:\\Rohit_VisualStudio\\ServerManagementFormRest\\bin\\Debug\\WorkSpaceDetails.xml", FileMode.OpenOrCreate);
//serializing into xml
XmlSerializer xs = new XmlSerializer(typeof(List<WorkspaceRootObject>), new System.Type[] {typeof(WorkspaceRootObject)});
TextWriter sw = new StreamWriter(fs);
xs.Serialize(sw, wso);
I have used Newtonsoft json. and after opening xml file it shows Invalid at the top level of the document. Error processing resource 'file:///D:/ProjectLocation/...

Related

Passing a json file as a parameter to a method

I am learning how to work with json data using Newtonsoft.Json.
I stored my valid json file in a folder in my console application and calling
a method that will process the json file.
static void Main(string[] args)
{
IEnumerable<IEnumerable<string>> result;
string pathToFile = #"C:\DevelopmentJson\ConsoleApp1\File\my_test.json";
MyReader objReader = new MyReader();
result = objReader.Export(pathToFile).ToList();
Console.WriteLine("Hello");
}
Here is the method within my class that is been called.
public IEnumerable<IEnumerable<string>> Export(string json)
{
var document = JToken.Parse(json);
var data = new List<List<string>>();
.....
return data;
}
I am beginning to feel I cannot use a pathToFile as a path to my json file.
I started to get the error message below on this line [var document = JToken.Parse(json);]
Newtonsoft.Json.JsonReaderException:
'Unexpected character encountered while parsing value: C. Path '', line 0, position 0.'
How do I resolve this error message?
The Newtonsoft Json.NET documentation has two examples showing how to deserialize JSON from a file. Below are both examples with minor modifications to help integrate with your code.
Option 1. Reading JSON data via JsonConvert
var pathToFile = #"C:\DevelopmentJson\ConsoleApp1\File\my_test.json";
// read file into a string and deserialize JSON to a type
var dataFromJsonConvert = JsonConvert.DeserializeObject<MyData>(File.ReadAllText(pathToFile));
// dataFromJsonConvert now holds your JSON data from file
Option 2. Reading JSON data via JsonSerializer
var pathToFile = #"C:\DevelopmentJson\ConsoleApp1\File\my_test.json";
// deserialize JSON directly from a file
using (StreamReader file = File.OpenText(pathToFile))
{
var serializer = new JsonSerializer();
var dataFromJsonSerializer = (IEnumerable<IEnumerable<string>>)serializer.Deserialize(file, typeof(MyData));
// dataFromJsonSerializer now holds your JSON data from file
}
Example demonstrating how to utilize answer
static void Main(string[] args)
{
var pathToFile = "C:\DevelopmentJson\ConsoleApp1\File\my_test.json";
var fileJsonRaw = File.ReadAllText(pathToFile))
var objReader = new MyReader();
var fileJsonParsed = objReader.Export(fileJsonRaw).ToList();
Console.WriteLine("Hello");
}
public MyData Export(string json)
{
return JsonConvert.DeserializeObject<MyData>(json);
}
Classes generated from your JSON data
The classes below were generated from your sample JSON. These classes are used within answer to demonstrate a complete solution.
public partial class MyData
{
[JsonProperty("UpdatedDay")]
public string UpdatedDay { get; set; }
[JsonProperty("UpdatedUser")]
public string UpdatedUser { get; set; }
[JsonProperty("solution")]
public Solution[] Solution { get; set; }
}
public partial class Solution
{
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("fields")]
public Field[] Fields { get; set; }
}
public partial class Field
{
[JsonProperty("firstname")]
public string Firstname { get; set; }
[JsonProperty("lastiname", NullValueHandling = NullValueHandling.Ignore)]
public string Lastiname { get; set; }
[JsonProperty("required")]
public bool FieldRequired { get; set; }
[JsonProperty("lastname", NullValueHandling = NullValueHandling.Ignore)]
public string Lastname { get; set; }
}
Note: The following using statements are necessary.
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
JToken.Parse doesn't take a path, it takes the actual json string.
You can get the contents of the file with File.ReadAllText.
Something like this (checks etc omitted):
public IEnumerable<IEnumerable<string>> Export(string path)
{
string json = File.ReadAllText(path);
var document = JToken.Parse(json);
var data = new List<List<string>>();
.....
return data;
}
Note that there are better ways of parsing a file with json.net. For more info read this.

De-serialize XML files with varying XmlRoot element names

I have a large number of XML files that I need to perform de-serialization on. These files have varying root names (over 250). I'm trying to pass the root attribute name through XmlSerializer before accessing the XML class to retrieve my data. Here is what I have but I'm still getting an error that the root name was expected although the XmlElement class is passing the attribute to the XmlSerializer class.
The method used to retrieve the file:
string strXmlDoc = path;
XmlDocument objXmlDoc = new XmlDocument();
objXmlDoc.Load(strXmlDoc);
XmlElement objRootElem = objXmlDoc.DocumentElement;
XmlSerializer xmlSerial = new XmlSerializer(typeof(XMLFile), new XmlRootAttribute(objRootElem.ToString()));
StreamReader sr = new StreamReader(path);
XMLFile entity = xmlSerial.Deserialize(sr) as XMLFile;
The XML classes file:
[Serializable]
//[XmlRoot("randomname")] Removed this line since I'm getting the XmlRoot attribute in the XmlSerializer line.
public class XMLFile
{
[System.Xml.Serialization.XmlElement("RECORD")]
public RECORD RECORD { get; set; }
}
[Serializable]
public class RECORD
{
[XmlElement("BK01")]
public Record Bk01 { get; set; }
[XmlElement("BK02")]
public Record Bk02 { get; set; }
}
[Serializable]
public class Record
{
[XmlAttribute("Value")]
public string Value { get; set; }
}
Change this:
XmlSerializer xmlSerial =
new XmlSerializer(typeof(XMLFile), new XmlRootAttribute(objRootElem.ToString()));
to this:
XmlSerializer xmlSerial =
new XmlSerializer(typeof(XMLFile), new XmlRootAttribute(objRootElem.Name));
^^^
XmlElement.ToString() will always return System.Xml.XmlElement, which is not what you want.

c# parse string to xml using StringReader

I have an XML and I load it in an class.
This is my XML
<out_policySystem xmlns:msl="http://www.ibm.com/xmlmap" xmlns:io="" xmlns:xs4xs="http://www.w3.org/2001/XMLSchema">
<BGBAResultadoOperacion>
<Severidad>OK</Severidad>
</BGBAResultadoOperacion>
<permiteOperar>true</permiteOperar>
<Lista xmlns:ns0=\"http://CalypsoPolicySystem_lib/service\">
<Codigo>ODM-006</Codigo>
<Descripcion>Aviso</Descripcion>
<DescripcionTecnica>XXXX</DescripcionTecnica>
</Lista>
</out_policySystem>
I have define my classes like this.
[XmlRoot(ElementName = "out_policySystem")]
public partial class output_policySystem
{
public BGBAResultadoOperacion BGBAResultadoOperacion { get; set; }
public bool permiteOperar { get; set; }
public List[] Lista { get; set; }
}
public partial class BGBAResultadoOperacion
{
public string Severidad { get; set; }
}
public partial class List
{
public string Codigo { get; set; }
public string Descripcion { get; set; }
public string DescripcionTecnica { get; set; }
}
I read this like this.
XmlNodeList elemlist = xDoc.GetElementsByTagName("out_policySystem");
string result = elemlist[0].InnerXml;
XmlSerializer serializer = new XmlSerializer(typeof(BGBAResultadoOperacion));
using (StringReader reader = new StringReader(result))
{
result = (BGBAResultadoOperacion)(serializer.Deserialize(reader));
}
the value of result is this.
<BGBAResultadoOperacion><Severidad>OK</Severidad></BGBAResultadoOperacion><permiteOperar>true</permiteOperar><Lista><Codigo>ODM-006</Codigo><Descripcion>Aviso</Descripcion><DescripcionTecnica>xxxx</DescripcionTecnica></Lista>
What I need is to get the value of BGBAResultadoOperacion
when i set
using (StringReader reader = new StringReader(result))
{
result = (BGBAResultadoOperacion)(serializer.Deserialize(reader));
}
result get XML error...
There are multiple root elements. Line 1, position 76.
XML node out_policySystem has three root elements inside it. I need to parse only BGBAResultadoOperacion
How can I get it?
Thanks
That's because of this line:
elemlist[0].InnerXml
Which returns an XML Fragment, not an XML Document.
<BGBAResultadoOperacion>
<Severidad>OK</Severidad>
</BGBAResultadoOperacion>
<permiteOperar>true</permiteOperar>
<Lista xmlns:ns0=\"http://CalypsoPolicySystem_lib/service\">
<Codigo>ODM-006</Codigo>
<Descripcion>Aviso</Descripcion>
<DescripcionTecnica>XXXX</DescripcionTecnica>
</Lista>
So either use the .OuterXML, or use XElement.CreateReader() as described in the answer here: Serialize an object to XElement and Deserialize it in memory

Unable to deserialize property with specific name

I'm using DataContractSerializer in C# to deserialize xml file into object, and everything was working fine :)
My issue started when I add a new property to my class and xml file. My new property name is EncryptionKey every time I deserialize file, property value remain null, but when i change the name of xml element and property to anEncryptionKey it deserialized correctly without changing anything else in the code.
Actually I try a lot of options for property name like EncryptKey, Encrypt and a lot more but I ended up with anEncryptionKey.
Maybe there is some constraint on properties names or something like that or I just need more caffeine to figure it out.
Xml file:
<?xml version="1.0" encoding="utf-8" ?>
<KioskSettings xmlns="http://schemas.datacontract.org/2004/07/Proxies" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ID>20198</ID>
<HeartBeatInterval>1</HeartBeatInterval>
<ServerURL></ServerURL>
<EncryptionKey>abcd</EncryptionKey>
</KioskSettings>
Code i use to deserialize file into object:
private KioskSettings ReadEngineSettingsFromSimulatorXmlFile()
{
KioskSettings engineSettings = new KioskSettings();
DataContractSerializer serializer = new DataContractSerializer(typeof(KioskSettings));
FileStream fs = new FileStream(#"c:\simulation.xml", FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (serializer.IsStartObject(reader))
{
engineSettings = (KioskSettings)serializer.ReadObject(reader);
}
break;
}
}
fs.Flush(); fs.Close();
reader.Close();
reader = null;
serializer = null;
return engineSettings;
}
KioskSettings class:
public class KioskSettings
{
public string ID { get; set; }
public int HeartBeatInterval {get; set;}
public string ServerURL {get; set;}
public string EncryptionKey { get; set; }
}
Note: Above code may contains some syntax errors because I modify it to make it short.
You need to ensure your XML nodes are in alphabetical order:
<?xml version="1.0" encoding="utf-8" ?>
<KioskSettings xmlns="http://schemas.datacontract.org/2004/07/Proxies" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<EncryptionKey>abcd</EncryptionKey>
<HeartBeatInterval>1</HeartBeatInterval>
<ID>20198</ID>
<ServerURL></ServerURL>
</KioskSettings>
Serialize a KioskSettings object with the following code, and ensure your XML takes the same form:
public static string DataContractSerializeObject<T>(T objectToSerialize)
{
using (MemoryStream memStm = new MemoryStream())
{
var serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(memStm, objectToSerialize);
memStm.Seek(0, SeekOrigin.Begin);
using (var streamReader = new StreamReader(memStm))
{
string result = streamReader.ReadToEnd();
return result;
}
}
}
If you need to preserve a specific order then specify the DataMember attribute on your class properties - Data Member Order e.g.
[DataContract]
public class KioskSettings
{
[DataMember(Order = 1)]
public string ID { get; set; }
[DataMember(Order = 2)]
public int HeartBeatInterval { get; set; }
[DataMember(Order = 3)]
public string ServerURL { get; set; }
[DataMember(Order = 4)]
public string EncryptionKey { get; set; }
}

Deserialize xml to IList c#

I am trying to deserialize some xml into an IList, but I am having problems. This is what I have done so far:
The XML:
<?xml version="1.0" encoding="utf-8"?>
<Animals>
<Animal>
<Name>Cow</Name>
<Color>Brown</Color>
</Animal>
</Animals>
The Model:
[XmlRoot("Animals")]
public class Model
{
[XmlElement("Animal")]
public IList<Animal> AnimalList { get; set; }
}
public class Animal
{
[XmlElement("Name")]
public string Name{ get; set; }
[XmlElement("Color")]
public string Color{ get; set; }
}
Deserialization:
FileStream fs = new FileStream("file.xml", FileMode.Open);
XmlReader xml = XmlReader.Create(fs);
XmlSerializer ser = new XmlSerializer(typeof(List<Model>));
var list = (List<Model>)ser.Deserialize(xml);
I get an invalid operation exception when running the code above. What am I doing wrong?
Thanks,
James Ford
Try that:
// Create a new XmlSerializer instance with the type of the test class
XmlSerializer SerializerObj = new XmlSerializer(typeof(List<Model>));
// Create a new file stream for reading the XML file
FileStream ReadFileStream = new FileStream(#"C:\file.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
// Load the object saved above by using the Deserialize function
List<Model> LoadedObj = (List<Model>)SerializerObj.Deserialize(ReadFileStream);
// Cleanup
ReadFileStream.Close();
The problem is that you are using an IList<Animal>. You need to use a List<Animal> so that it knows the specific type to use.
EDIT: Using the following code in LINQPad works perfectly. Only difference is I am loading the XML via string instead of file, but even when I change to a file it works fine. I just added the using for System.Xml.Serialization.
void Main()
{
string xml = #"<?xml version=""1.0"" encoding=""utf-8""?>
<Animals>
<Animal>
<Name>Cow</Name>
<Color>Brown</Color>
</Animal>
</Animals>";
XmlReader reader = XmlReader.Create(new StringReader(xml));
XmlSerializer ser = new XmlSerializer(typeof(Model));
var list = (Model)ser.Deserialize(reader);
list.Dump();
}
// Define other methods and classes here
[XmlRoot("Animals")]
public class Model
{
[XmlElement("Animal")]
public List<Animal> AnimalList { get; set; }
}
public class Animal
{
[XmlElement("Name")]
public string Name{ get; set; }
[XmlElement("Color")]
public string Color{ get; set; }
}
I think you need to change your XmlSerializer to this:
XmlSerializer ser = new XmlSerializer(typeof(Model));
Before you were trying to serialize a list of Models, you want to serialize a XML file into a Model, which contains a list of stuff.
Also, you need to change your ObjectList definition to
public List<Animal> AnimalList { get; set; }

Categories

Resources