我有一個WSDL,我的web服務的消費者期望會嚴格遵守。我將它轉換爲wsdl.exe的接口,並讓我的web服務實現它。除了這個問題,我對結果普遍滿意。如何使用從wsdl自動生成的類重寫C#DateTime序列化?
一個簡單GetCurrentTime方法將具有在接口定義中的WSDL生成以下響應類:
[System.CodeDobmCompiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="[Client Namespace]")]
public partial class GetCurrentTimeResponse {
private System.DateTime timeStampField;
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified]
public System.DateTime TimeStamp{
// [accesses timeStampField]
}
}
當我把響應數據到自動生成的響應的類,它被序列化爲適當的XML響應。 (大多數的Web方法具有更爲複雜的返回類型的數組的多層次。)
的問題是,datetime對象的缺省序列違反WSDL中的要求之一:
...
<xsd:simpleType name="SearchTimeStamp">
<xsd:restriction base="xsd:dateTime">
<xsd:pattern value="[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{1,7})?Z">
</xsd:restriction>
</xsd:simpleType>
...
注該模式的最後一部分,如果包含它們,亞秒必須是1或7個字符。客戶似乎拒絕迴應,因爲它不符合該要求。
主要問題是,當.NET序列化一個DateTime對象時,它會忽略所有尾隨零,這意味着結果的亞秒值會有所不同。 (例如,默認情況下,「12:34:56.700」被序列化爲「<TimeStamp>
12:34:56:7 </TimeStamp>
」)。我們使用毫秒精度,所以我需要所有時間戳以7亞秒數格式化,以便與WSDL兼容。
這很容易,如果我可以指定格式字符串,但我不知道如何控制DateTime對象用來序列化爲XML的字符串,或者重寫序列化行爲。我該怎麼做呢?請記住以下幾點...
- 我想盡可能少地修改生成的代碼......如果可以通過部分類或繼承類進行更改,最好不要這樣做。
- 對Web方法的返回類型使用繼承類將導致Web服務不再實現自動生成的接口。
- TimeStamp類型出現在其他更復雜的響應類型中。因此,手動覆蓋整個序列化過程可能會非常耗時。
更新: 我試圖儘早實現IXmlSerializable的,約翰建議,並得到了以下錯誤: System.InvalidOperationException: There was an error reflecting type '[...].GetCurrentTimeResponse'. ---> System.InvalidOperationException: Only XmlRoot attribute may be specified for the type [...].GetCurrentTimeResponse. Please use XmlSchemaProviderAttribute to specify schema type.
在那之後,我想,我會砍了生成的代碼太多我喜歡並不斷尋找其他解決方案。
你不應該,在一般情況,得到那個例外。你可以顯示你的'IXmlSerializable'實現嗎? – 2010-04-21 00:50:55