object로 받은 결과를 xmlInclude 형식으로 쓰기 싫어서 만들어봄
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace API.HelloWorld.Response
{
[Serializable]
//[XmlInclude(typeof(DB.HelloWorld.Table.Hello.HelloData))]
//[XmlInclude(typeof(DB.HelloWorld.Table.Hello.HelloDataArray))]
[DataContract(Namespace = "")]
public class Result : IXmlSerializable
{
private Credential credential = null;
[XmlIgnore]
public Credential Credential { get => credential; set => credential = value; }
[XmlElement("credential", IsNullable = false)]
public string XmlCredential
{
set { }
get
{
return credential != null ? credential.ToXmlSerializable() : null;
}
}
private object data = null;
[XmlElement(IsNullable =false, Namespace ="")]
public object Data { set => data = value; get => data == null ? null : Convert.ChangeType(data, data.GetType()); }
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
throw new NotImplementedException();
}
public void WriteXml(XmlWriter writer)
{
if (credential != null)
{
writer.WriteStartElement("credential");
writer.WriteString(credential.ToXmlSerializable());
writer.WriteEndElement();
}
if (data != null)
{
#region Root
var d = data.GetType().GetCustomAttributes(true);
if (d.Any(r => r.GetType().Equals(typeof(System.Xml.Serialization.XmlRootAttribute))))
{
var t = (System.Xml.Serialization.XmlRootAttribute)Convert.ChangeType(d.Where(r => r.GetType().Equals(typeof(System.Xml.Serialization.XmlRootAttribute))).First(), typeof(System.Xml.Serialization.XmlRootAttribute));
writer.WriteStartElement(t.ElementName);
}
else
{
if (!data.GetType().IsArray)
{
writer.WriteStartElement(data.GetType().Name.ToString());
}
else
{
writer.WriteStartElement(data.GetType().Name.ToString().Replace("[", "").Replace("]", "") + "Array");
}
}
if (!data.GetType().IsArray)
{
XmlObjectWriter(writer, data);
}
else
{
var c = ConvertCast<dynamic>(data);
foreach (var i in c)
{
XmlRootObjectWriter(writer, i);
}
}
writer.WriteEndElement();
#endregion Root
}
}
private T ConvertCast<T>(object o)
{
return (T)Convert.ChangeType(o, o.GetType());
}
private void XmlRootObjectWriter(XmlWriter writer, object data)
{
#region Root
var d = data.GetType().GetCustomAttributes(true);
if (d.Any(r => r.GetType().Equals(typeof(System.Xml.Serialization.XmlRootAttribute))))
{
var t = (System.Xml.Serialization.XmlRootAttribute)Convert.ChangeType(d.Where(r => r.GetType().Equals(typeof(System.Xml.Serialization.XmlRootAttribute))).First(), typeof(System.Xml.Serialization.XmlRootAttribute));
writer.WriteStartElement(t.ElementName);
}
else
{
writer.WriteStartElement(data.GetType().Name);
}
if (!data.GetType().IsArray)
{
XmlObjectWriter(writer, data);
}
else
{
var c = ConvertCast<dynamic>(data);
foreach (var i in c)
{
XmlObjectWriter(writer, i);
}
}
writer.WriteEndElement();
#endregion Root
}
//static int count = 0;
private void XmlObjectWriter(XmlWriter writer, object data)
{
#region element
////get set 찾기
var propertyList = data.GetType().GetMembers().Where(r => r.MemberType == System.Reflection.MemberTypes.Property);
foreach (var m in propertyList)
{
object output = data.GetType().GetProperty(m.Name.ToString()).GetValue(data);
if (output == null)
continue;
if (m.GetCustomAttributes(true).Any(r => r.GetType() == typeof(System.Xml.Serialization.XmlIgnoreAttribute)))
continue;
if (m.GetCustomAttributes(true).Any(r => r.GetType() == typeof(System.Xml.Serialization.XmlElementAttribute)))
{
var t = (System.Xml.Serialization.XmlElementAttribute)Convert.ChangeType(m.GetCustomAttributes(true).Where(r => r.GetType().Equals(typeof(System.Xml.Serialization.XmlElementAttribute))).First(), typeof(System.Xml.Serialization.XmlElementAttribute));
writer.WriteStartElement(t.ElementName);
//count++;
}
else
{
continue;
}
if (!output.GetType().IsArray)
{
var child = output.GetType().GetMembers().Where(r => r.MemberType == System.Reflection.MemberTypes.Property);
if (child.Count() == 0 || data.GetType().GetProperty(m.Name.ToString()).PropertyType == typeof(string))
{
writer.WriteString(output.ToString());
}
else
{
XmlObjectWriter(writer, output);
}
}
else
{
//배열인 경우 XmlRoot를 추가
var c = ConvertCast<dynamic>(output);
foreach (var i in c)
{
XmlRootObjectWriter(writer, i);
}
}
writer.WriteEndElement();
//count--;
}
#endregion element
}
}
}
'개발관련 > C#' 카테고리의 다른 글
ObjectSerialize (0) | 2017.08.10 |
---|---|
Aes 암호화/복호화 (0) | 2017.08.10 |
XmlSerializer (0) | 2017.08.03 |
Http Handler 비동기 처리 (0) | 2017.07.25 |
구글 billing 영수증 검증 토큰 얻기 (4) | 2017.06.28 |