2012-05-28 97 views
1

我有一個要求,我必須使用System.Object作爲WCF中的參數。由於它不是可序列化的,因爲它使用System.Object,因此操作不受支持,所以我收到消息。任何解決這個問題的方法。WCF System.Object序列化

+10

那是什麼讓你想送'object'(原因這是完全沒有合同的)通過一個面向契約的協議?此外(我恨我自己甚至提到它) - 你有沒有嘗試通過配置啓用NetDataContractSerializer? –

+0

如果一個對象不會序列化任何東西,你期望在另一邊得到什麼? –

回答

5

當通過線路發送消息時,默認情況下,WCF將只序列化足夠的信息以獲得消息,即合同的成員。如果您的消息以「對象」作爲參數,則需要使用類型信息通過線路發送額外的信息。如果在客戶端和服務器上使用相同的程序集,則可以在服務器(和客戶端)中使用NetDataContractSerializer(而不是默認的DataContractSerializer),並且它們將能夠交換任意對象,如下面的代碼。但是,正如@MarcGravell提到的,這可能不是WCF的最佳使用...

的代碼,以使NetDataContractSerializer

public class Post_8b2c7ad7_b1c3_410b_b907_f25cee637110 
{ 
    public class Person 
    { 
     public string Name { get; set; } 
     public int Age { get; set; } 
     public override string ToString() 
     { 
      return string.Format("Person[Name={0},Age={1}]", Name, Age); 
     } 
    } 
    [ServiceContract] 
    public interface ITest 
    { 
     [OperationContract] 
     object Echo(object obj); 
    } 
    public class Service : ITest 
    { 
     public object Echo(object obj) 
     { 
      return obj; 
     } 
    } 
    public class ReplaceSerializerOperationBehavior : DataContractSerializerOperationBehavior 
    { 
     public ReplaceSerializerOperationBehavior(OperationDescription operation) 
      : base(operation) 
     { 
     } 
     public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes) 
     { 
      return new NetDataContractSerializer(name, ns); 
     } 
     public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes) 
     { 
      return new NetDataContractSerializer(name, ns); 
     } 
     public static void ReplaceSerializer(ServiceEndpoint endpoint) 
     { 
      foreach (var operation in endpoint.Contract.Operations) 
      { 
       for (int i = 0; i < operation.Behaviors.Count; i++) 
       { 
        if (operation.Behaviors[i] is DataContractSerializerOperationBehavior) 
        { 
         operation.Behaviors[i] = new ReplaceSerializerOperationBehavior(operation); 
         break; 
        } 
       } 
      } 
     } 
    } 
    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); 
     var endpoint = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), ""); 
     ReplaceSerializerOperationBehavior.ReplaceSerializer(endpoint); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress)); 
     ReplaceSerializerOperationBehavior.ReplaceSerializer(factory.Endpoint); 
     ITest proxy = factory.CreateChannel(); 
     Console.WriteLine(proxy.Echo("Hello")); 
     Console.WriteLine(proxy.Echo(123.456)); 
     Console.WriteLine(proxy.Echo(new Uri("http://tempuri.org"))); 
     Console.WriteLine(proxy.Echo(new Person { Name = "John Doe", Age = 33 })); 

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

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