Serialization issue with XmlSerializer in WPF - c#

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.

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 class adds prefixes automatically to XML elements

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>

How do I tell xmlwriter to ignore empty nodes in C#?

I am serializing the following entity into XML to send to our Google Search Appliance:
[Serializable]
[XmlType("record")]
public class GSADocumentRecord
{
public enum RecordActions
{
Add,
Delete
}
[XmlAttribute(AttributeName = "url")]
public string URL { get; set; }
[XmlAttribute(AttributeName = "mimetype")]
public string MimeType { get; set; }
[XmlAttribute(AttributeName = "last-modified")]
public string LastModified { get; set; }
[XmlAttribute(AttributeName = "action")]
public string Action { get; set; }
[XmlArray(ElementName = "metadata", Order = 0)]
public List<GSADocumentRecordMeta> MetaData { get; set; }
[XmlElement(ElementName = "content", Order = 1, Type = typeof(CDATA))]
public CDATA Content { get; set; }
}
The problem is that when this is serialzied without any MetaData entries, it adds <metadata /> to the xml. This is a problem because GSA (for whatever reason) errors out if there is an empty metadata node when used for some actions.
I am serializing this class with the following code:
var ms = new System.IO.MemoryStream();
XmlSerializer xml = new XmlSerializer(this.GetType());
StreamWriter sw = new StreamWriter(ms);
XmlWriter xw = new XmlTextWriter(sw);
xw.WriteStartDocument();
xw.WriteDocType("gsafeed", "-//Google//DTD GSA Feeds//EN", null, null);
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
xml.Serialize(xw, this, ns);
ms.Position = 0;
How can I tell the XmlWriter to ignore this element if the list is empty?
Having a self-closing tag certainly seems legal, it sounds like the parser on their side is causing the problem. You could write the XML out to a string first, and then do a .Replace("<metadata />", "").

c# WCF getting list of elements values

I have a piece of XML example below
<job>
<refno>XXX</refno>
<specialisms>
<specialism>1</specialism>
<specialism>2</specialism>
</specialisms>
</job>
How using WCF c# do I serialise these values into a list?
I currently have...
[DataMember]
public SpecialismList specialisms { get; set; }
[CollectionDataContract(Name = "specialisms", ItemName = "specialism")]
public class SpecialismList : List<int> { }
But it isn't currently working... any tips?
This data contract should work out just fine to serialize to the XML you posted (see code below). What is the problem you're having?
public class StackOverflow_7386673
{
[DataContract(Name = "job", Namespace = "")]
public class Job
{
[DataMember(Order = 0)]
public string refno { get; set; }
[DataMember(Order = 1)]
public SpecialismList specialisms { get; set; }
}
[CollectionDataContract(Name = "specialisms", ItemName = "specialism", Namespace = "")]
public class SpecialismList : List<int> { }
public static void Test()
{
MemoryStream ms = new MemoryStream();
DataContractSerializer dcs = new DataContractSerializer(typeof(Job));
Job job = new Job
{
refno = "XXX",
specialisms = new SpecialismList { 1, 2 }
};
XmlWriterSettings ws = new XmlWriterSettings
{
OmitXmlDeclaration = true,
Indent = true,
IndentChars = " ",
Encoding = new UTF8Encoding(false),
};
XmlWriter w = XmlWriter.Create(ms, ws);
dcs.WriteObject(w, job);
w.Flush();
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
}
}

Categories