C#学习教程:WCF服务返回字典数组当字典中的值是像int、string或Guid这样的简单类型时,这会很好地工作。但是,我现在有一个场景,我需要其中一个值是Dictionary的数组!这一切都编译得很好,服务的签名没有改变,但服务调用现在失败了。任何想法如何解决它?我试图用KnownType和ServiceKnownType属性注释我的服务类和方法,但这没有用。这是一段代码:[ServiceContract(Namespace="")][AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]publicclassService1{[OperationContract][ServiceKnownType(typeof(Dictionary))]publicDictionaryGetObject(){returnnewDictionary(){{"pty1",1},{"pty2",Guid.NewGuid()},{"pty3","blah"},{"pty4",newDictionary[]{newDictionary(){{“pty1”,4},{“pty2”,Guid.NewGuid()},{“pty3”,“blah”},},newDictionary(){{“pty1”,4},{“pty2”,Guid.NewGuid()},{"pty3","blahblah"},}}}};}}谢谢您的回答。我启用了WCF跟踪,而且正如所怀疑的那样,在序列化过程中出现了问题。问题不是字典的序列化,而是字典数组之一。这是WCF服务记录的异常。尝试序列化参数时出错:GetObjectResult。InnerException消息是“类型”System.Collections.Generic.Dictionary`2[[System.String,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089],[System.Object,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089]][]',数据协定名称为“ArrayOfArrayOfKeyValueOfstringanyType:http://schemas.microsoft.com/2003/10/Serialization/Arrays”,不应使用。将任何静态未知类型添加到已知类型列表中-例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。有关详细信息,请参阅InnerException。我还尝试用单个数据成员定义一个新的DataContract类,但它导致了同样的错误。这是代码,后面是WCF记录的异常。[DataContract][KnownType(typeof(ObjectHolder))]publicclassObjectHolder{[DataMember]publicobjectObject{get;私有集;}publicObjectHolder(objectobj){this.Object=obj;}}尝试序列化参数时出错:GetObjectResult。InnerException消息是“类型”System.Collections.Generic.Dictionary`2[[System.String,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089],[SilverlightApplication7.Web.ObjectHolder,SilverlightApplication7.Web,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null]][]',数据协定名称“ArrayOfArrayOfKeyValueOfstringObjectHolderWAwxSTlb:http://schemas.microsoft.com/2003/10/Serialization/Arrays”,不是预期的。将任何静态未知类型添加到已知类型列表中-例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。有关详细信息,请参阅InnerException。我再次使用ObjectHolder、ObjectHolder[]甚至ObjectHolder[][]ServiceKnownType,因为异常提到“ArrayOfArrayOfKeyValueOfstringObjectHolder”。目前还没有解决办法。首先,您应该在应用程序配置文件中配置WCF跟踪,以帮助您了解服务正在通信的内容。在这种情况下,您可以轻松获取通信过程中发生的所有错误。现在,让我们尝试解决您的问题。我对已知类型的问题非常有信心。在面向服务的世界中,您应该手动定义所有可以参与服务契约的具体类型,因为DataContractSerializer不在序列化对象中提供此类信息。在这种情况下,这意味着您应该执行以下操作:[ServiceKnownType(typeof(string))][ServiceKnownType(typeof(Guid))][ServiceKnownType(typeof(int))]//但我认为DataContractSerializer可以处理原语[ServiceKnownType(typeof(YourClass))]//您应该手动添加的用户定义类型publicDictionaryGetObject()另外我建议您不要在服务合同中使用对象,因为它很容易出错。考虑一下,您或您的同事随后修改了一行代码:newDictionary(){{"pty1",4},{"pty2",Guid.NewGuid()},{"pty3",newSomeClass()},//糟糕!!!在这种情况下,当您的服务尝试返回此字典时,您将遇到运行时失败,因为DataContractSerializer不期望此协定中的SomeClass。解决这个问题的一种方法是创建单独的类型:[DataContract][KnownType(typeof(Guid))][KnownType(typeof(SomeClass1))][KnownType(typeof(SomeClass2))]obj){对象=obj;}publicstaticMyTypeFromSomeClass1(SomeClass1c1){returnnewMyType(c1);}publicstaticMyTypeFromSomeClass2(SomeClass2c2){returnnewMyType(c2);}publicstaticMyTypeFromGuid(Guidguid){returnnewMyType(guid);}[DataMember]publicobjectObject{get;私有集;在这种情况下,如果你想添加一些新的类型,你应该添加一个工厂方法和一个KnownTypeAttribute(这个方法更详细,但更不容易出错)。但是,如果您的客户端和服务是在WCF上编写的,您可以牺牲面向服务的主要原则并使用NetDataContractSerializer而不是DataContractSerializer。NetDataContractSerializer旨在补充DataContractSerializer。您可以使用NetDataContractSerializer序列化类型并使用DataContractSerializer反序列化。但是NetDataContractSerializer在序列化的XML中包含CLR类型信息,而DataContractSerializer则没有。因此,NetDataContractSerializer可用于任何CLR类型的序列化和反序列化,而无需任何KnownType。尝试定义一个具有单个属性的类。该属性是字符串、对象的字典。用DataContract/DataMember标记类。然后使用该类来定义您的接口。但是,我现在有一个场景,我需要其中一个值是一个字典数组!问题是WCF不知道如何序列化/反序列化未标记DataMember属性和/或未添加到ServiceKnownType的对象数组。例如,如果有一些服务方法将任何对象作为参数publicinterfaceIServicefunctionDoSomething(ParameterasObject)作为整数端接口,并且你想传递一个整数数组Integer(),你必须显式添加这个整数数组服务于已知类型的类型。publicinterfaceIServicefunctionDoSomething(ParameterasObject)asintegerendinterface然后可以调用服务方法dimServiceasIServicedimArgumentasInteger()Service.DoSomething(Argument)知道如何解决吗?尝试添加属性。以上就是C#学习教程:WCF服务返回字典数组共享的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
