简体   繁体   English

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

[英]Why can't WCF pass an object in a dictionary?

In my WCF service I have the object QualifiedNumber defined as KnownType and ServiceKnown type. 在我的WCF服务中,我将对象QualifiedNumber定义为KnownTypeServiceKnown类型。 If I used the QualifiedNumber in the following methods: 如果我在以下方法中使用了QualifiedNumber

This one does NOT work. 这一项不起作用。 It throws an exception that in part reads: 它抛出一个部分读取的异常:

Element ' http://schemas.microsoft.com/2003/10/Serialization/Arrays:Value ' contains data of the ' http://schemas.datacontract.org/2004/07 ServiceLibrary.Web.Model:QualifiedNumber' data contract. 元素' http://schemas.microsoft.com/2003/10/Serialization/Arrays:Value '包含' http://schemas.datacontract.org/2004/07 ServiceLibrary.Web.Model:QualifiedNumber'数据协定的数据。 The deserializer has no knowledge of any type that maps to this contract. 解串器不知道任何映射到该合同的类型。 cannot deserialize because the definition of QualifiedNumber is not known. 无法反序列化,因为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;
}

This one DOES work 这确实起作用

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;
}

What is it about the dictionary that causes the exception? 导致异常的字典是什么?

Here is a detailed article on generic dictionary serialization over WCF: 这是有关通过WCF进行通用词典序列化的详细文章:

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

The takeaway quote from that article would be: 该文章的外卖报价为:

There is no way to meaningfully convey the semantics of a .NET dictionary class using WSDL/XSD. 无法使用WSDL / XSD有意义地传达.NET词典类的语义。

You simply need to add the following property to your datacontract class. 您只需要向datacontract类添加以下属性。

[DataMember]
public object UsedForKnownTypeSerializationObject;

So now the generated proxy contains the Knowtypes you set on the datacontract. 因此,现在生成的代理包含您在数据合同上设置的知识类型。 I had the same problem and this is the only solution I came up with. 我遇到了同样的问题,这是我想到的唯一解决方案。 If you don't at the a property of type Object to you DataContract class, the generated proxy doesn't contain the declared knowtypes 如果您不在DataContract类的Object类型的属性中,则生成的代理不包含声明的知识类型

For example: 例如:

[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; }

}

It's not as pretty because you end up with a dummy property which doesn't have any functional implementation. 它不是那么漂亮,因为您最终得到一个没有任何功能实现的虚拟属性。 But then again I don't have another solution. 但话又说回来,我没有其他解决方案。

You could wrap the Dictionary in a List. 您可以将字典包装在列表中。 So your code would look like: 因此您的代码如下所示:

[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;
}

It´s not really pretty. 这不是很漂亮。 But an easy way to tranfer a Dictionary via WCF. 但是通过WCF传输字典的一种简单方法。

使用Serializeable属性标记QualifiedNumber

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM