Serializing class adds prefixes automatically to XML elements - c#

I have the following class that needs to be serialized:
[XmlRoot("Login", Namespace = "http://tempuri.org/Logon"), Serializable()]
public class Login
{
[XmlElement("programCode")]
public string ProgramCode { get; set; }
[XmlElement("contactType")]
public string ContactType { get; set; }
[XmlElement("email")]
public string Email { get; set; }
[XmlElement("password")]
public string Password { get; set; }
[XmlElement("projectName")]
public string ProjectName { get; set; }
}
When I serialize this class, I obtain the following XML:
<q1:Login xmlns:q1="http://tempuri.org/Logon"><q1:programCode>abc</q1:programCode><q1:contactType>P</q1:contactType><q1:email>ws#abc.com</q1:email><q1:password>abc</q1:password><q1:projectName>abc</q1:projectName></q1:Login>
I do not know where the prefix q1 is getting generated from. I want an XML like this:
<Login xmlns="http://tempuri.org/Logon">
<programCode>abc</programCode>
<contactType>P</contactType>
<email>ws#abc.com</email>
<password>abc</password>
<projectName>abc</projectName>
</Login>
Can anyone please help me out with this? Thank you.
Update:
Serialization code:
public string GetObjectInXML(object obj)
{
StringWriter sw = new StringWriter();
StringBuilder sb = new StringBuilder(_soapEnvelope);
XmlSerializer serializer = new XmlSerializer(obj.GetType());
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
XmlWriterSettings settings = new XmlWriterSettings
{
OmitXmlDeclaration = true
};
XmlWriter writer = XmlWriter.Create(sw, settings);
ns.Add(string.Empty, string.Empty);
serializer.Serialize(writer, obj, ns);
var str = sw.ToString();
return str;
}
For now this is a method which returns string just to check if my XML is built properly.

The XMLSerializer supports providing a default namespace e.g.
string defaultNamespace = "http://tempuri.org/Logon";
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add(string.Empty, defaultNamespace);
XmlSerializer xs = new XmlSerializer(typeof(T), defaultNamespace);

Can you remove the name space?
[XmlRoot("Login", Namespace = ""), Serializable()]
public class Login {
[XmlElement("programCode")]
public string ProgramCode { get; set; }
[XmlElement("contactType")]
public string ContactType { get; set; }
[XmlElement("email")]
public string Email { get; set; }
[XmlElement("password")]
public string Password { get; set; }
[XmlElement("projectName")]
public string ProjectName { get; set; }
}
public static string SerializeXml<T>(T value)
{
var settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
var namespaces = new XmlSerializerNamespaces();
namespaces.Add("q1", "http://tempuri.org/Logon");
var xmlserializer = new XmlSerializer(typeof(T));
var stringWriter = new StringWriter();
using (var writer = XmlWriter.Create(stringWriter, settings))
{
xmlserializer.Serialize(writer, value, namespaces);
return stringWriter.ToString();
}
}
public static void Main(string[] args)
{
var login = new Login();
login.ContactType = "XMLType";
login.Email = "x#x.com";
var a = SerializeXml(login);
Console.WriteLine(a);
Console.ReadLine();
}
Result
<Login xmlns:q1="http://tempuri.org/Logon">
<contactType>XMLType</contactType>
<email>x#x.com</email>
</Login>

Related

How can I return xml without <string> element?

I am using XML serialization in my project. It's working good but I am facing two issues.
Formatting of nodes
Remove <string></string> from response
Sample object which I am trying to serialize is :
[XmlRoot("result")]
public class SwRequestListModel
{
public SwRequestListModel()
{
SwRequest = new List<SwRequestShortInfo>();
}
[XmlElement("api_version")]
public string ApiVersion { get; set; }
[XmlElement("sw_request")]
public List<SwRequestShortInfo> SwRequest { get; set; }
}
[XmlRoot(ElementName = "sw_request_short_info")]
public class SwRequestShortInfo
{
[XmlElement(ElementName = "sw_ref_number")]
public string SwRefNumber { get; set; }
[XmlElement(ElementName = "db_no")]
public string DbNo { get; set; }
[XmlElement(ElementName = "engine_manufacturing_no")]
public string EngineManufacturingNo { get; set; }
[XmlElement(ElementName = "engine_ref_type")]
public string EngineRefType { get; set; }
[XmlElement(ElementName = "raised_date")]
public string RaisedDate { get; set; }
[XmlElement(ElementName = "raised_by")]
public string RaisedBy { get; set; }
[XmlElement(ElementName = "status")]
public string Status { get; set; }
[XmlElement(ElementName = "approved_by")]
public string ApprovedBy { get; set; }
[XmlElement(ElementName = "system_type")]
public string SystemType { get; set; }
}
The code which I am using to serialize is :
public static string ToXml(SwRequestListModel obj)
{
XmlSerializer s = new XmlSerializer(obj.GetType());
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlWriterSettings settings = new XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = true,
Encoding = Encoding.UTF8,
NewLineOnAttributes = true,
NamespaceHandling = NamespaceHandling.OmitDuplicates,
IndentChars = Environment.NewLine
};
using (var sww = new StringWriter())
{
using (XmlWriter writer = XmlWriter.Create(sww, settings))
{
s.Serialize(writer, obj, ns);
return sww.ToString();
}
}
}
Response is display like :
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/"><result> <api_version>1.0</api_version> <sw_request> <sw_ref_number>588</sw_ref_number> <db_no>99899</db_no> <engine_manufacturing_no>MF99899</engine_manufacturing_no> <engine_ref_type>X40B</engine_ref_type> <raised_date>22/06/2021</raised_date> <raised_by>Srusti.Thakkar#test.com</raised_by> <status>Requested</status> <approved_by /> <system_type>test</system_type> </sw_request> <sw_request> <sw_ref_number>589</sw_ref_number> <db_no>88552</db_no> <engine_manufacturing_no>MF99899</engine_manufacturing_no> <engine_ref_type>X40B</engine_ref_type> <raised_date>22/06/2021</raised_date> <raised_by>Srusti.Thakkar#test.com</raised_by> <status>Requested</status> <approved_by /> <system_type>UNIC</system_type> </sw_request> <sw_request> <sw_ref_number>590</sw_ref_number> <db_no>33899</db_no> <engine_manufacturing_no>MF99899</engine_manufacturing_no> <engine_ref_type>X40B</engine_ref_type> <raised_date>22/06/2021</raised_date> <raised_by>Srusti.Thakkar#test.com</raised_by> <status>Requested</status> <approved_by /> <system_type>UNIC</system_type> </sw_request> </result></string>
Actual API Method is :
[HttpGet]
public string GetRequestList(string date, string status, string systemType)
{
SwRequestListModel result = new SwRequestListModel();
result.ApiVersion = "1.0";
//Here get data
return result.ToXml();
}
Browser result is :
Update :
I guess API method GetRequestList serialize string object. Try to return raw string.
[HttpGet]
public HttpResponseMessage GetRequestList(string date, string status, string systemType)
{
SwRequestListModel result = new SwRequestListModel();
result.ApiVersion = "1.0";
//Here get data
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(result.ToXml());
return response;
}

How to create constructor to fill xmlelement and attribute?

I have complex class which I want to serialize to XML format using costum attributes. I am stucked at XMLelement which is List and I would like to generate new items with constructor, where I can fill attribute name and text value.
Now I have to create seperate objects and those I can add to the List. I want to simplify this.
class to be serialized:
[XmlElement("Cfg")]
public ElCfg Cfg = new ElCfg();
public class ElCfg
{
[XmlAttribute("Name")] public string CfgName { get; set; } = "Default";
[XmlElement("Content")] public ElCont Content = new ElCont();
}
public class ElCont
{
[XmlAttribute("ver")] public string ContentVer { get; set; }
[XmlElement("Prop")] public List<ElProp> Properties = new List<ElProp>();
}
public class ElProp
{
[XmlAttribute("Name")]
public string PropertyName { get; set; }
[XmlText]
public string PropertyVal { get; set; }
}
usage in main:
static void Main(string[] args)
{
//build promotic object
PromoticXML xmlDoc = new PromoticXML();
xmlDoc.Cfg.Content.ContentVer = "80323";
PromoticXML.ElProp prop1 = new PromoticXML.ElProp();
prop1.PropertyName = "neco";
prop1.PropertyVal = "necojineho";
PromoticXML.ElProp prop2 = new PromoticXML.ElProp();
prop2.PropertyName = "neco";
prop2.PropertyVal = "necojineho";
xmlDoc.Cfg.Content.Properties.Add(prop1);
xmlDoc.Cfg.Content.Properties.Add(prop2);
//serialize promotic object
XmlWriterSettings xmlSet = new XmlWriterSettings();
xmlSet.Encoding = Encoding.Unicode;
xmlSet.Indent = true;
xmlSet.IndentChars = " ";
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
XmlSerializer serializer = new XmlSerializer(typeof(PromoticXML));
using (XmlWriter writer = XmlWriter.Create("promotic.xml", xmlSet))
{
serializer.Serialize(writer, xmlDoc);
}
Process.Start("notepad.exe", "promotic.xml");
}
What my goal is:
xmlDoc.Cfg.Content.Properties.Add(new PromoticXML.ElProp("someName", "someText"));
instead of:
PromoticXML.ElProp prop1 = new PromoticXML.ElProp();
prop1.PropertyName = "neco";
prop1.PropertyVal = "necojineho";
xmlDoc.Cfg.Content.Properties.Add(prop1);

Serializing with namespace declaration on childnode with XmlSerializer

I'm trying to serialize using XMLSerializer and achieve the following result:
Desired xml:
<?xml version="1.0" encoding="utf-8"?>
<RootElem xmlns="http://www.example.com/rootns">
<Elem1>
<Foo>bar</Foo>
</Elem1>
<Elem2>
<x:ElemX xmlns:x="http://www.sample.net/otherns">
<x:Bar>foo</x:Bar>
</x:ElemX>
</Elem2>
</RootElem>
The content in <elem3> will be parsed alone by a system on the other end, so the xmlns:x specification will have to be on the <elemx> node, and not on the rootnode as below.
Current serialized xml, not desired:
<?xml version="1.0" encoding="utf-8"?>
<RootElem xmlns:x="http://www.sample.net/otherns" xmlns="http://www.example.com/rootns">
<Elem1>
<Foo>bar</Foo>
</Elem1>
<Elem2>
<x:ElemX>
<x:Bar>foo</x:Bar>
</x:ElemX>
</Elem2>
</RootElem>
Anyone know a standard way to instruct XmlSerializer to achieve this?
Here's the code used to generate this sample (simple c# winform application)
private void Form1_Load(object sender, EventArgs e)
{
RootElem root = new RootElem();
root.Elem1 = new NormalElement() { Foo = "bar"};
ChildClass c = new ChildClass() { Bar = "foo"};
root.Elem2 = new ElementWithChildClass() { ElemX = c };
MemoryStream ms = new MemoryStream();
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("x", "http://www.sample.net/otherns");
XmlSerializer xser = new XmlSerializer(typeof(RootElem));
XmlTextWriter tw = new XmlTextWriter(ms, Encoding.UTF8);
tw.Formatting = Formatting.Indented;
xser.Serialize(tw, root, ns);
ms.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(ms, Encoding.UTF8);
textBox1.Text = sr.ReadToEnd();
}
[XmlRoot(Namespace = "http://www.example.com/rootns")]
public class RootElem
{
public NormalElement Elem1 { get; set; }
public ElementWithChildClass Elem2 { get; set; }
}
public class NormalElement
{
public string Foo { get; set; }
}
public class ElementWithChildClass
{
[XmlElement(Namespace = "http://www.sample.net/otherns")]
public ChildClass ElemX { get; set; }
}
[XmlRoot("RefDoc", Namespace = "http://www.sample.net/otherns")]
public class ChildClass
{
public string Bar { get; set; }
}

Serialization issue with XmlSerializer in WPF

I have been trying to serialize an object which has an enum
public EEEEEEE HandledAirlineCopyInd { get; set; }
[XmlIgnore]
public bool RRRRRRR{ get; set; }
[XmlElement("MatchInfo", typeof(TTTTTTTTT), Order = 11)]
[XmlElement("MessageInfo", typeof(YYYYYYYYY), Order = 11)]
public object Item { get; set; }
[XmlAttribute]
public XXXXXXXX ModuleID { get; set; }
[XmlElement(Order = 5)]
The attribute ModuleId is an enum
[Serializable]
[GeneratedCode("System.Xml", "4.0.30319.34283")]
[XmlType(Namespace = "http://VVVV/common/7/0")]
public enum XXXXXXXX
{
WM = 0,
WT = 1,
WI = 2,
}
when I am trying to serialize as below,
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
XmlSerializer serializer = new XmlSerializer(objectToSerialize.GetType());
MemoryStream ms = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = omitDeclaration;
settings.Encoding = encoding;
XmlWriter writer = XmlWriter.Create(ms, settings);
serializer.Serialize(writer, objectToSerialize, ns);
string xmlString = encoding.GetString(ms.ToArray());
string xmlStringCleaned = CleanInvalidXmlChars(xmlString);
It is not serializing. please advise.

PaymentDetails is not successfully deserialized, returning a null object, because it seems it is expected to have IXmlDeserializable

[XmlRoot("Quote")]
public class Quote
{
[XmlElement("Insurance")]
public InsuranceDetails InsDetails { get; set; }
[XmlElement("Payment")]
public PaymentDetails PayDetails { get; set; }
}
public class InsuranceDetails : IXmlSerializable
{
[XmlElement(ElementName = "Details1")]
public string Details1 { get; set; }
public void ReadXml(XmlReader reader)
{
reader.ReadStartElement("Insurance");
Details1 = reader.ReadElementString("Details1");
reader.ReadEndElement();
}
public void WriteXml(XmlWriter writer)
{
// do write suff
}
}
public class PaymentDetails
{
[XmlElement(ElementName = "Details1")]
public string Details1 { get; set; }
}
Given this example, using XmlSerializer to deserialize my string to QuoteObject, PaymentDetails is not successfully deserialized, returning a null object, because it seems it is expected to have IXmlDeserializable. It only works if PaymentDetails is parsed in first place. Is this some expected behavior from XmlSerializer?
using (TextReader read = new StringReader(xml))
{
var serializer = new XmlSerializer(typeof(Quote));
return (Quote)serializer.Deserialize(read);
}
Well these are the ReadXml and WriteXml I modified:
public void ReadXml(XmlReader reader)
{
reader.MoveToContent();
var empty=reader.IsEmptyElement;
reader.ReadStartElement();
if(!empty){
Details1=reader.ReadElementString("Details1");
reader.ReadEndElement();
}
}
public void WriteXml(XmlWriter writer)
{
var str=string.IsNullOrWhiteSpace(Details1)?"":Details1;
writer.WriteElementString("Details1",str);
}
Following are serialize and deserialize functions:
public static string Serialize<T>(T t)
{
var xmlser=new XmlSerializer(typeof(T));
XmlWriterSettings settings = new XmlWriterSettings();
using(StringWriter textWriter = new StringWriter()) {
using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) {
xmlser.Serialize(xmlWriter, t);
}
return textWriter.ToString();
}
}
public static T Deserialize<T>(string xml)
{
if(string.IsNullOrEmpty(xml)) {
return default(T);
}
XmlSerializer serializer = new XmlSerializer(typeof(T));
XmlReaderSettings settings = new XmlReaderSettings();
using(StringReader textReader = new StringReader(xml)) {
using(XmlReader xmlReader = XmlReader.Create(textReader, settings)) {
return (T) serializer.Deserialize(xmlReader);
}
}
}
Serialization Test:
var q=new Quote();
q.PayDetails = new PaymentDetails{Details1="Payment Details 1"};
q.InsDetails=new InsuranceDetails{Details1="Insurance Details 1"};
str = Serialize<Quote>(q);
Which gives (str):
<?xml version="1.0" encoding="utf-16"?>
<Quote xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Payment>
<Details1>Payment Details 1</Details1>
</Payment>
<Insurance>
<Details1>Insurance Details 1</Details1>
</Insurance>
</Quote>
Deserialization Test:
var dq=Deserialize<Quote>(str);
Console.WriteLine(dq.PaymentDetails.Detail1);//gives "Payment Details 1"
Console.WriteLine(dq.InsuranceDetails.Detail1);//gives "Insurance Details 1"
PS:- The Serialize code was copied from another SO answer verbatim. I learned how to serialize to string using StringWriter.
First of all you don't have to implement IXmlSerializable in any of the classes. Second of all, you don't provide the content of the xml variable. It may contain a mistype/bug, if you created it manually.
I used the following code, to test your classes:
using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace XmlDeSerialize
{
[XmlRoot("Quote")]
public class Quote
{
[XmlElement("Insurance")]
public InsuranceDetails InsDetails { get; set; }
[XmlElement("Payment")]
public PaymentDetails PayDetails { get; set; }
}
public class InsuranceDetails
{
[XmlElement(ElementName = "Details1")]
public string Details1 { get; set; }
}
public class PaymentDetails
{
[XmlElement(ElementName = "Details1")]
public string Details1 { get; set; }
}
class Program
{
static void Main(string[] args)
{
var qin = new Quote
{
InsDetails = new InsuranceDetails { Details1 = "insurance details text" },
PayDetails = new PaymentDetails { Details1 = "payment details text" },
};
string xml;
using (var stream = new MemoryStream())
{
var serializer = new XmlSerializer(typeof(Quote));
serializer.Serialize(stream, qin);
stream.Position = 0;
using (var sr = new StreamReader(stream))
{
xml = sr.ReadToEnd();
}
}
Quote qout;
using (TextReader read = new StringReader(xml))
{
var deserializer = new XmlSerializer(typeof(Quote));
var obj = deserializer.Deserialize(read);
qout = (Quote)obj;
}
Console.WriteLine("InsDetails.Details1='{0}'", qout.InsDetails.Details1);
Console.WriteLine("PayDetails.Details1='{0}'", qout.PayDetails.Details1);
}
}
}
The value of xml after serialization:
<?xml version="1.0"?>
<Quote xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Insurance>
<Details1>insurance details text</Details1>
</Insurance>
<Payment>
<Details1>payment details text</Details1>
</Payment>
</Quote>
The console output I received:
InsDetails.Details1='insurance details text'
PayDetails.Details1='payment details text'
Try the code yourself and see if it works for you. Clearly to me you don't provide valid XML content for deserialization, or other part of your code you did not provide in your question is to blame.

Categories