Folks,Элементы управления в XML C# сериализации
Я пытаюсь создать базовый класс с элементами, которые будут существовать в нескольких различных типов классов. Я близок к решению, но мне нужно немного больше контролировать вывод из класса XML Serializer.
UPDATE
Ok на основе ответа ниже я добавил Serializable интерфейс для Xml и получили немного дальше.
Ниже представлен выход из моего нового тестового APP, первые два вывода XML, как я ожидаю, третий близок, но ему не хватает пространства имен в корневом элементе, и мне нужно, чтобы SomeNewNameForPData действовал так, как если бы это была PData, т. Е. нет PData, как показано в последнем показанном XML, а также отсутствие приложения из базового класса запросов. См. Окончательный пример ожидаемого вывода.
<?xml version="1.0" encoding="utf-8"?>
<Payment1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Application="MyApp">
<Pdata Language="en">
<TimeStamp>2016-06-17T15:31:37.7767381+01:00</TimeStamp>
</Pdata>
<RequestType>Pay1</RequestType>
</Payment1>
<?xml version="1.0" encoding="utf-8"?>
<Payment2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Application="MyApp">
<Sender>ProgramClass</Sender>
<RequestType>Pay2</RequestType>
</Payment2>
<?xml version="1.0" encoding="utf-8"?>
<Payment3>
<SomeNewNameForPData>
<P_Data Language="en">
<TimeStamp>2016-06-17T15:31:37.7767381+01:00</TimeStamp>
</P_Data>
</SomeNewNameForPData>
</Payment3>
Ожидаемый результат:
<?xml version="1.0" encoding="utf-8"?>
<Payment3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Application="MyApp">
<SomeNewNameForPData Language="en">
<TimeStamp>2016-06-17T15:31:37.7767381+01:00</TimeStamp>
</SomeNewNameForPData>
</Payment3>
Обновленный код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.ComponentModel;
using System.Xml;
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)
{
Request cp = new Payment1() { Application = "MyApp", DataField = new P_Data() { Language = "en" } };
Request cp2 = new Payment2() { Application = "MyApp", Sender = "ProgramClass" };
Request cp3 = new Payment3() { Application = "MyApp", DataField = new P_Data() { Language = "en" } };
string s1 = cp.MessageAsString();
string s2 = cp2.MessageAsString();
string s3 = cp3.MessageAsString();
Console.WriteLine(s1);
Console.WriteLine("");
Console.WriteLine(s2);
Console.WriteLine("");
Console.WriteLine(s3);
Console.ReadKey();
}
}
public class Helpers : StringWriter
{
public override Encoding Encoding
{
get { return Encoding.UTF8; }
}
}
public abstract class Request
{
[XmlAttribute()]
public string Application { get; set; }
public virtual string MessageAsString()
{
return CreateMessage();
}
private string CreateMessage()
{
return SerializeObject<Request>(this, null);
}
public static string SerializeObject<X>(X toSerialize, XmlSerializerNamespaces xmlNameSpace)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
StringWriter textWriter = new StringWriter();
string utf8 = ""; ;
using (StringWriter writer = new Helpers())
{
xmlSerializer.Serialize(writer, toSerialize, xmlNameSpace);
utf8 = writer.ToString();
}
return utf8;
}
}
public abstract class RequestType1 : Request
{
public RequestType1()
{
}
[XmlIgnore()]
public abstract string RequestType { get; set; }
[XmlElement("Pdata")]
public virtual P_Data DataField { get; set; }
}
public abstract class RequestType2 : Request
{
public RequestType2()
{
}
[XmlIgnore()]
public abstract string RequestType { get; set; }
public string Sender { get; set; }
}
[Serializable]
public abstract class RequestType3 : RequestType1, IXmlSerializable
{
public RequestType3()
{
}
[XmlElement("SomeNewNameForPData")]
public override P_Data DataField { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
throw new NotImplementedException();
}
public void ReadXml(XmlReader reader)
{
throw new NotImplementedException();
}
public void WriteXml(XmlWriter writer)
{
writer.WriteStartElement("SomeNewNameForPData");
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
new XmlSerializer(typeof(P_Data)).Serialize(writer, this.DataField, ns);
writer.WriteEndElement();
}
}
public class Payment1 : RequestType1
{
public Payment1()
{
}
public override string RequestType
{
get
{
return "Pay1";
}
set { }
}
}
public class Payment2 : RequestType2
{
public Payment2()
{
}
public override string RequestType
{
get
{
return "Pay2";
}
set { }
}
}
public class Payment3 : RequestType3
{
public Payment3()
{
}
public override string RequestType
{
get
{
return "Pay3";
}
set { }
}
}
public class P_Data
{
public P_Data()
{
//We need to format the datetime field
TimeStamp = DateTime.Now;
}
[XmlAttribute, DefaultValue("")]
public string Language { get; set; }
public DateTime TimeStamp { get; set; }
}
}
Так что мои вопросы:
Как добавить или сохранить пространство имен в корневом элементе для Payment3 при использовании custo m WriteXml, мне также нужно предоставить средства для записи элементов базового класса или не получить их в силу того факта, что я сериализую класс с помощью XmlSerializer на основе его типа?
мне нужно SomeNewNameForPData действовать, как если бы оно было PDATA, т.е. не PDATA наглядного
Добавить обратно в Заявлении от базового класса Request.
ТИА
Можете ли вы объяснить, почему вы не хотите для отображения узла ''? –
Я использую Nodes в качестве плачхолдера для различных кланов, которые могут существовать в Request или RequestType2, поэтому этот список NODE добавляется с разными классами в зависимости от того, что требуется третьей стороне. В классе Nodes я указываю все элементы, которые могут существовать, это всего лишь подмножество из них для демонстрационных целей, чтобы объяснить проблему. –