Trying to create a web api using c# .net which will take following input
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetUser xmlns="http://tempuri.org/">
<UserRecorder>
<COMPANY>string</COMPANY>
<PASSWORD>string</PASSWORD>
<USER>string</USER>
<UserRecord>
<item>
<ST>1</ST>
<LT>1</LT>
<TNO>ABC</TNO>
</item>
</UserRecord>
</UserRecorder>
</GetUser>
</soap:Body>
</soap:Envelope>
and should return the following output in XML
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<GetUserResponse xmlns="http://tempuri.org/">
<UserRecorder.Response>
<Company>string</Company>
<UserRecord.Response>
<item>
<ST>int</ST>
<LT>int</LT>
<TNo>string</TNo>
<ADate>string</ADate>
<ATime>string</ATime>
<LAT>string</LAT>
<LON>string</LON>
</item>
</UserRecord.Response>
</UserRecorder.Response>
</GetUserResponse>
</soap12:Body>
</soap12:Envelope>
==== WHAT I DID TILL NOW ===
Input step done as you can see below XML input generated from API link
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetUser xmlns="http://tempuri.org/">
<UserRecorder>
<COMPANY>string</COMPANY>
<PASSWORD>string</PASSWORD>
<USER>string</USER>
<UserRecord>
<item>
<ST>int</ST>
<LT>int</LT>
<TNO>string</TNO>
</item>
</UserRecord>
</UserRecorder>
</GetUser>
</soap:Body>
</soap:Envelope>
Now I am facing issue to generating same response as shared above. My response coming as follow: by using POSTMAN
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetUserResponse xmlns="http://tempuri.org/">
<GetUserResult><?xml version="1.0" encoding="utf-8"?><UserRecorder xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Company>TW</Company><UserRecord><item><ST>1</ST><LT>1</LT><TNo>4582</TNo><ADate>20210415</ADate><ATime>20:00:00</ATime><LAT>65.25</LAT><LON>108.24</LON></item></UserRecord></UserRecorder></GetUserResult>
</GetUserResponse>
</soap:Body>
</soap:Envelope>
My Code snippet as follows:
//CUserResponse class
public class CUserResponse
{
public class UserRecorder
{
private string company;
public string Company
{
get { return company; }
set { company = value; }
}
private UserRecord eTA_TRACK;
public UserRecord UserRecord
{
get { return eTA_TRACK; }
set { eTA_TRACK = value; }
}
}
public class UserRecord
{
private Item roots;
public Item item
{
get { return roots; }
set { roots = value; }
}
}
public class Item
{
int sALES_TYPE;
int lOCATION_TYPE;
string tANK_LORRY_NO = string.Empty;
string aLERT_DATE = string.Empty;
string aLERT_TIME = string.Empty;
string lOCATION_COORDINATES_LAT = string.Empty;
string lOCATION_COORDINATES_LON = string.Empty;
public int ST
{
get { return sALES_TYPE; }
set { sALES_TYPE = value; }
}
public int LT
{
get { return lOCATION_TYPE; }
set { lOCATION_TYPE = value; }
}
public string TNo
{
get { return tANK_LORRY_NO; }
set { tANK_LORRY_NO = value; }
}
public string ADate
{
get { return aLERT_DATE; }
set { aLERT_DATE = value; }
}
public string ATime
{
get { return aLERT_TIME; }
set { aLERT_TIME = value; }
}
public string LAT
{
get { return lOCATION_COORDINATES_LAT; }
set { lOCATION_COORDINATES_LAT = value; }
}
public string LON
{
get { return lOCATION_COORDINATES_LON; }
set { lOCATION_COORDINATES_LON = value; }
}
}
}
/// End of CUserResponse class
And asmx code is below:
//asmx code snippet
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class KECommWebService : System.Web.Services.WebService
{
#region API
public class Item
{
int sALES_TYPE;
int lOCATION_TYPE;
string tANK_LORRY_NO = string.Empty;
public int ST
{
get { return sALES_TYPE; }
set { sALES_TYPE = value; }
}
public int LT
{
get { return lOCATION_TYPE; }
set { lOCATION_TYPE = value; }
}
public string TNO
{
get { return tANK_LORRY_NO; }
set { tANK_LORRY_NO = value; }
}
}
public class UserRecord
{
private Item roots;
public Item item
{
get { return roots; }
set { roots = value; }
}
}
public class UserRecorder
{
private string company;
private string password;
private string user;
public string COMPANY
{
get { return company; }
set { company = value; }
}
public string PASSWORD
{
get { return password; }
set { password = value; }
}
public string USER
{
get { return user; }
set { user = value; }
}
private UserRecord eTA_TRACK;
public UserRecord UserRecord
{
get { return eTA_TRACK; }
set { eTA_TRACK = value; }
}
}
[WebMethod]
public string GetUser(UserRecorder UserRecorder)
{
CUserResponse.UserRecorder cETAResponse = new CUserResponse.UserRecorder();
cETAResponse.Company = "TW";
CUserResponse.UserRecord eTA_TRACKResponse = new CUserResponse.UserRecord();
CUserResponse.Item itemresponse = new CUserResponse.Item();
itemresponse.ST = 1;
itemresponse.LT = 1;
itemresponse.ADate = "20210415";
itemresponse.ATime = "20:00:00";
itemresponse.LAT = "65.25";
itemresponse.LON = "108.24";
itemresponse.TNo = "4582";
eTA_TRACKResponse.item = itemresponse;
cETAResponse.UserRecord = eTA_TRACKResponse;
Type t = cETAResponse.GetType();
var xml = "";
using (StringWriter sww = new Utf8StringWriter())
{
using (XmlWriter writer = XmlWriter.Create(sww))
{
var ns = new XmlSerializerNamespaces();
// add empty namespace
//ns.Add("", "");
XmlSerializer xsSubmit = new XmlSerializer(t);
xsSubmit.Serialize(writer, cETAResponse, ns);
xml = sww.ToString(); // Your XML
}
}
return xml;
}
public class Utf8StringWriter : StringWriter
{
public override Encoding Encoding => Encoding.UTF8;
}
#endregion
}
//END of asmx code snippet
Pl guide...
Related
I am trying to serialize the object which is having properties of type double value but output xml is having the one of the parameter value as "-0".
I am using .Net framework 3.5.
Sample code:
[Serializable]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
Public class Data
{
[XmlElement(Form = XmlSchemaForm.Unqualified)]
public double Lateral { get; set;}
}
public class Test
{
Public static void Main()
{
Test t=new Test();
Data data=new Data();
data.Lateral=0;
string xml = t.ToXml(data);
Console.WriteLine(xml);
}
Public string ToXml(Data data)
{
using (StringWriter stringWriter = new StringWriter())
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Data));
xmlSerializer.Serialize(stringWriter, data);
return stringWriter.ToString();
}
}
}
}
Output xml:
<?xml version="1.0" encoding="utf-16"?>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Lateral>-0</Lateral>
</Data>
Sometimes it happens with double 0. you can try a very simple trick
public class Data
{
private double _lateral;
public double Lateral
{
get { return _lateral + 0 ; }
set { _lateral = value; }
}
//or
public double Lateral
{
get { return _lateral; }
set { _lateral = value + 0 ; }
}
}
I am getting this error after sending my request:
System.ServiceModel.FaultException`1[FinancierAPITester.SITCustomerServiceReference.ApiError]: Unable to process the request as an attempt was made to create an abstract class. (Fault Detail is equal to FinancierAPITester.SITCustomerServiceReference.ApiError).
When sending this request:
//MessageBox.Show("Running Add Contact Details Test!");
CustomerServiceClient customerServiceClient = new CustomerServiceClient();
AddContactDetailRequest addContactDetailsRequest = new AddContactDetailRequest();
AddContactDetailResponse addContactDetailsResponse = new AddContactDetailResponse();
addContactDetailsRequest.ContactDetails = new SITCustomerServiceReference.ContactDetail();
addContactDetailsRequest.UserName = "username";
addContactDetailsRequest.Password = "password";
addContactDetailsRequest.SystemToken = systemToken;
addContactDetailsRequest.CustomerNumber = "customerNumber";
addContactDetailsRequest.ContactDetails.SequenceNumber = 1;
In SOAP UI the request works fine like this (XML):
<ns:AddContactDetail>
<!--Optional:-->
<ns:request>
<!--Optional:-->
<data:AccessToken/>
<!--Optional:-->
<data:Password>${#Project#password}</data:Password>
<!--Optional:-->
<data:ProcessId/>
<!--Optional:-->
<data:SystemToken>${#Project#systemToken}</data:SystemToken>
<!--Optional:-->
<data:UserName>${#Project#username}</data:UserName>
<!--Optional:-->
<data:ContactDetails xmlns:i="http://www.w3.org/2001/XMLSchema-instance" i:type="data:Phone">
<data:FinancierContactDetail i:nil="true"/>
<data:FinancierLocationCode i:nil="true"/>
<data:FinancierTypeCode i:nil="true"/>
<data:SequenceNumber>1</data:SequenceNumber>
<data:Number>${#TestCase#phoneNumber}</data:Number>
<data:PhoneType>${#TestCase#phoneType}</data:PhoneType>
<data:UserId i:nil="true"/>
</data:ContactDetails>
<!--Optional:-->
<data:CustomerNumber>00100000000</data:CustomerNumber>
</ns:request>
</ns:AddContactDetail>
The main problem for me is that I cant find E-Mail/Phone type after typing in addContactDetailsRequest.ContactDetails. and so Obv I expect an error when not sending the actual main contact details.
This is the definition for .ContactDetails:
[System.Runtime.Serialization.DataMemberAttribute()]
public FinancierAPITester.SITCustomerServiceReference.ContactDetail ContactDetails {
get {
return this.ContactDetailsField;
}
set {
if ((object.ReferenceEquals(this.ContactDetailsField, value) != true)) {
this.ContactDetailsField = value;
this.RaisePropertyChanged("ContactDetails");
}
}
}
More Definitions if they help:
[System.Diagnostics.DebuggerStepThroughAttribute()[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="ContactDetail", Namespace="URL")]
[System.SerializableAttribute()]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(FinancierAPITester.SITCustomerServiceReference.Fax))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(FinancierAPITester.SITCustomerServiceReference.Email))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(FinancierAPITester.SITCustomerServiceReference.Phone))]
public partial class ContactDetail : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
[System.NonSerializedAttribute()]
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private System.Nullable<int> SequenceNumberField;
[global::System.ComponentModel.BrowsableAttribute(false)]
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
get {
return this.extensionDataField;
}
set {
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public System.Nullable<int> SequenceNumber {
get {
return this.SequenceNumberField;
}
set {
if ((this.SequenceNumberField.Equals(value) != true)) {
this.SequenceNumberField = value;
this.RaisePropertyChanged("SequenceNumber");
}
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="Email", Namespace="http://financier.api.welcom.co.uk/2016/10/data")]
[System.SerializableAttribute()]
public partial class Email : FinancierAPITester.SITCustomerServiceReference.ContactDetail {
[System.Runtime.Serialization.OptionalFieldAttribute()]
private System.DateTime DateDeletedField;
private string EmailAddressField;
private FinancierAPITester.SITCustomerServiceReference.EmailType EmailTypeField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string UserIdField;
[System.Runtime.Serialization.DataMemberAttribute()]
public System.DateTime DateDeleted {
get {
return this.DateDeletedField;
}
set {
if ((this.DateDeletedField.Equals(value) != true)) {
this.DateDeletedField = value;
this.RaisePropertyChanged("DateDeleted");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
public string EmailAddress {
get {
return this.EmailAddressField;
}
set {
if ((object.ReferenceEquals(this.EmailAddressField, value) != true)) {
this.EmailAddressField = value;
this.RaisePropertyChanged("EmailAddress");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
public FinancierAPITester.SITCustomerServiceReference.EmailType EmailType {
get {
return this.EmailTypeField;
}
set {
if ((this.EmailTypeField.Equals(value) != true)) {
this.EmailTypeField = value;
this.RaisePropertyChanged("EmailType");
}
}
}
How do I add this Phone/Email/Fax type? So I can actually send the request with the E-Mail/Phone/Fax.
Thanks
The problem was I had to initialise it first then fill in the instances like below:
addContactDetailsRequest.ContactDetails = new SITCustomerServiceReference.Phone();
SITCustomerServiceReference.Phone phoneContactDetails = new Phone();
phoneContactDetails.Number = "01772444444";
phoneContactDetails.PhoneType = SITCustomerServiceReference.PhoneType.Home;
string currentDateString = "2017/06/11T00:00:00";
DateTime currentDate = Convert.ToDateTime(currentDateString);
phoneContactDetails.DateDeleted = currentDate;
addContactDetailsRequest.UserName = "UserName ";
addContactDetailsRequest.Password = "Password ";
addContactDetailsRequest.SystemToken = systemToken;
addContactDetailsRequest.CustomerNumber = "00123456789";
addContactDetailsRequest.ContactDetails.SequenceNumber = 1;
addContactDetailsRequest.ContactDetails = phoneContactDetails;
Then when it comes to including the email in the request itself just add reference it to the object of which you filled in all the details of after initialising.
I am new to SOAP Webservice. Please suggest me how to achieve following XML
I'm trying to generate C# that creates a fragment of XML like this.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<querySeatResponse xmlns="xxx">
<querySeatResult>
<querySeat_status code="int" msg="string">
<details>
<detail seat_no="string" available="string" />
<detail seat_no="string" available="string" />
</details>
</querySeat_status>
</querySeatResult>
</querySeatResponse>
</soap:Body>
</soap:Envelope>
But I am getting following Output :
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<querySeatResponse xmlns="xxx">
<querySeatResult>
<querySeat_status code="int" msg="string">
<details>
<detail xsi:nil="true" />
<detail xsi:nil="true" />
</details>
</querySeat_status>
</querySeatResult>
</querySeatResponse>
</soap:Body>
</soap:Envelope>
My Source Code as follows :
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class abc : System.Web.Services.WebService
{
[WebMethod]
[SoapDocumentMethod("xxx", RequestNamespace = "xxx", ResponseNamespace = "xxx", Use = SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Wrapped)]
public querySeat_Main querySeat([XmlAttribute] string signature, string operator_code, string route_id, string trip_no, string depart_date, string counter_from, string counter_to, string bus_type)
{
querySeat_Main main = new querySeat_Main();
querySeat_status status = new querySeat_status();
querySeat_status.detail detail = new querySeat_status.detail();
status.code = 0;
status.msg = "success";
main.querySeat_status = status;
return main;
}
}
[Serializable]
[GeneratedCode("System.Xml", "xxxx")]
[XmlType(Namespace = "xxx")]
[DebuggerStepThrough]
[DesignerCategory("code")]
public class querySeat_Main
{
querySeat_status status;
public querySeat_Main()
{
}
public querySeat_status querySeat_status { get { return status; } set { status = value; } }
}
[Serializable]
[GeneratedCode("System.Xml", "xxx")]
[XmlType(Namespace = "xxx")]
[DebuggerStepThrough]
[DesignerCategory("code")]
[XmlRoot("querySeat_status", Namespace = "xxx")]
public class querySeat_status
{
int Code;
string Msg;
public querySeat_status() { }
[XmlAttribute]
public int code { get { return Code; } set { Code = value; } }
[XmlAttribute]
public string msg { get { return Msg; } set { Msg = value; } }
[XmlArray("details")]
[XmlArrayItem("detail")]
public List<detail> details = new List<detail>();
[Serializable]
[GeneratedCode("System.Xml", "xxx")]
[DebuggerStepThrough]
[DesignerCategory("code")]
[XmlRoot("querySeat_status", Namespace = "xxx")]
public class detail
{
string seat;
string avail;
public detail() { }
[XmlAttribute]
public string seat_no { get { return seat; } set { seat = value; } }
[XmlAttribute]
public string available { get { return avail; } set { avail = value; } }
}
}
As mentioned by Alex, looks like you don't initialize your details, you can try:
public querySeat_Main querySeat([XmlAttribute] string signature, string operator_code, string route_id, string trip_no, string depart_date, string counter_from, string counter_to, string bus_type)
{
querySeat_Main main = new querySeat_Main();
querySeat_status status = new querySeat_status();
querySeat_status.detail detail = new querySeat_status.detail();
detail.available = "no";
detail.seat_no = "7";
status.code = 0;
status.details = new List<querySeat_status.detail>();
status.details.Add(detail);
status.msg = "success";
main.querySeat_status = status;
return main;
}
so i have this problem i`m trying to serialize my classes to the point that they will look like this:
<orders>
<order>
<ordersID>22070</ordersID>
<ordersTotal>53.00</ordersTotal>
<prod>
<productCount>1</productCount>
<productPrice>2.00</productPrice>
<productPricePromo>0.00</productPricePromo>
<productDiscount>0</productDiscount>
<productName>Шампоан против косопад Loreal Density Advanced 500 мл.</productName>
<productNumber>30055</productNumber>
</prod>
<prod>
<productCount>1</productCount>
<productPrice>6.00</productPrice>
<productPricePromo>0.00</productPricePromo>
<productDiscount>0</productDiscount>
<productName>Маска за суха коса Loreal Интенс Рипер 200 мл.</productName>
<productNumber>30107</productNumber>
</prod>
</order>
</orders>
But whatever i try e end up like this:
<?xml version="1.0" encoding="UTF-8"?>
<orders xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<order>
<order>
<ordersID>0</ordersID>
<ordersTotal>0</ordersTotal>
<products>
<progducts>
<productCount>0</productCount>
<productPrice>0</productPrice>
<productPricePromo>0</productPricePromo>
<productDiscount>0</productDiscount>
<productNumber>0</productNumber>
</progducts>
<progducts>
<productCount>0</productCount>
<productPrice>0</productPrice>
<productPricePromo>0</productPricePromo>
<productDiscount>0</productDiscount>
<productNumber>0</productNumber>
</progducts>
</products>
</order>
</order>
</orders>
The problem is the names of the second and third class i`m using is geting listed as tags aswell inside the xml. So my question is: is there any way around this?
Here is my code aswell.
Classes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace testXML
{
[Serializable]
public class orders
{
private List <order> m_order = new List <order>();
[XmlArrayItem(typeof(order))]
public List<order> order
{
get { return m_order; }
set { m_order = value; }
}
}
[Serializable]
public class order
{
public int ordersID { get; set; }
public double ordersTotal { get; set; }
private List<progducts> prod = new List<progducts>();
[XmlArrayItem(typeof(progducts))]
public List<progducts> products
{
get { return prod; }
set { prod = value; }
}
}
[Serializable]
public class progducts
{
public string productName { get; set; }
public int productCount { get; set; }
public double productPrice { get; set; }
public double productPricePromo { get; set; }
public double productDiscount { get; set; }
public Int64 productNumber { get; set; }
}
}
And here is the execution code:
orders f = new orders();
order or = new order();
progducts p1 = new progducts();
progducts p2 = new progducts();
f.order.Add(or);
or.products.Add(p1);
or.products.Add(p2);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(orders));
TextWriter writer = new StreamWriter("Family.xml");
xmlSerializer.Serialize(writer, f);
writer.Close();
Thank you for any help in advance!
Replace the [XmlArrayItem(typeof(order))] with [XmlElement("order")] and [XmlArrayItem(typeof(progducts))] with [XmlElement("prod")]. That will remove one level when serializing the lists.
Just add another attributes to your property order like this:
[XmlArray("orders")]
[XmlArrayItem("order", typeof(order))]
public List<order> order
{
get { return m_order; }
set { m_order = value; }
}
That should work.
If you use the following classes which were generated using xsd.exe:
using System.Xml.Serialization;
using System;
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class orders
{
private ordersOrder orderField;
public ordersOrder order
{
get
{
return this.orderField;
}
set
{
this.orderField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class ordersOrder
{
private int ordersIDField;
private double ordersTotalField;
private ordersOrderProd[] prodField;
public int ordersID
{
get
{
return this.ordersIDField;
}
set
{
this.ordersIDField = value;
}
}
public double ordersTotal
{
get
{
return this.ordersTotalField;
}
set
{
this.ordersTotalField = value;
}
}
[System.Xml.Serialization.XmlElementAttribute("prod")]
public ordersOrderProd[] prod
{
get
{
return this.prodField;
}
set
{
this.prodField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class ordersOrderProd
{
private int productCountField;
private double productPriceField;
private double productPricePromoField;
private double productDiscountField;
private string productNameField;
private Int64 productNumberField;
public int productCount
{
get
{
return this.productCountField;
}
set
{
this.productCountField = value;
}
}
public double productPrice
{
get
{
return this.productPriceField;
}
set
{
this.productPriceField = value;
}
}
public double productPricePromo
{
get
{
return this.productPricePromoField;
}
set
{
this.productPricePromoField = value;
}
}
public double productDiscount
{
get
{
return this.productDiscountField;
}
set
{
this.productDiscountField = value;
}
}
public string productName
{
get
{
return this.productNameField;
}
set
{
this.productNameField = value;
}
}
public Int64 productNumber
{
get
{
return this.productNumberField;
}
set
{
this.productNumberField = value;
}
}
}
Then the following code:
var orders = new orders
{
order = new ordersOrder
{
ordersID = 1,
ordersTotal = 1,
prod = new ordersOrderProd[]
{
new ordersOrderProd
{
productCount = 1,
productDiscount = 8.4,
productName = "Widget",
productNumber = 987987,
productPrice = 78.9,
productPricePromo = 68.75
}
}
}
};
XmlSerializer xmlSerializer = new XmlSerializer(typeof(orders));
TextWriter writer = new StreamWriter(".\\Family.xml");
xmlSerializer.Serialize(writer, orders);
writer.Close();
Gives you the following output:
<?xml version="1.0" encoding="utf-8"?>
<orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<order>
<ordersID>1</ordersID>
<ordersTotal>1</ordersTotal>
<prod>
<productCount>1</productCount>
<productPrice>78.9</productPrice>
<productPricePromo>68.75</productPricePromo>
<productDiscount>8.4</productDiscount>
<productName>Widget</productName>
<productNumber>987987</productNumber>
</prod>
</order>
</orders>
You can use a serialization attribute to change the names of the XML elements or attributes you want to represent your class structure. See MSDN
I need to be able to define two nodes with the same name but completely different subnode structures. I didn't design this XML schema but for the time being I'm forced to use it as is. I realize it's a terrible abuse of everything that is XML but there you have it.
What I need it to look like:
<order>
<ItemType type="Clubs">
<Club num="1">
<ClubName>Some Name</ClubName>
<ClubChoice>Something Else</ClubChoice>
</Club>
</ItemType>
<ItemType type="Gift" val="MailGreeting">
<GiftName>MailGreeting</GiftName>
<GiftDescription></GiftDescription>
<GiftQuanity>1</GiftQuanity>
</ItemType
</order>
Of course it's far more complicated than but you get the gist.
I'm using XmlSerializer and would really like to avoid using XDocument but if that's what I need to do then so be it.
If your order contains properties and not a list you can tell the serializer to name the elements like this:
[XmlRoot("order")]
public class Order
{
private Whatever whateverInstance;
[XmlElement("ItemType")]
public Whatever WhateverInstance
{
get { return whateverInstance; }
set { whateverInstance = value; }
}
private Something somethingInstance;
[XmlElement("ItemType")]
public Something SomethingInstance
{
get { return somethingInstance; }
set { somethingInstance = value; }
}
}
If it's a list of things you could get to have a identical element name as well but you will get a redundant xsi:Type attribute:
[XmlRoot("order")]
public class Order
{
private ItemType[] itemTypes;
[XmlElement("ItemType")]
public ItemType[] ItemTypes
{
get { return itemTypes; }
set { itemTypes = value; }
}
}
[XmlInclude(typeof(Clubs))]
[XmlInclude(typeof(Gift))]
public abstract class ItemType
{
private string type = "None";
[XmlAttribute]
public string Type
{
get { return type; }
set { type = value; }
}
}
public class Clubs : ItemType
{
public Clubs()
{
Type = "Clubs";
}
private Club[] clubsArray;
[XmlElement("Club")]
public Club[] ClubsArray
{
get { return clubsArray; }
set { clubsArray = value; }
}
}
public class Club
{
private int num = 0;
[XmlAttribute("num")]
public int Num
{
get { return num; }
set { num = value; }
}
private string clubName = "";
public string ClubName
{
get { return clubName; }
set { clubName = value; }
}
private string clubChoice = "";
public string ClubChoice
{
get { return clubChoice; }
set { clubChoice = value; }
}
}
public class Gift : ItemType
{
public Gift()
{
Type = "Gift";
}
private string val = "";
[XmlAttribute("val")]
public string Val
{
get { return val; }
set { val = value; }
}
private string giftName = "";
public string GiftName
{
get { return giftName; }
set { giftName = value; }
}
private string giftDescription = "";
public string GiftDescription
{
get { return giftDescription; }
set { giftDescription = value; }
}
private int giftQuanity = 0;
public int GiftQuanity
{
get { return giftQuanity; }
set { giftQuanity = value; }
}
}
Test:
List<ItemType> list = new List<ItemType>();
list.Add(new Clubs() { ClubsArray = new Club[] { new Club() { Num = 0, ClubName = "Some Name", ClubChoice = "Something Else" } } });
list.Add(new Gift() { Val = "MailGreeting", GiftName = "MailGreeting", GiftDescription = "GiftDescription", GiftQuanity = 1});
Order order = new Order();
rder.ItemTypes = list.ToArray();
XmlSerializer serializer = new XmlSerializer(typeof(Order));
StreamWriter sw = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Stuff.xml");
serializer.Serialize(sw, order);
sw.Close();
Output:
<order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ItemType xsi:type="Clubs" Type="Clubs">
<Club num="0">
<ClubName>Some Name</ClubName>
<ClubChoice>Something Else</ClubChoice>
</Club>
</ItemType>
<ItemType xsi:type="Gift" Type="Gift" val="MailGreeting">
<GiftName>MailGreeting</GiftName>
<GiftDescription>GiftDescription</GiftDescription>
<GiftQuanity>1</GiftQuanity>
</ItemType>
</order>