C# WCF服务返回字典数组<;字符串,对象>;

C# WCF服务返回字典数组<;字符串,对象>;,c#,wcf,dictionary,object,C#,Wcf,Dictionary,Object,我一直在尝试使用SilverLight客户端调用ASP.Net WCF服务,该服务将返回字典。 当字典中的值是简单的类型,如int、string或Guid时,这种方法工作得很好 但是,我现在有一个场景,其中需要一个值作为字典的数组!它编译得很好,服务的签名没有改变,但是服务调用现在失败了 有没有办法解决这个问题?我试图用KnownType和servicenowntype属性对我的服务类和方法进行注释,但没用 下面是一段代码: [ServiceContract(Namespace = "")] [

我一直在尝试使用SilverLight客户端调用ASP.Net WCF服务,该服务将返回
字典。
当字典中的值是简单的类型,如
int
string
Guid
时,这种方法工作得很好

但是,我现在有一个场景,其中需要一个值作为
字典的数组
!它编译得很好,服务的签名没有改变,但是服务调用现在失败了

有没有办法解决这个问题?我试图用
KnownType
servicenowntype
属性对我的服务类和方法进行注释,但没用

下面是一段代码:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1
{
    [OperationContract]
    [ServiceKnownType(typeof(Dictionary<string, object>))]
    public Dictionary<string, object> GetObject()
    {
        return new Dictionary<string, object>()
            {
                { "pty1", 1 },
                { "pty2", Guid.NewGuid() },
                { "pty3", "blah" },
                { "pty4", new Dictionary<string, object>[]
                              {
                                  new Dictionary<string, object>()
                                      {
                                          { "pty1", 4 },
                                          { "pty2", Guid.NewGuid() },
                                          { "pty3", "blah" },
                                      }
                                   ,
                                   new Dictionary<string, object>()
                                      {
                                          { "pty1", 4 },
                                          { "pty2", Guid.NewGuid() },
                                          { "pty3", "blahblah" },
                                      }
                              }
            }
        };
    }
}
new Dictionary<string, object>()
{
 { "pty1", 4 },
 { "pty2", Guid.NewGuid() },
 { "pty3", new SomeClass() }, //OOPS!!!
}
尝试序列化参数GetObjectResult时出错。InnerException消息为'Type'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][]不应使用数据协定名称为“ArrayOfKeyValueOfStringObjectHolderWawXSTLB:”的“ArrayOfArrayOfKeyValueOfstringObjectHolderWAwxSTlb:”。将任何静态未知的类型添加到已知类型列表中-例如,使用KnownTypeAttribute属性或将其添加到传递给DataContractSerializer的已知类型列表中。“。有关更多详细信息,请参阅InnerException

我再次为
ObjectHolder
ObjectHolder[]
甚至
ObjectHolder[][]
使用了
ServiceKnownType
,因为异常提到了“
ArrayOfKeyValueOfStringObjectHolder


仍然没有解决方案。

尝试定义一个具有单个属性的类。该属性是字符串、对象的字典

用DataContract/DataMember标记该类。然后使用该类定义您的接口。

首先,您应该在app cofig文件中定义接口,该文件可以帮助您了解在服务通信的引擎盖下发生了什么。在这种情况下,您可以轻松获得通信过程中发生的所有错误

现在,让我们试着解决你的问题。我几乎确信这个问题是已知类型的。在面向服务的世界中,您应该手动定义可以参与服务契约的所有具体类型,因为DataContractSerializer在序列化对象中不提供此类信息

在这种情况下,这意味着您应该执行以下操作:

[ServiceKnownType(typeof(string))] 
[ServiceKnownType(typeof(Guid))]
[ServiceKnownType(typeof(int))] // but I think DataContractSerializer can deal himself with primitives
[ServiceKnownType(typeof(YourClass))] //UserDefined types you should add manually
public Dictionary<string, object> GetObject()
在这种情况下,如果您想添加一些新类型,您应该添加factory方法和KnownTypeAttribute(这种方法更详细,但不太容易出错)

然而,如果您的客户机和服务是在WCF上编写的,那么您可以牺牲主要的面向服务的原则而使用它。NetDataContractSerializer旨在补充DataContractSerializer。您可以使用NetDataContractSerializer序列化类型,并使用DataContractSerializer反序列化。但是NetDataContractSerializer在序列化的XML中包含CLR类型信息,而DataContractSerializer不包含。因此,NetDataContractSerializer可以用于任何CLR类型的序列化和反序列化,而无需任何KnownTypes内容

然而,我现在有一个场景,我需要一个值作为字典数组

问题是WCF不知道如何序列化/反序列化未标记有
DataMember
属性和/或未添加到
ServiceKnownType
s的对象数组

例如,如果有某种服务方法,它将任意对象作为参数

public interface IService
    function DoSomething(Parameter as Object) as integer
end interface
如果要传递,比如一个整数数组
Integer()
,则必须显式地将此整数数组类型添加到服务已知类型

<ServiceKnownType(GetType(Integer()))>
public interface IService
    function DoSomething(Parameter as Object) as integer
end interface
有没有办法解决这个问题


尝试添加
属性。

我猜WCF在序列化对象时可能会遇到问题。如果可行的话,你可以试着编字典。我同意sipwiz的观点,你将很难把字典连载起来。应该使字典包含可序列化的对象(这意味着你需要一个接一个地更改你的字典。我相信字典按照你期望的方式序列化会有问题。它不可互操作。这是最好的答案,你可以通过指出字典不是未知类型的字典,而是字典中包含的对象类型来改进它。这就是为什么添加[ServiceKnownType(typeof(Dictionary))]没有帮助,而添加[ServiceKnownType(typeof(typeof)(对象可能是什么类型)]会有帮助。
public interface IService
    function DoSomething(Parameter as Object) as integer
end interface
<ServiceKnownType(GetType(Integer()))>
public interface IService
    function DoSomething(Parameter as Object) as integer
end interface
dim Service as IService
dim Argument as Integer()
Service.DoSomething(Argument)