This is my first attempt at serializing an XML and I need to understand why errors occur in my code:
private void function(Object2 InputParameters)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer s = new XmlSerializer(typeof(Object1));
StringWriter XMLWriter = new StringWriter();
s.Serialize(XMLWriter, InputParameters, ns);
XmlDocument DOC_Xml = new XmlDocument();
DOC_Xml.LoadXml(XMLWriter.ToString());
}
InnerException:
{"An object of type 'SRV.Entities.Object2' cannot be converted to type 'SRV.Entities.Object1'."}
StackTrace:
" in System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)\r\n in System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces)\r\n "
The error line is at s.Serialize(XMLWriter, ParametrosEntrada, ns); but I don't understand the reason.
How could I solve the serialization between different objects?
Thank you, guys.
You have a bug
private void function(Object2 InputParameters)
and
XmlSerializer s = new XmlSerializer(typeof(Object1));
you need
XmlSerializer s = new XmlSerializer(typeof(Object2));
aka, you need to consistently have "Object2" as the input parameter AND the argument of "typeof".
More deeply, you can consider Generics. So you can pass the type is.... as needed . Either Object1 OR Object2. (but not both)
private void MyFunction<T>(T InputParameters)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer s = new XmlSerializer(typeof(T));
StringWriter XMLWriter = new StringWriter();
s.Serialize(XMLWriter, InputParameters, ns);
XmlDocument DOC_Xml = new XmlDocument();
DOC_Xml.LoadXml(XMLWriter.ToString());
}
You can see more at this SOF answer:
Using generics with XmlSerializer
Related
XmlTypeMapping myTypeMapping = new SoapReflectionImporter().ImportTypeMapping(typeof(AddressValidationRequest));
XmlSerializer serializer = new XmlSerializer(myTypeMapping);
TextWriter writer = new StreamWriter(filename);
serializer.Serialize(writer, request);
writer.Close();
I am trying to serialize a class into XML (SOAP). I keep receiving the error message below. Does anyone know why this might be happening?
System.InvalidOperationException: 'There was an error generating the XML document.'
InvalidOperationException: Token StartElement in state Epilog would result in an invalid XML document.
System.InvalidOperationException
HResult=0x80131509
Message=There was an error generating the XML document.
Source=System.Private.Xml
StackTrace:
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces)
at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o)
This exception was originally thrown at this call stack:
System.Xml.XmlTextWriter.AutoComplete(System.Xml.XmlTextWriter.Token)
System.Xml.XmlTextWriter.WriteStartElement(string, string, string)
System.Xml.Serialization.XmlSerializationWriter.WriteStartElement(string, string, object, bool, System.Xml.Serialization.XmlSerializerNamespaces)
System.Xml.Serialization.XmlSerializationWriter.WriteArray(string, string, object, System.Type)
System.Xml.Serialization.XmlSerializationWriter.WriteReferencedElement(string, string, object, System.Type)
System.Xml.Serialization.XmlSerializationWriter.WriteReferencedElements()
System.Xml.Serialization.ReflectionXmlSerializationWriter.GenerateTypeElement(object, System.Xml.Serialization.XmlTypeMapping)
System.Xml.Serialization.ReflectionXmlSerializationWriter.WriteObject(object)
System.Xml.Serialization.XmlSerializer.SerializeUsingReflection(System.Xml.XmlWriter, object, System.Xml.Serialization.XmlSerializerNamespaces, string, string)
System.Xml.Serialization.XmlSerializer.Serialize(System.Xml.XmlWriter, object, System.Xml.Serialization.XmlSerializerNamespaces, string, string)
Inner Exception 1:
InvalidOperationException: Token StartElement in state Epilog would result in an invalid XML document.
Use XmlTextWriter instead of TextWriter and do a writer.WriteStartElement("wrapper"):
XmlTypeMapping myTypeMapping = new SoapReflectionImporter().ImportTypeMapping(typeof(AddressValidationRequest));
XmlSerializer serializer = new XmlSerializer(myTypeMapping);
XmlTextWriter writer = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
writer.Formatting = System.Xml.Formatting.Indented;
writer.WriteStartElement("wrapper");
serializer.Serialize(writer, request);
writer.WriteEndElement();
writer.Close();
Reference:
https://learn.microsoft.com/en-us/dotnet/api/system.xml.serialization.soapreflectionimporter?view=net-6.0#examples
I have a XML structer like that
<?xml version="1.0" encoding="utf-8"?>
<Product>
<ProductName>da</ProductName>
<PluginPath></PluginPath>
<Instances></Instances>
</Product>
and i serialize my object to string.
<?xml version="1.0"?>
<Instance xmlns:xsi="http://bla bla" xmlns:xsd="bla bla" UniqueId="d4820029b7d7">
<InstanceName>Instance MyTestPluginForm</InstanceName>
<Description>Test Plugin IW</Description>
<AddedDate>2016-10-19T11:05:10.7443404+02:00</AddedDate>
<LogSettings>
<LoggingLevel>None</LoggingLevel>
<LogFilePath /><MaximumSize>100</MaximumSize
<ClearAfterDays>7</ClearAfterDays>
<IsSaveActiviesToEventLog>false</IsSaveActiviesToEventLog>
</LogSettings>
<ProductSpecific/>
</Instance>
So I want to append the second one in the Instances node in the first xml. But as you see both has xml definition on the top and after serializazion i got xmlns:xsi and xmlns:xsd attributes.
How to solve this problem?
PS: I do not want to create XML elements. Because my xml schema is dynamic. It has to be done with serialization. (I already checked this sample)
I solved the problem. using the code here
public static void CreateXmlFile(Instance instance, string filePath)
{
var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Product><ProductName>da</ProductName><PluginPath></PluginPath><Instances></Instances></Product>";
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
xmlDocument.Save(filePath);
XmlNode xnode = xmlDocument.CreateNode(XmlNodeType.Element, "Instances", null);
XmlSerializer xSeriz = new XmlSerializer(typeof(Instance));
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlWriterSettings writtersetting = new XmlWriterSettings();
writtersetting.OmitXmlDeclaration = true;
StringWriter stringwriter = new StringWriter();
using (XmlWriter xmlwriter = System.Xml.XmlWriter.Create(stringwriter, writtersetting))
{
xSeriz.Serialize(xmlwriter, instance, ns);
}
xnode.InnerXml = stringwriter.ToString();
XmlNode bindxnode = xnode.SelectSingleNode("Instance");
xmlDocument.DocumentElement.SelectSingleNode("Instances").AppendChild(bindxnode);
xmlDocument.Save(filePath);
}
I've written some .net code to serialize an object using the XMLSerializer class.
public static string serialize(object o)
{
Type type = o.GetType();
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(type);
System.IO.StringWriter writer = new System.IO.StringWriter();
serializer.Serialize(writer, o);
return writer.ToString();
}
The output looks like this:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>a</string>
<string>b</string>
<string>c</string>
</ArrayOfString>
That's great, but what I would really like is to get just the root node without the XML doctype declaration at the beginning.
The reason I want to do this is because I would like to use the root element of the XML serialized object as part of another XML document.
XmlWriterSettings has a property to omit the XML declaration (OmitXmlDeclaration):
public static string Serialize(object obj)
{
var builder = new StringBuilder();
var xmlSerializer = new XmlSerializer(obj.GetType());
using (XmlWriter writer = XmlWriter.Create(builder,
new XmlWriterSettings() { OmitXmlDeclaration = true }))
{
xmlSerializer.Serialize(writer, obj);
}
return builder.ToString();
}
The file format I'm working with (OFX) is XML-like and contains a bunch of plain-text stuff before the XML-like bit begins. It doesn't like having between the plain-text and XML parts though, so I'm wondering if there's a way to get XmlSerialiser to ignore that. I know I could go through the file and wipe out that line but it would be simpler and cleaner to not write it in the first place! Any ideas?
You'll have to manipulate the XML writer object you use when calling the Serialize method. Its Settings property has a OmitXmlDeclaration property, which you'll want to set to true. You'll also need to set the ConformanceLevel property, otherwise the XmlWriter will ignore the OmitXmlDeclaration property.
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.ConformanceLevel = ConformanceLevel.Fragment;
XmlWriter writer = XmlWriter.Create(/*whatever stream you need*/,settings);
serializer.Serialize(writer,objectToSerialize);
writer.close();
Not too tough, you just have to serialize to an explicitly declared XmlWriter and set the options on that writer before you serialize.
public static string SerializeExplicit(SomeObject obj)
{
XmlWriterSettings settings;
settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
XmlSerializerNamespaces ns;
ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer serializer;
serializer = new XmlSerializer(typeof(SomeObject));
//Or, you can pass a stream in to this function and serialize to it.
// or a file, or whatever - this just returns the string for demo purposes.
StringBuilder sb = new StringBuilder();
using(var xwriter = XmlWriter.Create(sb, settings))
{
serializer.Serialize(xwriter, obj, ns);
return sb.ToString();
}
}
I have a class that is marked with DataContract attributes and I would like to create an XDocument from objects of that class. Whats the best way of doing this?
I can do it by going via an XmlDocument but this seems like an unnecessary step.
You can create an XmlWriter directly into the XDocument:
XDocument doc = new XDocument();
using (var writer = doc.CreateWriter())
{
// write xml into the writer
var serializer = new DataContractSerializer(objectToSerialize.GetType());
serializer.WriteObject(writer, objectToSerialize);
}
Console.WriteLine(doc.ToString());
this is how i do it, which gives clean xml without all the namespace stuff in it,
XDocument xdoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
using (var writer = xdoc.CreateWriter())
{
System.Xml.Serialization.XmlSerializer x =
new System.Xml.Serialization.XmlSerializer(objecttoserialize.GetType());
x.Serialize(writer, objecttoserialize);
}
Debug.WriteLine(xdoc.ToString());