首页 文章

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

提问于
浏览
5

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

这个不起作用 . 它引发了一个异常,部分内容如下:

元素'http://schemas.microsoft.com/2003/10/Serialization/Arrays:Value'包含'http://schemas.datacontract.org/2004/07 ServiceLibrary.Web.Model:QualifiedNumber'数据的数据 Contract . 反序列化器不知道映射到此 Contract 的任何类型 . 无法反序列化,因为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;
}

什么是导致异常的字典?

4 回答

  • 1

    这是关于WCF上的通用字典序列化的详细文章:

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

    该文章的内容引用如下:

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

  • 0

    您只需将以下属性添加到datacontract类 .

    [DataMember]
    public object UsedForKnownTypeSerializationObject;
    

    所以现在生成的代理包含您在datacontract上设置的Knowtypes . 我有同样的问题,这是我提出的唯一解决方案 . 如果您没有在DataContract类的Object类型的属性,生成的代理不包含声明的知识类型

    例如:

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

    它并不漂亮,因为你最终得到了一个没有任何功能实现的虚拟属性 . 但话说再说一遍,我没有其他解决办法 .

  • 4

    使用 Serializeable 属性标记 QualifiedNumber .

  • 0

    您可以将Dictionary包装在List中 . 所以你的代码看起来像:

    [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传输Dictionary的简单方法 .

相关问题