将未知对象序列化为xml

时间:2012-11-21 16:04:50

标签: xml generics object serialization

我有一个我希望通过WCF服务发送的对象,这需要能够序列化和对象,我可能不知道它的类型。我看到这适用于主要类型,但是对于引用类型,我无法成功序列化值。在下面的测试中,我在调试时尝试序列化List或Tuple对象时收到错误消息。在不知道类型的情况下,是否有一种很好的方法来执行此过程?

[DataContract]
public class SizingObject
{
    [DataMember]
    public List<SizingItem> SizingItems { get; set; }
}

[DataContract]
public class SizingItem
{
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Value { get; set; }

    [DataMember]
    public string Unit { get; set; }

    [DataMember]
    public string ListItemId { get; set; }

    [DataMember]
    public object Item { get; set; }
}

[DataContract] public class SizingObject { [DataMember] public List<SizingItem> SizingItems { get; set; } } [DataContract] public class SizingItem { [DataMember] public string Name { get; set; } [DataMember] public string Value { get; set; } [DataMember] public string Unit { get; set; } [DataMember] public string ListItemId { get; set; } [DataMember] public object Item { get; set; } }

        var i = new SizingObject();
        i.SizingItems = new List<SizingItem>();
        i.SizingItems.Add(new SizingItem
                              {
                                  Item = "String",
                                  ListItemId = string.Empty,
                                  Name = "string item",
                                  Unit = string.Empty,
                                  Value = string.Empty
                              });

        i.SizingItems.Add(new SizingItem
                              {
                                  Item = 0.23,
                                  ListItemId = string.Empty,
                                  Name = "double item",
                                  Unit = string.Empty,
                                  Value = string.Empty
                              });

        i.SizingItems.Add(new SizingItem
                              {
                                  Item = new List<double> { 3, 4, 5, 6 },
                                  ListItemId = string.Empty,
                                  Name = "list<double> item",
                                  Unit = string.Empty,
                                  Value = string.Empty
                              });

        i.SizingItems.Add(new SizingItem
                              {
                                  Item = new Tuple<string, double>("TupleItem", 2.00),
                                  ListItemId = string.Empty,
                                  Name = "Tuple<string, double> item",
                                  Unit = string.Empty,
                                  Value = string.Empty
                              });

        // Serialize User Data
        var stringWriter = new StringWriter();
        var serializer1 = new XmlSerializer(typeof(SizingObject));
        serializer1.Serialize(stringWriter, i);
        var xml = stringWriter.ToString();

        var serializer2 = new XmlSerializer(typeof(SizingObject));
        i = (SizingObject)serializer2.Deserialize(new StringReader(xml));

        var dict = new Dictionary<Type, Func<object, object>>();
        dict.Add(typeof(string), e => e as string);
        dict.Add(typeof(double), e => e);
        dict.Add(typeof(List<double>), e => e as List<double>);
        dict.Add(typeof(Tuple<string, double>), e => e as Tuple<string, double>);

        foreach (var item in i.SizingItems)
        {
            var result = dict[item.Item.GetType()].Invoke(item.Item);
        }

2 个答案:

答案 0 :(得分:0)

曾经想过只是将其作为Object发送?

假设您在两端都有“模板”类的副本,您可以将其作为对象发送,然后将其转发到接收端的类型。

另一个想法是将其作为XML传输,假设没有真正敏感的信息,并在接收端重建类。

答案 1 :(得分:0)

我发现当我花费更多时间并提供一组已知类型时,我能够解决这个问题。我无法序列化Tuple类型,因此必须创建一个替代方案,但这是我预期的,因为它的类型,列表和其他对象现在完全可序列化。

var types = new Type[] { typeof(string), typeof(double), typeof(List), typeof(WCFTuple) };

            // Serialize User Data
            var stringWriter = new StringWriter();
            var serializer1 = new XmlSerializer(typeof(SizingObject), types);
            serializer1.Serialize(stringWriter, i);
            var xml = stringWriter.ToString();

            // Deserialize object.
            var serializer2 = new XmlSerializer(typeof(SizingObject), types);
            i = (SizingObject)serializer2.Deserialize(new StringReader(xml));

// Serialize User Data var stringWriter = new StringWriter(); var serializer1 = new XmlSerializer(typeof(SizingObject), types); serializer1.Serialize(stringWriter, i); var xml = stringWriter.ToString(); // Deserialize object. var serializer2 = new XmlSerializer(typeof(SizingObject), types); i = (SizingObject)serializer2.Deserialize(new StringReader(xml));