2011-03-04 39 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「知道」了。