xml deserialization with error - c#

can you help me?
I have small experience in xml-serialization and can't resolve this problem.
I create request and get an answer
I have xml-response like this(from debug):
<?xml version=\"1.0\" encoding=\"utf-8\"?>\n
<SpellResult>
<error code=\"1\" pos=\"0\" row=\"0\" col=\"0\" len=\"6\">
<word>wird</word>
<s>word</s>
<s>world</s>
...
</error>
</SpellResult>
my deserialization:
...
var deserializer = new XmlSerializer(typeof(T));
using (MemoryStream memoryStream = new MemoryStream(StringToUtf8ByteArray(response.ToString())))
{
memoryStream.Position = 0;
var result = (T)deserializer.Deserialize(memoryStream);
return result;
}
...
Where:
private Byte[] StringToUtf8ByteArray(string xmlString)
{
// UTF8Encoding encoding = new UTF8Encoding();
var byteArray = Encoding.UTF8.GetBytes(xmlString);
return byteArray;
}
This is T-type:
[Serializable()]
[XmlRoot("SpellResult")]
public class SpellResult
{
public List<error> Errors
{
get;
set;
}
}
[Serializable()]
public class error
{
[XmlAttribute("code")]
public int Code
{
get;
set;
}
[XmlAttribute("pos")]
public int Position
{
get;
set;
}
[XmlAttribute("row")]
public int Row
{
get;
set;
}
[XmlAttribute("col")]
public int Column
{
get;
set;
}
[XmlAttribute("len")]
public int Length
{
get;
set;
}
[XmlElement("word")]
public string Word
{
get;
set;
}
[XmlArray]
[XmlArrayItem("s", typeof(Steer))]
public Steer[] Steer
{
get;
set;
}
}
[Serializable()]
public class Steer
{
[XmlElementAttribute("s")]
public string s { get; set; }
}
And I have exception: {"Data at the root level is invalid. Line 1, position 1."}
I tried to fix this problem with any answers from SO and other sites, but they do not resolve the issue.

To help diagnose errors like this, try to create an instance of the class, containing the data that you expected to get from your input XML. Then serialize your instance, and look at the results. This will tell you how XML Serialization expects your data to appear.
I suspect that you are missing an <Errors> element.

You class hierarchy, if you want to have Steer as class, must looks like this:
public class SpellResult
{
[XmlElement("error")]
public List<Error> Errors { get; set; }
}
public class Error
{
[XmlAttribute("code")]
public int Code { get; set; }
[XmlAttribute("pos")]
public int Position { get; set; }
[XmlAttribute("row")]
public int Row { get; set; }
[XmlAttribute("col")]
public int Column { get; set; }
[XmlAttribute("len")]
public int Length { get; set; }
[XmlElement("word")]
public string Word { get; set; }
[XmlElement("s")]
public List<Steer> Steers { get; set; }
}
public class Steer
{
[XmlText]
public string S { get; set; }
}
or, you can avoid class Steer just deserialize s elements into list of strings
[XmlElement("s")]
public List<string> Steers { get; set; }

Oh,
It was my carelessness and simple mistake.
I wrote
MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(responce))
But responce is an object of RestResponse...
Where I wrote:
string resp = response.Content.ToString();
using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(resp)))
{
...
}
It's worked. Facepalm.
Thanks for help.

Related

trying to use serializing to save and load variables from console app (c#) ( answered)

it was Answered by a comment from Chris.
i had to also do equipedShield = stateVariables.equipedShield; equipedWeapon = stateVariables.equipedWeapon; healthPotionCount = stateVariables.healthPotionCount; playerExpEarned = stateVariables.playerExpEarned;
to make it load, thank you chris.
my question is can i use variable names to store values? or do they have to be actual numbers?
i found a post here C# - Saving Console Game Values
i choose to do the serializing but instead save on mydocuments so i could actually find the txt file ( and i did)
to load in main:
string folder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
folder = Path.Combine(folder, "RNGgameSaveFiles");
Directory.CreateDirectory(folder);
string dataFile = Path.Combine(folder, "RNGgameSaveFileV1");
if (File.Exists(dataFile))
{
using (Stream stateStream = File.OpenRead(dataFile))
{
BinaryFormatter deserializer = new BinaryFormatter();
stateVariables = (AppState)deserializer.Deserialize(stateStream);
}
}
it seems to save it just fine, but when loading everything is empty.
like :
static int roundsPlayed;
static decimal money = 0;
static decimal totalMoneyEarned;
static double totalScore;
static int totalKills;
static int totalLosses;
saved as:
stateVariables.totalLosses = totalLosses;
stateVariables.totalKills = totalKills;
stateVariables.totalScore = totalScore;
stateVariables.totalMoneyEarned = totalMoneyEarned;
stateVariables.money = money;
stateVariables.roundsPlayed = roundsPlayed;
or is that what is messing it up for me?
i made that class called appstate:
namespace rngGame
{
[Serializable()]
public class AppState
{
public int roundsPlayed { get; set; }
public decimal money { get; set; }
public decimal totalMoneyEarned { get; set; }
public double totalScore { get; set; }
public int totalKills { get; set; }
public int totalLosses { get; set; }
public bool owned01 { get; set; }
public bool owned02 { get; set; }
public bool owned03 { get; set; }
public bool owneds01 { get; set; }
public bool owneds02 { get; set; }
public bool owneds03 { get; set; }
public double healthPotionCount { get; set; }
public int equipedWeapon { get; set; }
public int equipedShield { get; set; }
public int playerLevel { get; set; }
public int playerExpEarned { get; set; }
to save and exit
( this part does work, it does create the file):
static void closeAndSave()
{
string folder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
folder = Path.Combine(folder, "RNGgameSaveFiles");
Directory.CreateDirectory(folder);
string dataFile = Path.Combine(folder, "RNGgameSaveFileV1");
using (Stream stateStream = File.Create(dataFile))
{
BinaryFormatter serializer = new BinaryFormatter();
serializer.Serialize(stateStream, stateVariables);
}
}
You've got some code that puts values into stateVariables and serializes it, but you have to do the opposite as well - ie, read the values from it and set your static members to those values.

Json class saving a value while containing other default values

Hey all I am trying to figure out how to go about saving just one value in my JSON class instead of having to write the whole JSON out again with "New". I am using the Newton JSON.Net.
This is my JSON structure:
public class GV
{
public class Data
{
[JsonProperty("pathForNESPosters")]
public static string PathForNESPosters { get; set; }
[JsonProperty("pathForSNESPosters")]
public static string PathForSNESPosters { get; set; }
[JsonProperty("pathForSEGAPosters")]
public static string PathForSEGAPosters { get; set; }
[JsonProperty("pathToNESContent")]
public static string PathToNESContent { get; set; }
[JsonProperty("pathToSNESContent")]
public static string PathToSNESContent { get; set; }
[JsonProperty("pathToSEGAContent")]
public static string PathToSEGAContent { get; set; }
[JsonProperty("lastSavedVolume")]
public static double LastSavedVolume { get; set; }
}
public class Root
{
public Data data { get; set; }
}
And I have no issues with loading that data from a file into my class:
GV.Root myDeserializedClass = JsonConvert.DeserializeObject<GV.Root>(File.ReadAllText(
currentAssemblyPath + String.Format(#"\Resources\{0}", "dataForLinks.json")
));
But I have yet to find anything searching that will let me do one update to an object in the class without wiping it out doing a New statement.
What I am wanting to do is something like the following:
-Load the json into my class object [Done]
-Save a value thats in my class object [stuck here]
GV.pathToNESContent = "new value here";
-Save class object (with the one new value) back to the file for which it came from preserving the other original values. [not here yet]
When I update just that one class object I am wanting to contain the original values for all the other JSON data I read in from the file.
Anyone have a good example of the above you can share?
update
I'd ditch the inner class structure:
namespace GV
{
public class Data
{
[JsonProperty("pathForNESPosters")]
public string PathForNESPosters { get; set; }
[JsonProperty("pathForSNESPosters")]
public string PathForSNESPosters { get; set; }
[JsonProperty("pathForSEGAPosters")]
public string PathForSEGAPosters { get; set; }
[JsonProperty("pathToNESContent")]
public string PathToNESContent { get; set; }
[JsonProperty("pathToSNESContent")]
public string PathToSNESContent { get; set; }
[JsonProperty("pathToSEGAContent")]
public string PathToSEGAContent { get; set; }
[JsonProperty("lastSavedVolume")]
public double LastSavedVolume { get; set; }
}
public class Root
{
public Data Data { get; set; }
}
Deser (use Path.Combine to build paths, not string concat):
var x = JsonConvert.DeserializeObject<GV.Root>(File.ReadAllText(
Path.Combine(currentAssemblyPath, "Resources", "dataForLinks.json"))
));
Edit:
x.Data.PathToNESContent = "...";
and re-ser

What is wrong in my class hierarchy for an xml deserialization?

I'm trying to deserialize the following xml document into a C# object:
<ns1:StockerFichiers
xmlns:ns1="http://www.foo.fr/bar/Repository"
xmlns:ns0="http://www.foo.fr/bar/Transport/">
<ns1:fichiersAStocker>
<ns0:FichierIdentifie>
<ns0:Contenu></ns0:Contenu>
<ns0:DomaineIdLocalDoc>128</ns0:DomaineIdLocalDoc>
<ns0:EstOriginal>true</ns0:EstOriginal>
<ns0:IdLocalDoc>2018-07-06T154554_70183_2</ns0:IdLocalDoc>
<ns0:PieceDynamique>false</ns0:PieceDynamique>
<ns0:GoldenSource>false</ns0:GoldenSource>
<ns0:TypeDoc>PDF</ns0:TypeDoc>
<ns0:TypeMime>application/pdf</ns0:TypeMime>
</ns0:FichierIdentifie>
</ns1:fichiersAStocker>
</ns1:StockerFichiers>
I know a lot of deserialization questions already exist, but even if some seems to be solving the same issue I face, None of what I've tried did populate my List<FichierIdentifie>.
Where I deserialize:
public void StockerFichiersXmlBase64(string fichiersAStocker)
{
//serializer
XmlRootAttribute xroot = new XmlRootAttribute();
xroot.ElementName = "StockerFichiers";
xroot.Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY; //ns1
XmlSerializer deserializer = new XmlSerializer(typeof(StockerFichiersRoot),xroot );
//fichiersAStocker is base64 encoded
byte[] data = Convert.FromBase64String(fichiersAStocker);
StringReader stringReader = new StringReader(Encoding.UTF8.GetString(data));
//deserialization
StockerFichiersRoot deserializedFiles = (StockerFichiersRoot)deserializer.Deserialize(stringReader);
}
My current version :
// Root
[XmlRoot(ElementName = "StockerFichiers", Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY)]
public class StockerFichiersRoot
{
[XmlElement(ElementName = "fichiersAStocker", Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY)]
public FichiersAStocker fichiersAStocker { get; set; }
}
//sub root
public class FichiersAStocker
{
[XmlArray(ElementName = "fichiersAStocker", Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY)]
[XmlArrayItem(ElementName = "FichierIdentifie", Namespace=NamespacesConstantes.NAMESPACE_MSS_TRANSPORT)]
public List<FichierIdentifie> FichiersIdentifie { get; set; }
}
public class FichierIdentifie
{
[XmlElement(Namespace = NamespacesConstantes.NAMESPACE_TRANSPORT)]
public byte[] Contenu { get; set; }
//all fields are similar to the first one
}
And with this variation of the subroot class according to Is it possible to deserialize XML into List<T>? :
//sub root
public class FichiersAStocker
{
[XmlElement(ElementName = "FichierIdentifie", Namespace=NamespacesConstantes.NAMESPACE_MSS_TRANSPORT)]
public List<FichierIdentifie> FichiersIdentifie { get; set; }
}
I've also tried to remove the class FichiersAStocker (the sub root), to put the List<FichierIdentifie> in the root class, with both [xmlArray..] and [XmlElement] variations but with no success.
I always get an object with the list empty.
Try using XML2CSharp to generate class. Then try using that class or use it for debugging.
Generated code for your XML looks like this:
(You can remove unwanted properties)
/*
Licensed under the Apache License, Version 2.0
http://www.apache.org/licenses/LICENSE-2.0
*/
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace Xml2CSharp
{
[XmlRoot(ElementName="FichierIdentifie", Namespace="http://www.foo.fr/bar/Transport/")]
public class FichierIdentifie {
[XmlElement(ElementName="Contenu", Namespace="http://www.foo.fr/bar/Transport/")]
public string Contenu { get; set; }
[XmlElement(ElementName="DomaineIdLocalDoc", Namespace="http://www.foo.fr/bar/Transport/")]
public string DomaineIdLocalDoc { get; set; }
[XmlElement(ElementName="EstOriginal", Namespace="http://www.foo.fr/bar/Transport/")]
public string EstOriginal { get; set; }
[XmlElement(ElementName="IdLocalDoc", Namespace="http://www.foo.fr/bar/Transport/")]
public string IdLocalDoc { get; set; }
[XmlElement(ElementName="PieceDynamique", Namespace="http://www.foo.fr/bar/Transport/")]
public string PieceDynamique { get; set; }
[XmlElement(ElementName="SisraGoldenSource", Namespace="http://www.foo.fr/bar/Transport/")]
public string SisraGoldenSource { get; set; }
[XmlElement(ElementName="TypeDocSisra", Namespace="http://www.foo.fr/bar/Transport/")]
public string TypeDocSisra { get; set; }
[XmlElement(ElementName="TypeMime", Namespace="http://www.foo.fr/bar/Transport/")]
public string TypeMime { get; set; }
}
[XmlRoot(ElementName="fichiersAStocker", Namespace="http://www.foo.fr/bar/Repository")]
public class FichiersAStocker {
[XmlElement(ElementName="FichierIdentifie", Namespace="http://www.foo.fr/bar/Transport/")]
public FichierIdentifie FichierIdentifie { get; set; }
}
[XmlRoot(ElementName="StockerFichiers", Namespace="http://www.foo.fr/bar/Repository")]
public class StockerFichiers {
[XmlElement(ElementName="fichiersAStocker", Namespace="http://www.foo.fr/bar/Repository")]
public FichiersAStocker FichiersAStocker { get; set; }
[XmlAttribute(AttributeName="ns1", Namespace="http://www.w3.org/2000/xmlns/")]
public string Ns1 { get; set; }
[XmlAttribute(AttributeName="ns0", Namespace="http://www.w3.org/2000/xmlns/")]
public string Ns0 { get; set; }
}
}
Really frustrating mistake that took me half a day to solve :
notice how "NamespacesConstantes.NAMESPACE_MSS_TRANSPORT" is close to "NamespacesConstantes.NAMESPACE_TRANSPORT". Add some lazy autocompletion and you can fool yourself while defining the [XmlElement...] in the "FichiersAStocker" class.
Thanks for your help Matt, I noticed this mistake while i paste some of my code on https://dotnetfiddle.net/ ! :)

How to deserialize the above JSON string to datatable in c#

How can I deserialize the following JSON string to a datatable in c#
{
"m_MaxCapacity":2147483647,
"Capacity":1888,
"m_StringValue":"<table border=3><tr><th>Master ID</th><th>Tag ID</th><th>Plant ID</th><th>Machine Name</th><th>Sap ID</th><th>Log</th></tr><tr><td>2296</td><td>567</td><td>567</td><td>hjhnh</td><td>567</td><td>17-09-2016 15:03:04</td></tr><tr><td>2297</td><td>55555</td><td>567</td><td>hjhnh</td><td>567</td><td>17-09-2016 15:04:27</td></tr><tr><td>2298</td><td>55555</td><td>567</td><td>hjhnh</td><td>0000</td><td>17-09-2016 15:04:53</td></tr><tr><td>2299</td><td>55555</td><td>567</td><td>hjhnh</td><td>0000</td><td>17-09-2016 15:05:11</td></tr><tr><td>2300</td><td>6678</td><td>6754</td><td>nnn</td><td>789</td><td>17-09-2016 15:20:51</td></tr><tr><td>2301</td><td>6678</td><td>6754</td><td>AF</td><td>789</td><td>17-09-2016 15:23:57</td></tr><tr><td>2302</td><td>6678</td><td>6754</td><td>ttttttt</td><td>789</td><td>17-09-2016 15:33:22</td></tr><tr><td>2303</td><td>6678</td><td>6754</td><td>ttttttt</td><td>789</td><td>17-09-2016 15:43:10</td></tr><tr><td>2304</td><td>6678</td><td>6754</td><td>ttttttt</td><td>789</td><td>17-09-2016 15:43:23</td></tr><tr><td>2305</td><td>6678</td><td>6754</td><td>ttttttt</td><td>789</td><td>17-09-2016 15:43:50</td></tr><tr><td>2306</td><td>6678</td><td>6754</td><td>lmno</td><td>789</td><td>17-09-2016 15:49:25</td></tr><tr><td>2307</td><td>6678</td><td>6754</td><td>ttttttt</td><td>789</td><td>22-09-2016 11:23:16</td></tr><tr><td>2308</td><td>6678</td><td>6754</td><td>ttttttt</td><td>789</td><td>22-09-2016 11:40:07</td></tr><tr><td>2309</td><td>6678</td><td>6754</td><td>ccccc</td><td>789</td><td>22-09-2016 11:40:18</td></tr><tr><td>2310</td><td>6678</td><td>6754</td><td>ttttttt</td><td>789</td><td>22-09-2016 11:45:53</td></tr><tr><td>2311</td><td>6678</td><td>6754</td><td>ttttttt</td><td>789</td><td>22-09-2016 12:00:48</td></tr><tr><td>2312</td><td>6678</td><td>6754</td><td>mmmmmmmmmm</td><td>789</td><td>22-09-2016 12:00:52</td></tr></table>",
"m_currentThread":0
}
Any ideas welcome.
First you have to add package Newtonsoft.Json to your project.Next create class with object. You can use http://json2csharp.com/ it's very helpfull tool. Finally you have to Deserialize yours json. Try use this sample.
public class RootObject
{
public long m_MaxCapacity { get; set; }
public int Capacity { get; set; }
public string m_StringValue { get; set; }
public int m_currentThread { get; set; }
}
string json= {"m_MaxCapacity":2147483647,"Capacity":1888,"m_StringValue":"Master IDTag IDPlant IDMachine NameSap IDLog2296567567hjhnh56717-09-2016 15:03:04229755555567hjhnh56717-09-2016 15:04:27229855555567hjhnh000017-09-2016 15:04:53229955555567hjhnh000017-09-2016 15:05:11230066786754nnn78917-09-2016 15:20:51230166786754AF78917-09-2016 15:23:57230266786754ttttttt78917-09-2016 15:33:22230366786754ttttttt78917-09-2016 15:43:10230466786754ttttttt78917-09-2016 15:43:23230566786754ttttttt78917-09-2016 15:43:50230666786754lmno78917-09-2016 15:49:25230766786754ttttttt78922-09-2016 11:23:16230866786754ttttttt78922-09-2016 11:40:07230966786754ccccc78922-09-2016 11:40:18231066786754ttttttt78922-09-2016 11:45:53231166786754ttttttt78922-09-2016 12:00:48231266786754mmmmmmmmmm78922-09-2016 12:00:52","m_currentThread":0}
List<RootObject> list = new List<RootObject>();
list= JsonConvert.DeserializeObject<List<RootObject>>(json);
you can use: http://json2csharp.com/
there you get the class:
public class RootObject
{
public long m_MaxCapacity { get; set; }
public int Capacity { get; set; }
public string m_StringValue { get; set; }
public int m_currentThread { get; set; }
}
then you can add it to your context.

Xml Deserialize returms null values but xml has values

I saw few topics but no one looks like my problem.
Here is my class:
namespace Framework.Cielo.Models
{
[XmlRoot("transacao", Namespace = "http://ecommerce.cbmp.com.br")]
public class TransactionResponse
{
[XmlAttribute("id")]
public string ID { get; set; }
[XmlAttribute("versao")]
public string Version { get; set; }
[XmlElement("tid")]
public string tid { get; set; }
[XmlElement("pan")]
public string pan { get; set; }
[XmlElement("dados-pedido")]
public EstablishmentOrder Order { get; set; }
[XmlElement("forma-pagamento")]
public PaymentMethod PaymentMethod { get; set; }
[XmlElement("status")]
public TransactionStatusEnum Status { get; set; }
[XmlElement("url-retorno")]
public string ReturnUrl { get; set; }
[XmlElement("autenticacao")]
public Authentication Authentication { get; set; }
}
}
and here is the authentication class
namespace Framework.Cielo.Models
{
[XmlRoot("autenticacao")]
public class Authentication
{
[XmlElement("codigo")]
public int Code { get; set; }
[XmlElement("mensagem")]
public string Message { get; set; }
[XmlIgnore]
public DateTime Date { get; set; }
[XmlElement("data-hora")]
public string FormattedDate
{
get
{
return Date.ToString("yyyy-MM-ddTHH:mm:ss");
}
set
{
DateTime kdc = DateTime.MinValue;
DateTime.TryParse(value, out kdc);
Date = kdc;
}
}
[XmlElement("valor")]
public int Value { get; set; }
[XmlElement("lr")]
public int SecurityLevel { get; set; }
[XmlElement("arp")]
public object arp { get; set; }
[XmlElement("nsu")]
public object nsu { get; set; }
}
}
Here is how I deserialize:
string serializado = File.ReadAllText("req.xml");
var stringReader = new System.IO.StringReader(serializado);
var serializer = new XmlSerializer(typeof(TransactionResponse));
TransactionResponse preAuthResponse = serializer.Deserialize(stringReader) as TransactionResponse;
and here is my XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<transacao versao="1.3.0" id="100" xmlns="http://ecommerce.cbmp.com.br">
<tid>10069930690A16DF1001</tid>
<pan>b1SQ6jpKCDt3n9C0dgD/ZkPQ1Bh+7aJESqr/CwP64P0=</pan>
<dados-pedido>
<numero>100</numero>
<valor>29900</valor>
<moeda>986</moeda>
<data-hora>2013-10-15T00:57:19.032-03:00</data-hora>
<descricao/>
<idioma>PT</idioma>
<taxa-embarque>0</taxa-embarque>
</dados-pedido>
<forma-pagamento>
<bandeira>mastercard</bandeira>
<produto>1</produto>
<parcelas>1</parcelas>
</forma-pagamento>
<status>4</status>
<autenticacao>
<codigo>4</codigo>
<mensagem>Transacao sem autenticacao</mensagem>
<data-hora>2013-10-15T00:57:19.037-03:00</data-hora>
<valor>29900</valor>
<eci>0</eci>
</autenticacao>
<autorizacao>
<codigo>4</codigo>
<mensagem>Transação autorizada</mensagem>
<data-hora>2013-10-15T00:57:19.041-03:00</data-hora>
<valor>29900</valor>
<lr>00</lr>
<arp>123456</arp>
<nsu>661215</nsu>
</autorizacao>
</transacao>
When I run this code, all the elements get right, but not ARP and NSU elements (the last 2 of autorizacao tag)
I really don't know why. This XML comes from a web service and I can't figure out why my deserialize don't work with the 2 last items but works greater with any other element.
I have tried with your code and updated following and it works.
Commented second last <autenticacao> tag.
Rename last tag <autorizacao> to <autenticacao> . May be you are getting wrong xml & last two tags are confusing so I have tried with only one tag.
In Authentication class I have changed type of ARP and NSU otherwise we are getting XMlNode type while deserializing. You can also use string instead of int.
[XmlElement("arp")]
public int arp { get; set; }
[XmlElement("nsu")]
public int nsu { get; set; }

Categories