DataContractSerializer with Multiple Namespaces - c#

I am using a DataContractSerializer to serialize an object to XML. The main object is SecurityHolding with the namespace "http://personaltrading.test.com/" and contains a property called Amount that's a class with the namespace "http://core.test.com". When I serialize this to XML I get the following:
<ArrayOfSecurityHolding xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://personaltrading.test.com/">
<SecurityHolding>
<Amount xmlns:d3p1="http://core.test.com/">
<d3p1:Amount>1.05</d3p1:Amount>
<d3p1:CurrencyCode>USD</d3p1:CurrencyCode>
</Amount>
<BrokerageID>0</BrokerageID>
<BrokerageName i:nil="true" />
<RecordID>3681</RecordID>
</SecurityHolding></ArrayOfSecurityHolding>
Is there anyway I can control the d3p1 prefix? Am I doing something wrong or should I be doing something else?

Firstly, the choice of namespace alias should make no difference to a well-formed parser.
But; does it have to be DataContractSerializer? With XmlSerializer, you can use the overload of Serialize that accepts a XmlSerializerNamespaces. This allows you to pick and choose the namespaces and aliases that you use.
Ultimately; DataContractSerializer is not intended to give full xml control; that isn't its aim. If you want strict xml control, XmlSerializer is a better choice, even if it is older (and has some nuances/foibles of its own).
Full example:
using System;
using System.Xml.Serialization;
public class Amount
{
public const string CoreNamespace = "http://core.test.com/";
[XmlElement("Amount", Namespace=CoreNamespace)]
public decimal Value { get; set; }
[XmlElement("CurrencyCode", Namespace = CoreNamespace)]
public string Currency { get; set; }
}
[XmlType("SecurityHolding", Namespace = SecurityHolding.TradingNamespace)]
public class SecurityHolding
{
public const string TradingNamespace = "http://personaltrading.test.com/";
[XmlElement("Amount", Namespace = Amount.CoreNamespace)]
public Amount Amount { get; set; }
public int BrokerageId { get; set; }
public string BrokerageName { get; set; }
public int RecordId { get; set; }
}
static class Program
{
static void Main()
{
var data = new[] {
new SecurityHolding {
Amount = new Amount {
Value = 1.05M,
Currency = "USD"
},
BrokerageId = 0,
BrokerageName = null,
RecordId = 3681
}
};
var ser = new XmlSerializer(data.GetType(),
new XmlRootAttribute("ArrayOfSecurityHolding") { Namespace = SecurityHolding.TradingNamespace});
var ns = new XmlSerializerNamespaces();
ns.Add("foo", Amount.CoreNamespace);
ser.Serialize(Console.Out, data, ns);
}
}
Output:
<ArrayOfSecurityHolding xmlns:foo="http://core.test.com/" xmlns="http://personaltrading.test.com/">
<SecurityHolding>
<foo:Amount>
<foo:Amount>1.05</foo:Amount>
<foo:CurrencyCode>USD</foo:CurrencyCode>
</foo:Amount>
<BrokerageId>0</BrokerageId>
<RecordId>3681</RecordId>
</SecurityHolding>
</ArrayOfSecurityHolding>

I have solved this problem slightly differently to Marc that can be implemented in a base class.
Create a new attribute to define the additional XML namespaces that you will use in your data contract.
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public sealed class NamespaceAttribute : Attribute
{
public NamespaceAttribute()
{
}
public NamespaceAttribute(string prefix, string uri)
{
Prefix = prefix;
Uri = uri;
}
public string Prefix { get; set; }
public string Uri { get; set; }
}
Add the attribute to your data contracts.
[DataContract(Name = "SomeObject", Namespace = "http://schemas.domain.com/namespace/")]
[Namespace(Prefix = "a", Uri = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")]
[Namespace(Prefix = "wm", Uri = "http://schemas.datacontract.org/2004/07/System.Windows.Media")]
public class SomeObject : SerializableObject
{
private IList<Color> colors;
[DataMember]
[DisplayName("Colors")]
public IList<Colors> Colors
{
get { return colors; }
set { colours = value; }
}
}
Then in your Save method, use reflection to get the attributes and then write them to the file.
public static void Save(SerializableObject o, string filename)
{
using (Stream outputStream = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
if (outputStream == null)
throw new ArgumentNullException("Must have valid output stream");
if (outputStream.CanWrite == false)
throw new ArgumentException("Cannot write to output stream");
object[] attributes;
attributes = o.GetType().GetCustomAttributes(typeof(NamespaceAttribute), true);
XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.Indent = true;
writerSettings.NewLineOnAttributes = true;
using (XmlWriter w = XmlWriter.Create(outputStream, writerSettings))
{
DataContractSerializer s = new DataContractSerializer(o.GetType());
s.WriteStartObject(w, o);
foreach (NamespaceAttribute ns in attributes)
w.WriteAttributeString("xmlns", ns.Prefix, null, ns.Uri);
// content
s.WriteObjectContent(w, o);
s.WriteEndObject(w);
}
}
}

I have struggled with this problem also. The solution I present below is not optimal IMHO but it works. Like Marc Gravell above, I suggest using XmlSerializer.
The trick is to add a field to your class that returns a XmlSerializerNamespaces object. This field must be decorated with a XmlNamespaceDeclarations attribute. In the constructor of your class, add namespaces as shown in the example below. In the xml below note that the root element is prefixed correctly as well as the someString element.
More info on XmlSerializerNamespaces
Schemas reference
[XmlRoot(Namespace="http://STPMonitor.myDomain.com")]
public class CFMessage : IQueueMessage<CFQueueItem>
{
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces xmlns;
[XmlAttribute("schemaLocation", Namespace=System.Xml.Schema.XmlSchema.InstanceNamespace)]
public string schemaLocation = "http://STPMonitor.myDomain.com/schemas/CFMessage.xsd";
[XmlAttribute("type")]
public string Type { get; set; }
[XmlAttribute("username")]
public string UserName { get; set; }
[XmlAttribute("somestring", Namespace = "http://someURI.com")]
public string SomeString = "Hello World";
public List<CFQueueItem> QueueItems { get; set; }
public CFMessage()
{
xmlns = new XmlSerializerNamespaces();
xmlns.Add("myDomain", "http://STPMonitor.myDomain.com");
xmlns.Add("xyz", "http://someURI.com");
}
}
<?xml version="1.0" encoding="utf-16"?>
<myDomain:CFMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xyz="http://someURI.com"
xsi:schemaLocation="http://STPMonitor.myDomain.com/schemas/CFMessage.xsd"
xyz:somestring="Hello World" type="JOIN" username="SJ-3-3008-1"
xmlns:myDomain="http://STPMonitor.myDomain.com" />

Add "http://www.w3.org/2001/XMLSchema" namespace by:
private static string DataContractSerialize(object obj)
{
StringWriter sw = new StringWriter();
DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
using (XmlTextWriter xw = new XmlTextWriter(sw))
{
//serializer.WriteObject(xw, obj);
//
// Insert namespace for C# types
serializer.WriteStartObject(xw, obj);
xw.WriteAttributeString("xmlns", "x", null, "http://www.w3.org/2001/XMLSchema");
serializer.WriteObjectContent(xw, obj);
serializer.WriteEndObject(xw);
}
StringBuilder buffer = sw.GetStringBuilder();
return buffer.ToString();
}

Related

Serialize object directly to CData

I need to make a api where in the request body there needs to be a CData object. All works exept that I cant figure out how to make my object serialze into a CData object. The project is written in the .net-framework.
I currently have the following code.
C#:
[XmlRoot(ElementName = "DATA")]
public class DATA
{
[XmlElement(ElementName = "ID")]
public int ID { get; set; }
[XmlElement(ElementName = "NAME")]
public string NAME{ get; set; }
}
[XmlRoot(ElementName = "NewDataSet")]
public class CDataSet
{
[XmlElement(ElementName = "DATA")]
public DATA data{ get; set; }
}
How the xml needs to look after:
<![CDATA[
<NewDataSet>
<DATA>
<ID>007</ID>
<NAME>John</NAME>
</DATA>
</NewDataSet>
]]>
I can make it working by serializing normally by making a request to this function:
public static string SerializeObject<T>(this T toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
Than manual adding the CData parts around it.
However my boss wants it make it work without manually adding the parts.
Please note I'm very new to C#.
Any step in the right direction will help. Thanks!
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication8
{
class Program
{
static void Main(string[] args)
{
CDataSet data = new CDataSet()
{
data = new DATA() { ID = "007", NAME = "John" }
};
MemoryStream stream = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(stream, settings);
XmlSerializer serializer = new XmlSerializer(typeof(CDataSet));
serializer.Serialize(writer, data);
writer.Flush();
writer.Close();
stream.Position = 0;
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
string xml = Encoding.UTF8.GetString(buffer);
string output = string.Format("<![CDATA[\n{0}\n]]>", xml);
}
}
[XmlRoot(ElementName = "DATA", Namespace = "")]
public class DATA
{
private int _ID { get; set; }
[XmlElement(ElementName = "ID")]
public string ID {
get { return _ID.ToString("D3");}
set{ _ID = int.Parse(value);}
}
[XmlElement(ElementName = "NAME")]
public string NAME { get; set; }
}
[XmlRoot(ElementName = "NewDataSet")]
public class CDataSet
{
[XmlElement(ElementName = "DATA")]
public DATA data { get; set; }
}
}

De-/serialization with a list of objects

I try to save and read multiple objects in one XML-File.
The function Serialize is not working with my existing List, but i dont know why. I already tried to compile it but i get an error wich says, that the methode needs an object refference.
Program.cs:
class Program
{
static void Main(string[] args)
{
List<Cocktail> lstCocktails = new List<Cocktail>();
listCocktails.AddRange(new Cocktail[]
{
new Cocktail(1,"Test",true,true,
new Cocktail(1, "Test4", true, true, 0)
});
Serialize(lstCocktails);
}
public void Serialize(List<Cocktail> list)
{
XmlSerializer serializer = new XmlSerializer(typeof(List<Cocktail>));
using (TextWriter writer = new StreamWriter(#"C:\Users\user\Desktop\MapSample\bin\Debug\ListCocktail.xml"))
{
serializer.Serialize(writer, list);
}
}
private void DiserializeFunc()
{
var myDeserializer = new XmlSerializer(typeof(List<Cocktail>));
using (var myFileStream = new FileStream(#"C:\Users\user\Desktop\MapSample\bin\Debug\ListCocktail.xml", FileMode.Open))
{
ListCocktails = (List<Cocktail>)myDeserializer.Deserialize(myFileStream);
}
}
Cocktail.cs:
[Serializable()]
[XmlRoot("locations")]
public class Cocktail
{
[XmlElement("id")]
public int CocktailID { get; set; }
[XmlElement("name")]
public string CocktailName { get; set; }
[XmlElement("alc")]
public bool alcohol { get; set; }
[XmlElement("visible")]
public bool is_visible { get; set; }
[XmlElement("counter")]
public int counter { get; set; }
private XmlSerializer ser;
public Cocktail() {
ser = new XmlSerializer(this.GetType());
}
public Cocktail(int id, string name, bool alc,bool vis,int count)
{
this.CocktailID = id;
this.CocktailName = name;
this.alcohol = alc;
this.is_visible = vis;
this.counter = count;
}
}
}
Ii also think I messed something up with the DiserializeFunc().
You are very close to implementing the Cocktail class correctly, but I think you're confused about how to serialize Lists. Your implementation of a Cocktail object class is completely fine, just get rid of the list related functions.
using System;
using System.Xml.Serialization;
namespace Serialization_Help
{
[Serializable()]
[XmlRoot("locations")]
public class Cocktail
{
[XmlElement("id")]
public int CocktailID { get; set; }
[XmlElement("name")]
public string CocktailName { get; set; }
[XmlElement("alc")]
public bool alcohol { get; set; }
[XmlElement("visible")]
public bool is_visible { get; set; }
[XmlElement("counter")]
public int counter { get; set; }
public Cocktail() {
}
public Cocktail(int id, string name, bool alc, bool vis, int count)
{
this.CocktailID = id;
this.CocktailName = name;
this.alcohol = alc;
this.is_visible = vis;
this.counter = count;
}
}
}
Now in your new function you want to serialize the list directly.
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace Serialization_Help
{
class Program {
static void Main(string[] args) {
List<Cocktail> list = new List<Cocktail> {
new Cocktail(01, "rum and coke", true, true, 5),
new Cocktail(02, "water on the rocks", false, true, 3)
};
Serialize(list);
List<Cocktail> deserialized = DiserializeFunc();
}
public static void Serialize(List<Cocktail> list) {
XmlSerializer serializer = new XmlSerializer(typeof(List<Cocktail>));
using (TextWriter writer = new StreamWriter(Directory.GetCurrentDirectory() + #"\ListCocktail.xml")) serializer.Serialize(writer, list);
}
private static List<Cocktail> DiserializeFunc() {
var myDeserializer = new XmlSerializer(typeof(List<Cocktail>));
using (var myFileStream = new FileStream(Directory.GetCurrentDirectory() + #"\ListCocktail.xml", FileMode.Open)) return (List<Cocktail>)myDeserializer.Deserialize(myFileStream);
}
}
}
Doing so should correctly print out the following .xml output:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfCocktail xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Cocktail>
<id>1</id>
<name>rum and coke</name>
<alc>true</alc>
<visible>true</visible>
<counter>5</counter>
</Cocktail>
<Cocktail>
<id>2</id>
<name>water on the rocks</name>
<alc>false</alc>
<visible>true</visible>
<counter>3</counter>
</Cocktail>
</ArrayOfCocktail>
Keep in mind that I have not provided implementation of any of the standard safety or null checks for the file. You'll have to check if the file exists yourself by using File.Exists(...) (see here for File.Exists implementation) and implement the correct try and catch cases and what your code will chose to do if it runs into serialization or input/outut errors.
You'd better use ExtendedXmlSerializer to serialize and deserialize.
Instalation
You can install ExtendedXmlSerializer from nuget or run the following command:
Install-Package ExtendedXmlSerializer
Serialization:
ExtendedXmlSerializer serializer = new ExtendedXmlSerializer();
var list = new List<Cocktail>();
var xml = serializer.Serialize(list);
Deserialization
var list = serializer.Deserialize<List<Cocktail>>(xml);
Standard XML Serializer in .NET is very limited.
Does not support serialization of class with circular reference or class with interface property,
Does not support Dictionaries,
There is no mechanism for reading the old version of XML,
If you want create custom serializer, your class must inherit from IXmlSerializable. This means that your class will not be a POCO class,
Does not support IoC.
ExtendedXmlSerializer can do this and much more.
ExtendedXmlSerializer support .NET 4.5 or higher and .NET Core. You can integrate it with WebApi and AspCore.

My nested Class collection XMLRoot name is not being used when serializing to xml

I have a Model populated and I wish to serlise to an xml document.
Due to naming conventions I have to over ride the class names for my XML document,
This is my Model(s):
[Serializable]
[XmlRoot("preferences")]
public class PreferencesModel
{
[XmlIgnore]
public string MessageToUser { get; set; }
[XmlElement(ElementName = "sectiondivider")]
public List<SectionDivider> SectionDivider { get; set; }
}
[Serializable]
[XmlRoot(ElementName = "sectiondivider")]
public class SectionDivider
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlElement("preference")]
public List<PreferenceModel> PreferenceModel { get; set; }
}
[Serializable]
[XmlRoot("preference")]
public class PreferenceModel
{
[XmlAttribute("type")]
public string Type { get; set; }
public string Name { get; set; }
[XmlAttribute("value")]
public string Value { get; set; }
[XmlElement("options")]
public List<Option> Options { get; set; }
}
this is how I serialize:
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(ObjectToXmlString(obj, includeNameSpace, includeStartDocument, rootAttribute));
return xDoc;
public static string ObjectToXmlString(Object obj, bool includeNameSpace, bool includeStartDocument, XmlRootAttribute rootAttribute)
{
SpecialXmlWriter stWriter = null;
XmlSerializer xmlSerializer = default(XmlSerializer);
string buffer = null;
try
{
if (rootAttribute == null)
{
xmlSerializer = new XmlSerializer(obj.GetType());
}
else
{
xmlSerializer = new XmlSerializer(obj.GetType(), rootAttribute);
}
MemoryStream memStream = new MemoryStream();
StringWriter writer = new StringWriter();
stWriter = new SpecialXmlWriter(memStream, new UTF8Encoding(false), includeStartDocument);
if (!includeNameSpace)
{
System.Xml.Serialization.XmlSerializerNamespaces xs = new XmlSerializerNamespaces();
//To remove namespace and any other inline
//information tag
xs.Add("", "");
xmlSerializer.Serialize(stWriter, obj, xs);
}
else
{
xmlSerializer.Serialize(stWriter, obj);
}
buffer = Encoding.UTF8.GetString(memStream.ToArray());
}
catch (Exception e)
{
string msg = e.Message;
throw;
}
finally
{
if (stWriter != null)
stWriter.Close();
}
return buffer;
}
I call it like this:
XmlDocument preferencesxml = Codec.ObjectToXml(m.SectionDivider,false,
false, new XmlRootAttribute("preferences"));
My m value is:
and my resulting XML is this:
XmlRootAttribute, as the name suggests, only applies to the root element of the XML being serialised.
You need to use XmlTypeAttribute in this context:
[XmlType("sectiondivider")]`
public class SectionDivider
{
//...
}
As an aside, the [Serializable] attribute is not relevant to XmlSerializer - it can be removed unless you need it for some other purpose.

C# - How to control the format of XML serialization?

I have a class that I need to serialize to XML with a specific format for a WCF service I'm using.
The class structure is this:
[XmlRoot(Namespace="http://schemas.datacontract.org/2004/07/XXX.IT.Messaging.Common.Entities")]
public class PushBroadcastingParams
{
[XmlElement]
public string appId { get; set; }
[XmlElement]
public string message { get; set; }
[XmlArray(Namespace = "http://schemas.datacontract.org/2004/07/XXX.IT.Messaging.Common.Entities.KMS.Requests")]
public List<CustomKeyValuePair> customData { get; set; }
}
[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/XXX.IT.Messaging.Common.Entities")]
public class PushNotificationParams : PushBroadcastingParams
{
[XmlArray(Namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")]
public string[] subscribersIDs { get; set; }
}
This is my serialization code:
public static string SerializeXML<T>(T obj, XmlSerializerNamespaces namespaces = null)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", "");
using (StringWriter sw = new StringWriter())
{
using (XmlWriter writer = XmlWriter.Create(sw, new XmlWriterSettings { OmitXmlDeclaration = true }))
{
new XmlSerializer(typeof(T)).Serialize(writer, obj, ns);
return sw.ToString();
}
}
}
I need the XML output to be exactly like this:
<PushNotificationParams xmlns="http://schemas.datacontract.org/2004/07/XXX.IT.Messaging.Common.Entities" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<appId>123</appId>
<customData xmlns:orb="http://schemas.datacontract.org/2004/07/XXX.IT.Messaging.Common.Entities.KMS.Requests">
<orb:CustomKeyValuePair>
<orb:Key>HEADER</orb:Key>
<orb:Value>FOCUS</orb:Value>
</orb:CustomKeyValuePair>
<orb:CustomKeyValuePair>
<orb:Key>TITLE</orb:Key>
<orb:Value>title of message</orb:Value>
</orb:CustomKeyValuePair>
<orb:CustomKeyValuePair>
<orb:Key>DESC</orb:Key>
<orb:Value>desc of message</orb:Value>
</orb:CustomKeyValuePair>
<orb:CustomKeyValuePair>
<orb:Key>MESSAGE_TYPE</orb:Key>
<orb:Value>POD</orb:Value>
</orb:CustomKeyValuePair>
</customData>
<message>test</message>
<subscribersIDs xmlns:orb="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<orb:string>USER-NAME</orb:string>
</subscribersIDs>
</PushNotificationParams>
But I can't get it to be with the name space and the prefix exectly like this and I can't get rid of the xmlns:xsd namespace.

How to generate this XML sample, with custom 2nd line, from within C#?

I need to generate the following XML, but have thus far been unsuccessful in injecting my custom header data:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:MT_Get_Name_Req xmlns:ns0="http://hsd.sd.com">
<personnel_id>1202</personnel_id>
<dob>19470906</dob>
</ns0:MT_Get_Name_Req>
How can i generate the above XML, from within C#?
Currently we have :
XmlSerializer serializer = new XmlSerializer(typeof(Employee));
StringWriter sww = new StringWriter();
XmlWriter writer = XmlWriter.Create(sww);
serializer.Serialize(writer, employee);
Employee Class:
public class Employee
{
public string personnel_id { get; set; }
public string dob { get; set; }
}
Making some reasonable guesses about what your Employee class looks like, you need to do the following:
Decorate your Employee class with [XmlRoot("MT_Get_Name_Req", Namespace = "http://hsd.sd.com")]. This will give your XML root element the correct name and namespace.
While the root is in the http://hsd.sd.com namespace, its child elements are not in any namespace. Thus their namespace will need to be overridden using an XmlElement attribute.
Setting the XmlRoot namespace will use the specified namespace as the default namespace. If you must use a prefixed namespace, you need to pass a XmlSerializerNamespaces with all desired namespaces to XmlSerializer.Serialize().
Thus:
[XmlRoot("MT_Get_Name_Req", Namespace = Employee.XmlNamespace)]
public class Employee
{
public const string XmlNamespace = "http://hsd.sd.com";
public const string XmlNamespacePrefix = "ns0";
const string xsi = "http://www.w3.org/2001/XMLSchema-instance";
const string xsd = "http://www.w3.org/2001/XMLSchema";
public static XmlSerializerNamespaces XmlSerializerNamespaces
{
get
{
var namespaces = new XmlSerializerNamespaces();
namespaces.Add(XmlNamespacePrefix, XmlNamespace);
// namespaces.Add("xsi", xsi); Uncomment to add standard namespaces.
// namespaces.Add("xsd", xsd);
return namespaces;
}
}
[XmlElement("personnel_id", Namespace="")]
public string personnel_id { get; set; }
[XmlElement("dob", Namespace = "")]
public string dob { get; set; }
}
And use it like
var xml = XmlSerializationHelper.GetXml(employee, Employee.XmlSerializerNamespaces, Encoding.UTF8);
Using the extension methods:
public static class XmlSerializationHelper
{
public sealed class StringWriterWithEncoding : StringWriter
{
private readonly Encoding encoding;
public StringWriterWithEncoding(Encoding encoding)
{
this.encoding = encoding;
}
public override Encoding Encoding
{
get { return encoding; }
}
}
public static string GetXml<T>(T obj, XmlSerializerNamespaces ns, Encoding encoding)
{
return GetXml(obj, new XmlSerializer(obj.GetType()), ns, encoding);
}
public static string GetXml<T>(T obj, XmlSerializer serializer, XmlSerializerNamespaces ns, Encoding encoding)
{
using (var textWriter = new StringWriterWithEncoding(encoding))
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; // For cosmetic purposes.
settings.IndentChars = " "; // For cosmetic purposes.
using (var xmlWriter = XmlWriter.Create(textWriter, settings))
{
if (ns != null)
serializer.Serialize(xmlWriter, obj, ns);
else
serializer.Serialize(xmlWriter, obj);
}
return textWriter.ToString();
}
}
}
To get
<?xml version="1.0" encoding="utf-8"?>
<ns0:MT_Get_Name_Req xmlns:ns0="http://hsd.sd.com">
<personnel_id>1202</personnel_id>
<dob>19470906</dob>
</ns0:MT_Get_Name_Req>
I did a small example for you. I included an XmlRoot Attribute to the Employee.class and added a namespace object when serializing the employee.
see Add prefixes and namespaces to xml Serialization
and SO Question How to set xml prefixes
Employee.cs
[XmlRoot("MT_Get_Name_Req", Namespace = "http://hsd.sd.com")]
public class Employee
{
[XmlElement(Namespace="")]
public string personnel_id { get; set; }
[XmlElement(Namespace = "")]
public string dob { get; set; }
}
demoFile.cs
private static void customXmlSerialization()
{
Employee employee = new Employee() { personnel_id = "1202", dob = "19470906" };
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("ns0", "http://hsd.sd.com");
XmlSerializer serializer = new XmlSerializer(typeof(Employee));
string path = #"e:\temp\data.xml";
XmlTextWriter writer = new XmlTextWriter(path, Encoding.UTF8);
serializer.Serialize(writer, employee,ns);
}
output
<?xml version="1.0" encoding="utf-8"?>
<ns0:MT_Get_Name_Req xmlns:ns0="http://hsd.sd.com">
<personnel_id>1202</personnel_id>
<dob>19470906</dob>
</ns0:MT_Get_Name_Req>

Categories

Resources