为什么 WCF 不能传递字典中的对象

本文关键字:对象 字典 WCF 不能 为什么 | 更新日期: 2023-09-27 17:55:46

在我的 WCF 服务中,我将对象QualifiedNumber定义为KnownTypeServiceKnown类型。如果我在以下方法中使用QualifiedNumber

这个不起作用。 它抛出一个异常,部分内容如下:

元素"http://schemas.microsoft.com/2003/10/Serialization/Arrays:Value"包含"http://schemas.datacontract.org/2004/07 ServiceLibrary.Web.Model:QualifiedNumber"数据合约的数据。 反序列化程序不知道映射到此协定的任何类型的内容。 无法反序列化,因为 QualifiedNumber 的定义未知。

[OperationContract]
public Dictionary<int, object> TestDictionaryGet()
{
    Dictionary<int, object> retDict = new Dictionary<int, object>();
    retDict.Add(1, new QualifiedNumber(new decimal(1.2), "<"));
    retDict.Add(2, "pass a simple string");
    return retDict;
}

这个确实有效

public struct element
{
    public int key;
    public object value;
}
[OperationContract]
public List<element> TestElementListGet()
{
    Dictionary<int, object> retDict = new Dictionary<int, object>();
    retDict.Add(1, new QualifiedNumber(new decimal(1.2), "<"));
    retDict.Add(2, "pass a simple string");
    List<element> retElements = new List<element>();
    foreach (KeyValuePair<int, object> item in retDict)
    {
        element newElement;
        newElement.key = item.Key;
        newElement.value = item.Value;
        retElements.Add(newElement);
    }
    return retElements;
}

导致异常的字典是什么?

为什么 WCF 不能传递字典中的对象

下面是有关通过 WCF 进行泛型字典序列化的详细文章:

http://www.request-response.com/blog/PermaLink,guid,ff5fab81-affb-4b2b-aa67-c80bdfc86cbd.aspx

该文章的要点是:

没有办法使用 WSDL/XSD 有意义地传达 .NET 字典类的语义。

只需将

以下属性添加到数据协定类中即可。

[DataMember]
public object UsedForKnownTypeSerializationObject;

因此,现在生成的代理包含您在数据协定上设置的知识类型。我遇到了同样的问题,这是我想出的唯一解决方案。如果您不在 DataContract 类的 Object 类型的 a 属性中,则生成的代理不包含声明的 knowtypes

例如:

[DataContract]
[KnownType(typeof(List<String>))]
public class Foo
{
    [DataMember]
    public String FooName { get; set; }
    [DataMember]
    public IDictionary<String, Object> Inputs { get; set; }
    [DataMember]
    private Object UsedForKnownTypeSerializationObject{ get; set; }
}

它不那么漂亮,因为你最终得到一个没有任何功能实现的虚拟属性。但话又说回来,我没有其他解决方案。

标记QualifiedNumber Serializeable属性。

您可以将字典包装在列表中。因此,您的代码将如下所示:

[OperationContract]
public List<Dictionary<int, object>> TestDictionaryGet()
{
    var resultList = new List<Dictionary<int, object>>();
    Dictionary<int, object> retDict = new Dictionary<int, object>();
    retDict.Add(1, new QualifiedNumber(new decimal(1.2), "<"));
    retDict.Add(2, "pass a simple string");
    resultList.Add(retDict);
    return resultList;
}

它不是很漂亮。但是通过 WCF 传输字典的一种简单方法。