我有两个SccmAction和TicketAction类,它们都实现了接口IDelivery。这些类将在一个处理队列上传输,我只想从中获取消息并对Deliver方法采取行动。
但是我似乎无法反序列化到接口,因为当我尝试这样做时,会抛出 System.NotSupportedException 。根据我收集的内容,XMLSerializer需要一个具体的类型来进行序列化。这是否让我不得不创建一个实现IDelivery并从中继承SccmAction和ArsAction的抽象类?我错过了什么吗?
编辑进一步澄清
我可能有设计缺陷,但我的目的是从包含这些对象的队列中提取消息。我的目的是让所有离开此队列的对象实现接口,确保处理对象的应用程序只对Deliver方法进行操作。 Deliver的每个对象实现都会有所不同。
反序列化代码
using (SqlConnection connection =
new SqlConnection(ConnectionString))
{
SqlCommand command = new SqlCommand(ReceiveString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
byte[] sb = (byte[])reader["message_body"];
SccmAction sa = DeserializeObject<SccmAction>(sb);
IDelivery iD = DeserializeObject<IDelivery>(sb);
}
reader.Close();
}
public static T DeserializeObject<T>(byte[] ba)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
MemoryStream memoryStream = new MemoryStream(ba);
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
return (T)xs.Deserialize(memoryStream);
}
类和接口
[Serializable]
public class SccmAction : IDelivery
{
public string MachineName { get; set; }
public string CollectionName { get; set; }
public string Action { get; set; }
public DateTime EntryDateTime { get; set; }
public SccmAction () { }
public void Deliver()
{
throw new NotImplementedException();
}
}
[Serializable]
public class ArsAction : IDelivery
{
public string MachineName { get; set; }
public string CustomerName { get; set; }
public ArsAction() { }
public void Deliver()
{
throw new NotImplementedException();
}
}
public interface IDelivery
{
void Deliver();
}
答案 0 :(得分:4)
简单地说,您无法在没有任何肮脏的情况下序列化界面。但是,为什么你想要序列化你的界面,它没有任何状态。它只有一个方法声明。
您可能希望在类中创建Serialize方法。所以他们可以单独序列化,他们知道他们是哪种类型。
此外,您如何期望XmlSerializer在不提供的情况下反序列化为精确类型?它不能简单地选择反序列化的内容......
然而,您可以更改此行
IDelivery iD = DeserializeObject<IDelivery>(sb);
到这个
IDelivery iD = DeserializeObject<SccmAction>(sb);
如果您不知道最初要反序列化的类型(ArsAction或SccmAction),那么您可以执行类似的操作。
public static IDelivery DeserializeFromString(string xml)
{
//replace this stream with whatever you are useing
StringReader strReader = new StringReader(xml);
XmlReader reader = new XmlTextReader(fs); //important to use XmlReader
reader.MoveToContent(); //move to root
String className = reader.Name.Trim(); //read the class name
//use the namespace IDelivery is located in
className = "IDeliveryNamespace." + className;
//get the type
Type classType = Type.GetType(className);
XmlSerializer serializer = new XmlSerializer(Type.GetType(className));
// Declare an object variable of the type to be deserialized.
IDelivery i;
// Use the Deserialize method to restore the object's state.
i = (IDelivery)Convert.ChangeType(serializer.Deserialize(reader),classType);
return i;
}
当然,这假设您的Serializable类名称未更改。意思是ArsAction类序列化,并且据我所知,你可以告诉我的情况。
这段代码有点脏,但它应该给你一个起点。