Specific Namespace in XML Deserialization fails - c#

I looked for an issue but couldn't find the answer the this particular case, so here is the issue.
When trying to deserialize a xml string into a strong type object I got the following message:
System.InvalidOperationException: There is an error in XML document (1, 2). ---> System.InvalidOperationException: <GetPointOfDelivery_Out xmlns='urn:webbeB2B:webservices:v0'> was not expected.
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderGetPointOfDelivery_Out.Read16_GetPointOfDelivery_Out()
Although the class has to my opinion the correct namespace attribute value defined, being :
[XmlType(AnonymousType = true, Namespace = "urn:webbeB2B:webservices:v0")]
public class GetPointOfDelivery_Out
{
[XmlElement("POD")]
public POD[] POD
….
}
The source string looks like this:
<out:GetPointOfDelivery_Out xmlns:out="urn:webbeB2B:webservices:v0">
<out:POD>
<out:PODID>FT}UntwKNFlX0000h100Dm</out:PODID>
….
</out:POD>
<out:ErrorMessage>
<out:MsgType>S</out:MsgType>
</out:ErrorMessage>
</out:GetPointOfDelivery_Out>
I use the following code to deserialize the string
var xmlSerializer = new XmlSerializer(typeof(T));
using (var textReader = new StringReader(xml))
{
return (T)xmlSerializer.Deserialize(textReader);
}
(Where T is GetPointOfDelivery_Out and xml the example given above.)
Any help is welcome.

While looking somewhat deeper into stack overflow I found the answer in the following post:
https://stackoverflow.com/a/1232328/1145146
I added the XmlRoot attribute on the target class to be deserialized
[Serializable]
[XmlRoot("GetPointOfDelivery_Out", Namespace = "urn:webbeB2B:webservices:v0")]
[XmlType(AnonymousType = true, Namespace = "urn:webbeB2B:webservices:v0")]
public class GetPointOfDelivery_Out

Related

WCF error: Expecting state 'Element'.. Encountered 'Text' with name '', namespace '' post call in XML format

I have a WCF service method that can't deserialize the post in XML format and will error with
Error in line 14 position 30. Expecting state 'Element'.. Encountered
'Text' with name '', namespace ''
I narrow down to the specific section like the reproducible sample below
var xmlSrc = #"<Keys>
<ProductKeyID>123</ProductKeyID>
<ProductKeyID>124</ProductKeyID>
<ProductKeyID>125</ProductKeyID>
</Keys>";
DataContractSerializer serializer = new DataContractSerializer(typeof(Keys));
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xmlSrc)))
{
var i = (Keys)serializer.ReadObject(stream);
}
[DataContract(Namespace = "")]
[Serializable]
public class Keys
{
[DataMember(Order = 1)]
public List<string> ProductKeyID { get; set; }
}
How to adjust the C# class to deserialize the XML properly?
I do search the post exists but most of them are json format and do not seem to help my case.
As an alternative you can use CollectionDataContract attribute. Your class Keys will be inherited from List. In CollectionDataContract attribute specify name of the root element and name of items.
[CollectionDataContract(Name = "Keys", ItemName = "ProductKeyID", Namespace ="")]
public class Keys<T> : List<T>
{
}
DataContractSerializer serializer = new DataContractSerializer(typeof(Keys<string>));
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xmlSrc)))
{
var i = (Keys<string>)serializer.ReadObject(stream);
}

How to set Namespace for DataContract?

I have a situation where I have a REST controller that is called by a user and this controller then requests data from upstream and receives JSON as a response. This JSON is then transformed into XML and send back to the user as a response.
The problem is that I am not able to set specific namespace for the XML root element. I am using DataContractSerializer.
I am not really experienced with .NET and have previously worked mainly with JSON so i am a bit lost as to what to try next.
I have tried to set the namespace using ContractNamespaceAttribute like:
[assembly: ContractNamespaceAttribute("http://schemas.datacontract.org/2004/07/APIBridge.Models", ClrNamespace = "APIBridge.Models")]
namespace APIBridge.Models
{
[DataContract]
public class Order
{
// DataMembers here...
}
}
And I also tried setting the namespace in the DataContracAttribute like:
namespace APIBridge.Models
{
[DataContract(Name = "Order", Namespace =
"http://schemas.datacontract.org/2004/07/APIBridge.Models")]
public class Order
{
// Datamembers here...
}
}
How I would like the namespace to be set is:
<ArrayOfOrder xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/APIBridge.Models">
But the actual result is:
<ArrayOfOrder xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.datacontractattribute?redirectedfrom=MSDN&view=netframework-4.8
In the DataContractAttribute documentation above it says:
"By default, when you apply the DataContractAttribute to a class, it uses the class name as the local name and the class's namespace (prefixed with "http://schemas.datacontract.org/2004/07/") as the namespace URI."
This actually would be the desired result but also as a default namespace I get the same result that is mentioned above. Why is this?
Any ideas?
UPDATE: Below requested service operation
public List<Order> loadOrdersBasic(UserOptions userOpts)
{
List<Order> orders = new List<Order>();
HttpClient httpClient = AuthenticationHelper.CreateHttpClient(userOpts, options);
String url = String.Format("api/orders?supplier_no={0}", userOpts.SupplierId);
HttpResponseMessage response = httpClient.GetAsync(url).Result;
if (response.IsSuccessStatusCode)
{
orders = response.Content.ReadAsAsync<List<Order>>().Result;
}
else {
throw new ServiceException(getHttpErrorMessage(url, response));
}
return orders;
}
Answering to my own question.
Turned out that I had missed one line in my configuration file where XmlMediaTypeFormatter was set to use XmlSerializer instead of DataContractSerializer. This overrode the default namespace.

How To Track Down Deserialize XML to Object Error in XSD?

This is a sample of my xml file:
<IFX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="finalizacaoOrcamentoVO">
<dadosOrcamento>...</dadosOrcamento>
<faturamento>...</faturamento>
</IFX>
This is my auto-generated by Visual Studio object class:
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class IFX
{
private IFXDadosOrcamento dadosOrcamentoField;
private IFXFaturamento faturamentoField;
But I've been getting this error every time I try to deserialize:
Message "Error document XML (1, 57)." string
This is my deserialize method:
IFX document;
XmlSerializer serializer = new XmlSerializer(typeof(object));
using (var reader = XmlReader.Create(file.InputStream))
{
document = (IFX)serializer.Deserialize(reader);
}
Any hint on what should be fixed?
Thanks in advance!
These are my subclasses:
ClassObject
The xsi:type attribute, short for {http://www.w3.org/2001/XMLSchema-instance}type, is a w3c standard attribute that is used to explicitly assert the type of its element. As explained in Xsi:type Attribute Binding Support, XmlSerializer interprets this to mean that the element is serialized from a polymorphic derived type of the expected type.
I.e. if your XML looks like:
<IFX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="finalizacaoOrcamentoVO">
<dadosOrcamento>
<IFXDadosOrcamentoValue>A IFXDadosOrcamentoValue</IFXDadosOrcamentoValue>
</dadosOrcamento>
</IFX>
Then XmlSerializer expects that the following classes will exist:
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
[XmlInclude(typeof(finalizacaoOrcamentoVO))]
public partial class IFX
{
private IFXDadosOrcamento dadosOrcamentoField;
public IFXDadosOrcamento dadosOrcamento { get { return dadosOrcamentoField; } set { dadosOrcamentoField = value; } }
}
public class finalizacaoOrcamentoVO : IFX
{
// This derived type may have some or all of the properties shown as elements in the XML file.
}
public class IFXDadosOrcamento
{
public string IFXDadosOrcamentoValue { get; set; }
}
Where finalizacaoOrcamentoVO is a type that inherits from IFX.
Note the presence of [XmlInclude(typeof(finalizacaoOrcamentoVO))]. This attribute informs the serializer of the subtypes that might be encountered and must be present for every allowed subtype.
Having done this, the XML can now be deserialized via:
IFX document;
XmlSerializer serializer = new XmlSerializer(typeof(IFX));
using (var reader = XmlReader.Create(inputStream))
{
document = (IFX)serializer.Deserialize(reader);
}
An instance of finalizacaoOrcamentoVO will actually get created thereby.
That being said, in your comment you state that your auto-generated classes do not include a derived type finalizacaoOrcamentoVO. If you generated the classes from an XSD, then the XSD and XML do not match and you should get that resolved. If you generated the classes by pasting this very XML into Visual Studio, then there might be a bug or limitation in Visual Studio's code generation, which can be fixed manually as shown above.
If you really want to ignore the xsi:type attribute, then you will have to do so manually, since support for it is built-in to the serializer. One way is to load into an intermediate XDocument:
XDocument xDoc;
using (var reader = XmlReader.Create(inputStream))
{
xDoc = XDocument.Load(reader);
}
var attr = xDoc.Root.Attribute("{http://www.w3.org/2001/XMLSchema-instance}type");
if (attr != null)
attr.Remove();
var document = xDoc.Deserialize<IFX>();
Using the extension method:
public static class XObjectExtensions
{
public static T Deserialize<T>(this XContainer element, XmlSerializer serializer = null)
{
if (element == null)
throw new ArgumentNullException();
using (var reader = element.CreateReader())
return (T)(serializer ?? new XmlSerializer(typeof(T))).Deserialize(reader);
}
}

Deserialize xml. xmlns='http//someaddress' was not expected

My problem is with deserialization of xml to c# objects. I have some class derived from some other class (I have the reason why I need to use inheritance in this place - doesn't matter why):
[Serializable]
[XmlType(TypeName = "OTA_HotelResRQ")]
public class ResRQ : OTA_HotelResRQ
{
}
in OTA_HotelResRQ I have declared namespaces and other information:
[Serializable]
[XmlTypeAttribute(Namespace = "http://www.opentravel.org/OTA/2003/05")]
[XmlRootAttribute(Namespace = "http://www.opentravel.org/OTA/2003/05", IsNullable = false)]
public class OTA_HotelResRQ : OtaRequestMessage, IRequest
And when I'm trying to serialize some request which looks like below:
<ns:OTA_HotelResRQ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns="http://www.opentravel.org/OTA/2003/05"
PrimaryLangID="en" EchoToken="5613971064477293649" ResStatus="Commit" Version="2.1">
...SOME REQUEST WITH NS:....
<ns:POS><ns:/POS>
And now when I'm trying to deserialize this I have:
There is an error in XML document (3, 2). ---> System.InvalidOperationException: <OTA_HotelResRQ xmlns='http://www.opentravel.org/OTA/2003/05'> was not expected.
do you have some idea why I can't deserialize this? I can't modify base class for my model and also I need to have "ns" prefixes because service where I want to send that requires this format.
UPDATE:
My deserialization is implemented, that I'm getting bytes from string and try to deserialize using:
return (T) new XmlSerializer(typeof (T)).Deserialize(new MemoryStream(bytes));
I tried to fix it using solution provided by Charles and I updated my model:
[Serializable]
[XmlRoot("OTA_HotelResRQ", Namespace = "http://www.opentravel.org/OTA/2003/05")]
[XmlType("OTA_HotelResRQ", Namespace = "http://www.opentravel.org/OTA/2003/05")]
public class ResRQ : OTA_HotelResRQ
{
}
but still with no success. When I try to deserialize then I'm getting exception:
Types 'OTA_HotelResRQ' and
'ResRQ' both use the XML type name,
'OTA_HotelResRQ', from namespace 'http://www.opentravel.org/OTA/2003/05'. Use
XML attributes to specify a unique XML name and/or namespace for the type.
XML attributes are not inherited, so you need to add an XmlRoot attribute to your derived class:
[Serializable]
[XmlRoot("OTA_HotelResRQ", Namespace = "http://www.opentravel.org/OTA/2003/05")]
public class ResRQ : OTA_HotelResRQ
{
}

There is an error in XML document (2, 2).What does this mean?

I am trying to read XML document.
My XML:
<?xml version="1.0" encoding="utf-8"?>
<SplashScreen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Path>SplashScreen/Image-King</Path>
</SplashScreen>
My code which is reading XML:
XmlGameScreen = new XmlManager<GameScreen>();
XmlGameScreen.Type = currentscreen.Type;
currentscreen = XmlGameScreen.Load("LoadXML/SplashScreen.xml");
And
public Type Type;
public T Load(string path)
{
T instance;
using (TextReader textreader = new StreamReader(path))
{
XmlSerializer xml = new XmlSerializer(Type);
instance = (T)xml.Deserialize(textreader);
}
return instance;
}
I am getting error on instance = (T)xml.Deserialize(textreader); Is my XML document wrong? I am trying to read <Path>.
Update :
My Internal Exception:
Cannot serialize member 'MyRPGgame.SplashScreen._image' of type 'Microsoft.Xna.Framework.Graphics.Texture2D'
In my case it appears one of the Visual Studio 2017 version 15.5 updates caused this error when trying to open SSRS projects. The solution is to delete the *.rptproj.rsuser file from the project folder and try again.
My experience from it would be that in the 2nd line in the 2nd chararacter, there is an error.
have a look if your class names are different from the XML tags. are you maybe changing the "XML Root name" to a different one.
Have a look at the XML structure and which class are you serializing to which node.
Also, read the
MSDN Documentation about the XmlRootAttribute Class.
That usually means you have whitespace at the start of the file; check for a line-break before the <?xml.... Even better: please show the first few bytes (preferably as far as <SplashScreen) of the file as viewed in a binary editor.
It could also mean you have an invisible unicode or control character somewhere before the <SplashScreen
Just wanted to share what worked for me. I had a similar error
System.InvalidOperationException: There is an error in XML document (1, 40).
---> System.InvalidOperationException: <tsResponse xmlns='http://xxxyyyzzzz.com/api'> was not expected.
I was trying to deserialize a string to an object of type tsResponse.
After adding the following attribute [Serializable, XmlRoot(ElementName = "tsResponse", Namespace = "http://xxxyyyzzzz.com/api")] to the class tsResponse i was able to resolve my issue.
[Serializable, XmlRoot(ElementName = "tsResponse", Namespace = "http://xxxyyyzzzz.com/api")]
public class tsResponse
{
[XmlElement]
public CredentialsXml credentials { get; set; }
}
I.e had to add Namespace attribute (System.Xml.Serialization).
Try this: When you are deserializing XML to List just add an extra
line to the start i.e ArrayOfAddressDirectory as follows and don't put any space at start and end of file.
<?xml version="1.0"?>
<ArrayOfAddressDirectory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<AddressDirectory>
<Owner>MS. Dhoni</Owner>
<Age>48</Age>
<Company>India</Company>
</AddressDirectory>
</ArrayOfAddressDirectory>
Here is the C# code:
namespace XmlReadProgram
{
public class AddressDirectory
{
public string Owner { get; set; }
public string Age { get; set; }
public string Company { get; set; }
}
public class Program
{
static void Main(string[] args)
{
List<AddressDirectory> adlist = new List<AddressDirectory>();
using (FileStream fileStream = File.OpenRead(#"E:\inputDirectory\address.xml"))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<AddressDirectory>));
adlist = (List<AddressDirectory>)serializer.Deserialize(fileStream);
}
//You can use foreach to print all data
Console.WriteLine(adlist[0].Owner);
Console.WriteLine(adlist[0].Age);
Console.WriteLine(adlist[0].Company);
}
}
}
In my case, a property with [XmlArrayAttribute] had the getter accessing a field with [XmlIgnoreAttribute] that was left uninitialized.
The problem in your case it's definitely the confusion between Type and template T. You are trying to construct Serializer with Type --> new XmlSerializer(Type) and then deserialize with template T ----> (T)xml.Deserialize. So the solution is to replace Type in constructing with typeof(T), and this should eliminate the initial XML document problem of (2, 2).

Categories

Resources