2011-03-04 67 views
1

我有一个泛型集合作为我与WCF序列化属性的类:什么属性用于序列化WCF中的集合?

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    TestObject Load(); 
} 

[DataContract] 
public class TestObject 
{ 
    [DataMember] 
    public Collection<object> Properties = new Collection<object>(); 
} 

它正常工作,直到我添加另一个集合作为集合中的(一个项目由“坏线”表示评论)

public class Service1 : IService1 
{ 
    public TestObject Load() 
    { 
     var obj = new TestObject(); 

     // bad line 
     obj.Properties.Add(new Collection<object>()); 

     return obj; 
    } 
} 

在这我得到异常:

System.ServiceModel.CommunicationException:远程服务器返回错误:NOTFOUND。

如果我删除的TestObject类,只是返回一个集合,然后添加其他集合进行收集奇怪的是正常工作:

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    Collection<object> Load(); 
} 

public class Service1 : IService1 
{ 
    public Collection<object> Load() 
    { 
     Collection<object> coll = new Collection<object>(); 

     coll.Add(DateTime.Now); 
     coll.Add(new Collection<object>() { DateTime.Now, new Collection<object>() }); 
     coll.Add("sdf"); 
     coll.Add(99); 

     return coll; 
    } 
} 

我试着与列表或一个ArrayList更换集合。我已经尝试从Collection创建我自己的派生类。我试过使用DataContract,KnownType,ServiceKnownType和CollectionDataContract属性的组合,但我要么不正确地使用它们,要么我有另一个问题。

那么有没有办法在第一个示例中通过应用属性或使用派生类将集合添加到我的集合中?或者有什么办法可以做到这一点?

+0

不记得我之前做了什么;只是从集合创建了一个派生类,并在派生类中添加了'Serializable'属性,不确定是否有成员,但可能也需要。 – eSPiYa 2011-03-04 05:28:49

回答

2

第一个示例的问题是Collection<object>等同于object [] - 任意值的数组。您需要告诉WCF集合可以包含哪些类型的值(通过使用数据协定中的[KnownTypeAttribute]或服务协定中的[ServiceKnownTypeAttribute]) - 即使此类值为Collection<object>。当我在数据合同上添加[KnownType(Collection <object>)]时,下面的代码有效。

public class StackOverflow_5189844_751090 
{ 
    [ServiceContract] 
    public interface IService1 
    { 
     [OperationContract] 
     TestObject Load(); 
    } 
    [DataContract] 
    [KnownType(typeof(Collection<object>))] 
    public class TestObject 
    { 
     [DataMember] 
     public Collection<object> Properties = new Collection<object>(); 
    } 
    public class Service1 : IService1 
    { 
     public TestObject Load() 
     { 
      var obj = new TestObject(); 

      // bad line 
      obj.Properties.Add(new Collection<object>()); 

      return obj; 
     } 
    } 
    static Binding GetBinding() 
    { 
     BasicHttpBinding result = new BasicHttpBinding(); 
     //Change binding settings here 
     return result; 
    } 
    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     ServiceHost host = new ServiceHost(typeof(Service1), new Uri(baseAddress)); 
     host.AddServiceEndpoint(typeof(IService1), GetBinding(), ""); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     var factory = new ChannelFactory<IService1>(GetBinding(), new EndpointAddress(baseAddress)); 
     var proxy = factory.CreateChannel(); 
     Console.WriteLine(proxy.Load()); 

     ((IClientChannel)proxy).Close(); 
     factory.Close(); 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 

在第二种情况下,因为收藏是经营合同的一部分,它被认为是已知类型为操作的一部分,所以它并不需要刻意添加。原始类型(字符串,数字,DateTime)也不需要显式声明,它们已经被WCF“知道”了。