Error while deserializing an XML document using RestSharp - c#

I am trying to deserialize the following XML response using RestSharp:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:payload xmlns:ns0="http://www.website.co.za/JSON_Token">
<ns0:content>
<ns0:reason>token successfully created</ns0:reason>
<ns0:success>true</ns0:success>
<ns0:authDetails>
<ns0:accessToken>feefaee94822a92ca7f134f74588cc69081b0e94</ns0:accessToken>
<ns0:expiresIn>604800</ns0:expiresIn>
<ns0:refreshToken>bc036cba4d346bf76809e143879cb8fb6983940c</ns0:refreshToken>
</ns0:authDetails>
</ns0:content>
This is a snapshot of my code:
IRestResponse response = client.Execute(request);
RestSharp.Deserializers.XmlDeserializer deserial = new RestSharp.Deserializers.XmlDeserializer();
payload apiresponse = deserial.Deserialize<payload>(response);
And this is the error that I am getting:
An unhandled exception of type 'System.Xml.XmlException' occurred in
System.Xml.dll Additional information: Data at the root level is
invalid. Line 1, position 1.
any ideas what I am doing wrong?

Thanks for all the replies.
I did some more investigation and after printing the content of the response to a string, it turned out that RestSharp was actually converting it from XML to JSON. No idea why it was doing that (i certainly wasn't specifying it, perhaps it's a default setting).
So because the response was a JSON then the XML deserializing was obviously throwing an error!
Thanks again.

Well, the exception message is pretty clear: Line 1 has invalid syntax:
<ns0:payload xmlns:ns0="http://www.website.co.za/JSON_Token">
The XML should probably look like this instead:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:payload xmlns:ns0="http://www.website.co.za/JSON_Token">
<ns0:content>
<ns0:reason>token successfully created</ns0:reason>
<ns0:success>true</ns0:success>
<ns0:authDetails>
<ns0:accessToken>feefaee94822a92ca7f134f74588cc69081b0e94</ns0:accessToken>
<ns0:expiresIn>604800</ns0:expiresIn>
<ns0:refreshToken>bc036cba4d346bf76809e143879cb8fb6983940c</ns0:refreshToken>
</ns0:authDetails>
</ns0:content>
</ns0:payload>
If you cannot change how the XML response is generated, you should pre-process the XML using common string-manipulation since it is invalid XML and hence cannot be parsed using standard tools.

Related

Deserialize an xml file or parse using linq to xml

Simplified XML file I need to decode:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:deliverylistResponse xmlns:ns2="http://tdriverap3.wsbeans.iseries/">
<return>
<COUNT>3</COUNT>
<DELIVERIES>
<ADD1>1300 address 1</ADD1>
<CITY>NICE CITY</CITY>
<ZIP>85705</ZIP>
</DELIVERIES>
<DELIVERIES>
<ADD1>40 S PINAL PKWY AVE</ADD1>
<CITY>FLORENCE</CITY>
<ZIP>85132</ZIP>
</DELIVERIES>
<DELIVERIES>
<ADD1>1825 EAST MAIN</ADD1>
<CITY>CHANDLER</CITY>
<ZIP>85286</ZIP>
</DELIVERIES>
<ERRORCODE/>
<RUNDATE>09/26/2018</RUNDATE>
</return>
</ns2:deliverylistResponse>
</soap:Body>
</soap:Envelope>
I am using the following to try and decode each of the individual addresses in the code.
I cannot figure out how to access them.
XElement xelement = XElement.Load(#"e:\test\X2.xml");
IEnumerable<XElement> addresses = xelement.Elements();
foreach (var address in addresses)
{
Console.WriteLine(address);
Console.WriteLine(address.Element("CITY").Value);
}
The first writeline works (it outputs the entire XML tree), the second says "System.Xml.Linq.XContainer.Element(...) returned null" - I have tried using DELIVERIES, COUNT, Body etc...
Obviously I am not telling it correctly how to traverse the structure, but I do not know how to go any further with it..
UPDATE: Thanks to some help I have figured out how to do it using Linq.
I would still like to be able to deserialize it if anybody has a pointer.
I followed several tutorials, but the multiple levels of this XML seems to be throwing me off.
I have created a class to hold the data but that is as far as my success with that path has gone.
Thank you,
Joe
Thank you Crowcoder -- this is what I wound up with, which will work.
The real XML file however does have about 60 fields so this is not as good as using a deserialize routine but I can at least move forward with the project.
XElement xelement = XElement.Load(#"e:\test\x2.xml");
IEnumerable<XElement> textSegs =
from seg in xelement.Descendants("DELIVERIES")
select seg;
foreach (var address in textSegs)
{
Console.WriteLine(address.Element("ADD1").Value);
Console.WriteLine(address.Element("CITY").Value);
Console.WriteLine(address.Element("ZIP").Value);
}
Console.ReadKey();

Asternet AGI GeneralMappingStrategy using XML

I am trying to use XML for my GeneralMappingStrategy in Asternet. I have my program working fine using List
such as:
agiServer.MappingStrategy = new GeneralMappingStrategy(
new List<ScriptMapping>()
{
new ScriptMapping() {
ScriptName = "testIVR",
ScriptClass = "Asterisk_Test.testIVR",
}
});
But I'd rather have it read an XML file as it says it can do in the documentation, however it does not seem to say anywhere what the XML format is required.
I have tried:
string pathtoxml = "test.xml";
agiServer.MappingStrategy = new GeneralMappingStrategy(pathtoxml);
With my XML as:
<?xml version="1.0"?>
<ScriptMapping>
<ScriptName>testIVR</ScriptName>
<ScriptClass>Asterisk_Test.testIVR</ScriptClass>
</ScriptMapping>
As a complete guess, seemed to make sense, but this won't compile, I get errors of:
System.InvalidOperationException: 'There was an error reflecting type 'System.Collections.Generic.List`1[AsterNET.FastAGI.MappingStrategies.ScriptMapping]'.'
Does anyone happen to know how to do this?
It appears that there was an issue with the Aster.NET library, I've now submitted the fix and it's been accepted. For anyone who has an issue on this in the future, the XML format is:
<?xml version="1.0"?>
<ArrayOfScriptMapping xmlns:xsi="w3.org/2001/XMLSchema-instance"; xmlns:xsd="w3.org/2001/XMLSchema">
<ScriptMapping>
<ScriptName>testIVR</ScriptName>
<ScriptClass>Asterisk_newTest.testIVR</ScriptClass>
</ScriptMapping>
</ArrayOfScriptMapping>

Error while reading body of request message

I need to read content of message in WCF project like
var messageContent = Encoding.UTF8.GetString(OperationContext.Current.RequestContext.RequestMessage.GetBody<byte[]>());
But in result I got an error:
Expecting element 'base64Binary' from namespace
'http://schemas.microsoft.com/2003/10/Serialization/'.. Encountered
'Element' with name 'Human', namespace
'http://numans.hr-xml.org/2007-04-15'.
Can you please suggest me what Im doing wrong?
Content that I'm sending are:
<Human xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://numans.hr-xml.org/2007-04-15">
<HumanId>
<guid>c2ee9a7e-c7a8-48e0-910b-47c2012bfa8e</guid>
</HumanId>
...
</Human>
Also I tried to read content like:
var messageContent = OperationContext.Current.RequestContext.RequestMessage.ToString();
Result of messageContent:
...stream...
GetBody<T> is used to deserialize the message body as type T. So when you call GetBody<byte[]>(), the deserializer expects base64-encoded binary data but finds the <Human> element.
If you only want to read the message body as string, use GetReaderAtBodyContents which returns an XmlDictionaryReader, at which you can use ReadOuterXml().
If you want to read the body as typed content, create a Human class from its XML representation and use GetBody<Human>().

dotnetrdf xml exception using QueryWithResultSet

I have an asp.net project in which, I would like to query DBPedia.
Using the following code I am getting an error:
public string testEndpoint()
{
//TEST02
SparqlRemoteEndpoint endpoint = new SparqlRemoteEndpoint(new Uri("http://dbpedia.org/sparql"), "http://dbpedia.org");
string res = "";
//Make a SELECT query against the Endpoint
SparqlResultSet results = endpoint.QueryWithResultSet("SELECT ?year WHERE {dbpedia:Rihanna dbpedia-owl:birthYear ?year}");
foreach (SparqlResult result in results)
{
res = result.ToString();
Console.WriteLine(result.ToString());}
Error message: "An exception of type 'System.Xml.XmlException' occurred in dotNetRDF.dll but was not handled in user code".
Even if I handle the exception the method cannot be executed. Regarding the details it says that there is an invalid XML-version 1.1.
As the XML comes from DBPedia I don't know how to change the xml version or how else I can handle this problem.
Virtuoso, which is the triple store used behind the dbpedia SPARQL endpoint, has updated its XML result generation. They replaced the XML version 1.0 with 1.1 in this commit. This causes the exception in the dotNetRDF parser.
Later on Virtuoso reverted the changes in the XML header. Hopefully DBPedia will update their binaries soon, so the old XML header appears again in the SPARQL results.
Source: http://github.com/openlink/virtuoso-opensource/issues/405

Lost prefix's definitions after deserialization of WCF message

I develop WCF-client. My client should validate incoming messages.
One of the messages has the following structure:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Header>...</SOAP-ENV:Header>
<SOAP-ENV:Body>
<OpDescriptionResponse>
<Field Name="DateTime" Type="xsd:dateTime">
</OpDescriptionResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
In this case the client should validate: the field "DateTime" has type "dateTime" from namespace "http://www.w3.org/2001/XMLSchema".
This response is deserialized in structure containing array of XmlElement.
But I have an issue: after message is deserialized and I received corresponding variable, containing all Field nodes I can't determine value of prefix "xsd", i.e. if I take any elementof type XMLElement corresponding to Field node in reply and call element.GetNamespaceOfPrefix("xsd") I get empty string as result.
How can I get prefix's definitions are saved after deserialization?
Help me please to overcome this issue.
In order to influence the namespace/prefix, you need to use XmlSerializerNamespaces.
The following code provides a rough reference:
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add("prefixHere", "http://namespace.here/");
XmlSerializer tempSerializer = new XmlSerializer(messageObject.GetType());
tempSerializer.Serialize(Console.Out, messageObject, namespaces);
Regards,

Categories

Resources