WEB API using C# - c#

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

.Net Xml serialization appending negative sign to 0

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 ; }
}
}

Solving Web-service Objects/Instances

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.

How do I give an attributes to array list item during serialization in c#

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;
}

XML serialization troubles

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

Serialize two nodes with the same name but different child nodes

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>

Categories

Resources