У меня есть сценарий, в котором объекты Request являются XML-запросами и отправляются обратно на TCP-сервер для обработки. Сериализация выполняется с помощью устаревшей структуры. Излишне говорить, что я не могу вносить изменения в устаревшую структуру.
Устаревшая структура, однако, достаточно умен, чтобы понять, реализует ли объект запроса IXmlSerializable
, в этом случае для выполнения сериализации используется метод WriteXml интерфейса.
Я хотел сохранить максимальный контроль над процессом serailzation в моей руке, поэтому я написал свой класс RequestBase следующим образом:
public abstract class RequestBase : IXmlSerializable
{
[XmlElement("Environment")]
public string BaseEnvironment { get; set; }
protected RequestBase()
{
}
protected RequestBase(string environment, string image):this()
{
HaloEnvironment = environment;
}
XmlSchema IXmlSerializable.GetSchema()
{
return null;
}
void IXmlSerializable.ReadXml(XmlReader reader)
{
throw new NotImplementedException();
}
void IXmlSerializable.WriteXml(XmlWriter writer)
{
WriteXml(writer);
}
protected virtual void WriteXml(XmlWriter writer)
{
}
}
Класс такой же простой, как можно себе представить. Любой объект запроса должен его реализовать. Примерный класс запроса выглядит следующим образом:
[XmlRoot("MyCuteRoot")]
public class CuteRequest : RequestBase
{
public string CuteName { get; set; }
public CuteRequest ()
{
}
protected override void WriteXml(XmlWriter writer)
{
writer.WriteStartElement("Parameters");
writer.WriteStartElement("header");
if (!string.IsNullOrWhiteSpace(BaseEnvironment ))
writer.WriteElementString("Environment", BaseEnvironment );
if (!string.IsNullOrWhiteSpace(CuteName ))
writer.WriteElementString("CuteNode", CuteName );
writer.WriteEndElement();//header
writer.WriteEndElement();//Parameters
}
}
Вышеуказанный класс дал мне следующий Xml:
<MyCuteRoot>
<Parameters>
<header>
<Environment>Developer</Environment>
<CuteNode>a2</CuteNode>
</header>
</Parameters>
</MyCuteRoot>
Солнце было ярким до сих пор, и я был счастлив, так как это сработало.
Затем появился сценарий, в котором сервер backend начал ожидать что-то, что он назвал BulkRequest. Теперь запросы будут интегрированы в коллекцию.
Я попытался обработать эту ситуацию со следующим классом BulkRequest:
public class BulkRequest:RequestBase
{
public IEnumerable<RequestBase> Requests { get; private set; }
public BulkRequest(IEnumerable<RequestBase> requests)
{
if (requests == null)
throw new ArgumentNullException("requests");
Requests = requests;
}
public BulkRequest()
{
}
protected override void WriteXml(XmlWriter writer)
{
foreach (RequestBase requestBase in Requests)
{
(requestBase as IXmlSerializable).WriteXml(writer);
}
}
}
Теперь это не работает. Я хочу, чтобы xml выглядел следующим образом:
<STPRequest>
<MyCuteRequest>
<Parameters>
<header>
<Environment>Developer</Environment>
<CuteName>a2</CuteName>
</header>
</Parameters>
</MyCuteRequest>
<MyCuteRequest>
<Parameters>
<header>
<Environment>Developer</Environment>
<CuteName>a2</CuteName>
</header>
</Parameters>
</MyCuteRequest>
</STPRequest>
это для двух объектов CuteRequest, присутствующих в Массовом запросе. Но я получаю следующий xml:
<STPRequest>
<BulkRequest>
<Parameters>
<header>
<Environment>Developer</Environment>
<CuteName>a2</CuteName>
</header>
</Parameters>
<Parameters>
<header>
<Environment>Developer</Environment>
<CuteName>a2</CuteName>
</header>
</Parameters>
</BulkRequest>
</STPRequest>
Проблемы: два:
-
Как избавиться от тега BulkRequest, который сам заставляет себя.
-
Как сделать значения XmlRoot элементов (например, MyCuteRequest) появляться в Xml (включая тег Параметры.)
Я благодарю вас за ваше терпение за то, что прочитал это. Любая помощь будет оценена по мере того, как через пару часов googling окажется бесполезным.
С уважением,