Начну с пояснения что в моем понимании означает сериализация. Сериализация - проебразование объекта к определенной, стандартизованной структуре с возможностью обратного преобразования к исходной структуре. Например, можно сериализовать произвольный DataSet, после десериализации сериализованный объект загружается непосредственно в целевой DataSet.
Как правило объекты сериализуются в какие-то битовые структуры, в частности в строки. Как частный случай - XML сериализация, когда сериализованный объект представляется в виде строки, имеющей XML структуру. Это подход очень удобен при передаче данных по HTTP протоколу. Так как это текстовый протокол, то и передавать по нему можно только текст. Чтобы передать произвольный объект нам и пригодится XML-сериализация.
Здесь я приведу пример, как можно сериализовать объект и послать его по HTTP протоколу в методе POST и принять и преобразовать к объекту на клиенте:
Например, имеем описание объекта:
public class Content
{
public Content() {}
[XmlAttribute] //означает, что атрибут бедут именно в структуре атрибута узла
public string type = "text/plain";
[XmlText] //основное значения узла
public string MSG;
}
[XmlRoot("Message")] //переименовываем название по-умолчания для того, чтобы в структуре XML файла узел назывался именно так
public class SMSMessage {
public SMSMessage() {}
[XmlAttribute]
public int id;
[XmlAttribute("submit-date")] //присваиваем определенное имя данному атрибуту
public DateTime submitdate;
[XmlAttribute]
public string msisdn;
[XmlAttribute("service-number")]
public string short_number;
[XmlAttribute("operator")]
public string network;
public Content content;
}
[XmlRoot("sms-request")]
public class SMSRequest {
public SMSRequest(){}
[XmlAttribute]
public string version = "1.0";
[XmlElement("message",typeof(SMSMessage))] //Указываем на то, что структура является контейнером для объектов типа SMSMessage
public SMSMessage[] Messages;
}
Пример сериализованного объекта выглядить следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<sms-request xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="
http://www.w3.org/2001/XMLSchema" version="1.0">
<message id="1" submit-date="2007-12-15T13:03:47.703125+04:00" msisdn="79277338091" service-number="3533" operator="MFVolga">
<content type="text/plain">Недвижимость</content>
</message>
</sms-request>
Объектов <message> может существовать сколько угодно, т.к. sms-request является контейнером для данного класса
Как же происходит сериалисзация? Во первых для того чтобы были доступны все классы и методы, необходимо подключить сборки:
using System.Xml.Serialization;
using System.IO;
using System.Web;
using System.Xml;
Следующие несколько строк произведут сериализацию (преобразование объекта класса SMSRequest в строковую переменную:
MemoryStream memoryStream = new MemoryStream();
XmlSerializer serializer = new XmlSerializer(typeof(SMSRequest));
XmlTextWriter xmlWriter = new XmlTextWriter(memoryStream,System.Text.Encoding.UTF8);
xmlWriter.Formatting = Formatting.Indented;
serializer.Serialize(xmlWriter, _SMSRequest);
memoryStream = (MemoryStream)xmlWriter.BaseStream;
string xml = UTF8ByteArrayToString(memoryStream.ToArray());
Теперь предположим, что у нас есть WEBService, который в качестве входного параметра получает объект типа SMSReqeust (его работу рассмотрим ниже). Вот этому сервису и передаем наш объект в методе POST:
System.Net.WebRequest req = System.Net.WebRequest.Create("
http://localhost/serviceXML.asmx/SMSko");
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(xml);
req.ContentLength = bytes.Length;
System.IO.Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
System.Net.WebResponse resp = req.GetResponse();
System.IO.StreamReader sr1 = new System.IO.StreamReader(resp.GetResponseStream());
string ServiceResponce = sr1.ReadToEnd().Trim();
Вот таким вот нехитрым образом получаем ответ от WEB сервиса. Скорее всего сервис тоже отвечает нам сериализованным объектом. Точнее, не скорее всего, а точно, но это уже не принципиально. Рассмотрим работу данного сервиса. Хочу отметить, что он тоже должен знать структуру и особенности сериализации объекта SMSRequest, описанного выше. Для этого есть два способа: также описать класс в WEB-сервисе, либо вынести описание сериализуемого класса в отедльную сборку и использовать ее в клиентской и серверной части, точнее, на обоих концах цепочки POST-GET. Итак, имеем одинаковое описание сериализуемых классов... Нам теперь надо реализовать функцию SMSko (см. URL в System.Net.WebRequest req = System.Net.WebRequest.Create("
http://localhost/serviceXML.asmx/SMSko");):
System.Web.HttpRequest request = System.Web.HttpContext.Current.Request;
System.Web.HttpResponse responce = System.Web.HttpContext.Current.Response;
byte[] b = new Byte[request.InputStream.Length];
if (request.InputStream.Length > 0)
{
b = request.BinaryRead((int)request.InputStream.Length);
}
//Десериализуем SMSRequest
SMSRequest _SMSRequest = SMSRequest.Deserialize(b);
Теперь делаем что угодно с полученным объектом _SMSRequets и отправляем ответ. В нашем случае - объект SMSResponce
[XmlRoot("sms-response")]
public class SMSResponce {
public SMSResponce() {}
public SMSResponce(SMSRequest SMSR) {
Messages = new SMSMessage[SMSR.Messages.Length];
for (int i = 0; i < SMSR.Messages.Length; i++)
{
Messages[i] = new SMSMessage();
Messages[i].content = SMSR.Messages[i].content;
Messages[i].ref_id = SMSR.Messages[i].id;
Messages[i].msisdn = SMSR.Messages[i].msisdn;
Messages[i].network = SMSR.Messages[i].network;
Messages[i].short_number = SMSR.Messages[i].short_number;
Messages[i].submitdate = DateTime.Now;
}
}
public byte[] Serialize()
{
MemoryStream memoryStream = new MemoryStream();
XmlSerializer serializer = new XmlSerializer(typeof(SMSResponce));
XmlTextWriter xmlWriter = new XmlTextWriter(memoryStream, System.Text.Encoding.UTF8);
xmlWriter.Formatting = Formatting.Indented;
serializer.Serialize(xmlWriter, this);
memoryStream = (MemoryStream)xmlWriter.BaseStream;
return memoryStream.ToArray();
}
[XmlAttribute]
public string version = "1.0";
[XmlElement("message", typeof(SMSMessage))]
public SMSMessage[] Messages;
[XmlAttribute("delivery-notificaton-requested")]
public string delivery_notificaton_requested = "false";
}
его можно удобно использовать, например вот так:
SMSResponce _SMSResponce = new SMSResponce(_SMSRequest);
UserResponse UR = IC.IncomeMessage(_SMSRequest.Messages[i].msisdn,
_SMSRequest.Messages[i].short_number,
_SMSRequest.Messages[i].content.MSG.ToUpper(),
_SMSRequest.Messages[i].network.ToUpper());
_SMSResponce.Messages[i].id = i;
_SMSResponce.Messages[i].content.MSG ="Посетите наш сайт www.smsestate.ru";
теперь сериализуем объект, всего одна строчка!!!
xml = UTF8ByteArrayToString(_SMSResponce.Serialize());
и отправляем его в responce:
responce.Clear();
responce.ContentType = "text/html";
responce.Write(xml);
responce.End();
Все... Наша связка по отправке-получению обеъктов готова...
Может возникнуть логичный вопрос, почему используем именно MemoryStream при сериализации? На самом деле выбрать кодировку (в нашем случае System.Text.Encoding.UTF8) можно только в случае использования MemoryStream или файлового обмена, сериализация непосредственно в строку по умолчанию использует кодировку utf-16 и изменить этот параметр никак нельзя. Так, что если вашим сервисам и приложениям позволительно работать в кодировке utf-16, можно использовать сериализацию непосредственно в строку без MemoryStream...
Всем успехов...