XmlSerializer反系列化问题

CalenNet 2010-10-04 07:33:27
在三层架构中,客户端按照XmlSerializer方式系列化了一个实体类,然后通过TCP发送到服务端,同时也发送了实体类的文件名、命名空间、Class名称等信息
由于实体类涉及Class比较多,不想一个个罗列,希望服务端通过反射形式,对这个XML进行反系列化

问题就是:
当客户端告知服务端程序当前的XML文件是SocketListening.Entity.T_SizeType这个Class的情况下,如何通过反射模式进行反系列化?


其中的一个实体类如下:


using System;
using System.Collections.Generic;
using System.Text;

namespace SocketListening.Entity
{
#region T_SizeType的存储过程实体类代码

public class T_SizeType
{
private int m_intSizeTypeCTN = 0;
private string m_strSizeType = "";
private string m_strSizeCTN = "";
private string m_strTypeCTN = "";
private string m_strWhereCondition = "";
private string m_strOrderByExpression = "";

public int SizeTypeCTN
{
get { return m_intSizeTypeCTN; }
set { m_intSizeTypeCTN = value; }
}
public string SizeType
{
get { return m_strSizeType; }
set { m_strSizeType = value; }
}
public string SizeCTN
{
get { return m_strSizeCTN; }
set { m_strSizeCTN = value; }
}
public string TypeCTN
{
get { return m_strTypeCTN; }
set { m_strTypeCTN = value; }
}
public string WhereCondition
{
get { return m_strWhereCondition; }
set { m_strWhereCondition = value; }
}
public string OrderByExpression
{
get { return m_strOrderByExpression; }
set { m_strOrderByExpression = value; }
}

}
#endregion
}




系列化反系列化如下:

public string XmlSerializeMS<T>(T t)
{
try
{
String mXmlString = null;
System.IO.MemoryStream mMS = new System.IO.MemoryStream();

System.Xml.Serialization.XmlSerializer mXS = new System.Xml.Serialization.XmlSerializer(typeof(T));

mXS.Serialize(mMS, t);

mXmlString = Convert.ToBase64String(mMS.ToArray());

return mXmlString;
}
catch (NullReferenceException NullEx)
{
throw NullEx;
}
catch (Exception Ex)
{
throw Ex;
}
}

public T XmlDeserializeMS<T>(string pXmlString)
{
try
{
System.Xml.Serialization.XmlSerializer mXS = new System.Xml.Serialization.XmlSerializer(typeof(T));

System.IO.MemoryStream mMS = new System.IO.MemoryStream(Convert.FromBase64String(pXmlString));

return (T)mXS.Deserialize(mMS);
}
catch (NullReferenceException NullEx)
{
throw NullEx;
}
catch (Exception Ex)
{
throw Ex;
}
}



系列化调用代码:

string mEntityXML = "";
SocketListening.Entity.T_SizeType mEST = new SocketListening.Entity.T_SizeType();

mEntityXML = XmlSerializeMS<SocketListening.Entity.T_SizeType>(mEST);


...全文
130 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
JiuchunYoung 2010-10-04
  • 打赏
  • 举报
回复
不是太懂
CalenNet 2010-10-04
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 wuyq11 的回复:]
反射获取T,一样调用
(Test)objType = Assembly.Load(_path).CreateInstance(namespace+"."+classname);
[/Quote]


关键是这里得不到(Test)


我用object mObj 写入函数调用可以通过,就是object 可以转换到SocketListening.Entity.T_SizeType
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 calennet 的回复:]
程序就通过了
但是SocketListening.Entity.T_SizeType 是通过一个文本来告知的,并且已经告知了
object mObj = mXS.Deserialize(mMS);
语句中的Object如何制定成通过放射获取到的SocketListening.Entity.T_SizeType 这个Class?[/Quote]

这就不符合实际了。实际使用中,编写反射和解析程序时,设计者只知道接口规范,然后要求mObj应该具有此接口,并按照此接口进行接下来的操作。

然后,当这个系统发布给其它程序员使用时,其它人(甚至是之后引用它的其它工程)才发明了Entity.T_SizeType 这个class。

如果不是这种用法,你又何必要反序列呢?
danjiewu 2010-10-04
  • 打赏
  • 举报
回复
LZ想要的目的是什么?反射得到的只能是object,因为编译期无法确定类型。
如果你想统一的进行一些操作,可以定义一个共同的父类或者接口。
wuyq11 2010-10-04
  • 打赏
  • 举报
回复
反射获取T,一样调用
(Test)objType = Assembly.Load(_path).CreateInstance(namespace+"."+classname);
CalenNet 2010-10-04
  • 打赏
  • 举报
回复
楼上的倒是给了个思路,我把原先的
System.Xml.Serialization.XmlSerializer mXS = new System.Xml.Serialization.XmlSerializer(typeof(T));
换成
System.Xml.Serialization.XmlSerializer mXS = new System.Xml.Serialization.XmlSerializer(mType);
程序就通过了
但是SocketListening.Entity.T_SizeType 是通过一个文本来告知的,并且已经告知了
object mObj = mXS.Deserialize(mMS);
语句中的Object如何制定成通过放射获取到的SocketListening.Entity.T_SizeType 这个Class?

目前通过快速监视,看到反系列化出来的mObj 却是是T_SizeType 这个class结构,数据也相同


System.Reflection.Assembly mAssembly = System.Reflection.Assembly.Load(mMiddlewares.MS[i].MH.EntityApp);

foreach (Type mType in mAssembly.GetTypes())
{
if ((mType.Namespace + "." + mType.Name) == mMiddlewares.MS[i].MH.Entity)
{
System.Xml.Serialization.XmlSerializer mXS = new System.Xml.Serialization.XmlSerializer(mType);
System.IO.MemoryStream mMS = new System.IO.MemoryStream(Convert.FromBase64String(mMiddlewares.MS[i].ME.Entity));
object mObj = mXS.Deserialize(mMS);

break;
}
}
  • 打赏
  • 举报
回复
这个设计问题根本不符合泛型的思路。
  • 打赏
  • 举报
回复
不是使用泛型<T>,而是根据“发送了实体类的文件名、命名空间、Class名称等信息”反射(Assembly.Load(...).GetType(...))得到类型t,然后写
System.Xml.Serialization.XmlSerializer mXS = new System.Xml.Serialization.XmlSerializer(t);
CalenNet 2010-10-04
  • 打赏
  • 举报
回复
楼上的解答不对地
我要通过放射方式来反系列化,而并不是通过一个已知的Class来反系列化
就是byte[] bytes = SerializeBinary<Test>(new Test());这个语句的<Test>是未知的


wuyq11 2010-10-04
  • 打赏
  • 举报
回复
[Serializable]
public class Test
{
public int id {get;set;};
}
public static byte[] SerializeBinary<T>(T t)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
System.IO.MemoryStream memStream = new System.IO.MemoryStream();
serializer.Serialize(memStream, t);
return memStream.GetBuffer();
}
public static T DeserializeBinary<T>(byte[] buf)
{
System.IO.MemoryStream memStream = new MemoryStream(buf);
memStream.Position = 0;
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deserializer =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
T t= (T)deserializer.Deserialize(memStream);
memStream.Close();
return t;
}
byte[] bytes = SerializeBinary<Test>(new Test());

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧