2008-10-01 58 views
2

使用.Net 3.0和VS2005。屬性未包含在生成的代理類中

所討論的對象是從WCF服務中消耗的,然後爲舊版API重新串入XML。因此,不是序列化TestObject,而是序列化缺少[XmlRoot]屬性的.TestObject;然而,子元素的所有[Xml *]屬性都在生成的代理代碼中,因此它們工作得很好。因此,所有的子元素都可以正常工作,但封裝元素並不是因爲[XmlRoot]屬性未包含在生成的代理代碼中。包含[XmlRoot]屬性的原始對象可以手動序列化。

我可以讓代理代碼包含[XmlRoot]屬性,以便生成的代理類也正確序列化嗎?如果我不能這樣做,我懷疑我將不得不使用[XmlType],但這會導致輕微的破壞,要求我更換其他組件,所以我更喜歡前者。我也想避免必須手動編輯自動生成的代理類。

下面是一些示例代碼(我在同一個應用程序中包含了客戶端和服務,因爲這樣做很快並且用於測試目的,在運行應用程序時註釋掉服務引用代碼並添加服務引用,然後取消註釋服務代碼並運行。)

namespace SerializationTest { 
    class Program { 
    static void Main(string[] args) { 

     Type serviceType = typeof(TestService); 
     using (ServiceHost host = new ServiceHost( 
      serviceType, 
      new Uri[] { 
       new Uri("http://localhost:8080/") 
      } 

     )) 
     { 

      ServiceMetadataBehavior behaviour = new ServiceMetadataBehavior(); 
      behaviour.HttpGetEnabled = true; 
      host.Description.Behaviors.Add(behaviour); 

      host.AddServiceEndpoint(serviceType, new BasicHttpBinding(), "TestService"); 
      host.AddServiceEndpoint(typeof(IMetadataExchange), new BasicHttpBinding(), "MEX"); 


      host.Open(); 

      TestServiceClient client = new TestServiceClient(); 
      localhost.TestObject to = client.GetObject(); 

      String XmlizedString = null; 
      using (MemoryStream memoryStream = new MemoryStream()) { 
       XmlSerializer xs = new XmlSerializer(typeof(localhost.TestObject)); 
       using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream)) { 
        xs.Serialize(xmlWriter, to); 
        memoryStream = (MemoryStream)xmlWriter.BaseStream; 
        XmlizedString = Encoding.UTF8.GetString(memoryStream.ToArray()); 
        Console.WriteLine(XmlizedString); 
       }  
      }  
     } 

     Console.ReadKey(); 
    } 
} 

[Serializable] 
[XmlRoot("SomethingElse")] 
public class TestObject { 

    private bool _worked; 

    public TestObject() { Worked = true; } 

    [XmlAttribute(AttributeName = "AttributeWorked")] 
    public bool Worked { 
     get { return _worked; } 
     set { _worked = value; } 
    } 
} 

[ServiceContract] 
public class TestService { 

    [OperationContract] 
    [XmlSerializerFormat] 
    public TestObject GetObject() { 
     return new TestObject(); 
    } 
    } 
} 

這是生成的Xml。

<?xml version="1.0" encoding="utf-8"?> 
<TestObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" AttributeWorked="true" /> 
+0

您是否控制用於生成代理的xsd模式? – hurst 2008-10-03 01:40:42

+0

我不驚訝沒有生成XmlRoot。我覺得奇怪的是,生成的類不叫「SomethingElse」。添加XmlRoot屬性後,您是否生成了代理? – csgero 2008-10-07 08:31:43

+0

我相信重點是避免修改架構/生成的代理。只需使用它們接收,然後轉向並再次發送到傳統方面。但是避免寫一套新的定義會很好 - 因此希望能夠即時重命名。我建議使用XmlAttributeOverrides。 – hurst 2008-10-09 00:58:28

回答

-1

我發現有人誰提供了一種方法來解決這種情況:

Matevz Gacnik's Weblog

使用的XmlAttributeOverrides這種方法,我寫了下面:

private static XmlSerializer GetOverridedSerializer() 
    { 
     // set overrides for TestObject element 
     XmlAttributes attrsTestObject = new XmlAttributes(); 
     XmlRootAttribute rootTestObject = new XmlRootAttribute("SomethingElse"); 
     attrsTestObject.XmlRoot = rootTestObject; 

     // create overrider 
     XmlAttributeOverrides xOver = new XmlAttributeOverrides(); 
     xOver.Add(typeof(localhost.TestObject), attrsTestObject); 

     XmlSerializer xSer = new XmlSerializer(typeof(localhost.TestObject), xOver); 
     return xSer; 
    } 

只要把這個方法在您的示例的Program類中,並替換Main()中的以下行:

 //XmlSerializer xs = new XmlSerializer(typeof(localhost.TestObject)); 
     XmlSerializer xs = GetOverridedSerializer(); 

然後運行以查看結果。

這裏是我的了:

<?xml version="1.0" encoding="utf-8"?><SomethingElse xmlns:xsi="http://www.w3.o 
rg/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Attribu 
teWorked="true" /> 
1

== == IF

這只是針對XmlRoot屬性。 XmlSerializer有一個構造函數,您可以在其中指定XmlRoot屬性。

對csgero的讚賞指向它。他的評論應該是解決方案。

XmlSerializer Constructor (Type, XmlRootAttribute) 

初始化 XmlSerializer類可以序列指定類型的 物體插入XML文檔 ,和反序列化XML文檔 成指定 類型的對象的新實例。它還指定使用 作爲XML根元素的類。

相關問題