2010-04-23 51 views
1

時,請求中只有根對象被反序列化我試圖創建一個接受任何輸入(Action =「*」)的wcf服務,然後在確定其類型後反序列化消息。爲了測試反序列化的目的,我目前對測試服務的類型進行了硬編碼。當使用Message.GetBody <>

我從反序列化過程中得不到任何錯誤,但是在反序列化發生後只有外部對象被填充。所有內部字段都是空的。我可以成功處理與原始wcf服務相同的請求。

我反序列化這種方式,其中knownTypes預計類型的類型列表:

DataContractSerializer ser = new DataContractSerializer(new createEligibilityRuleSet().GetType(), knownTypes); 
createEligibilityRuleSet newReq = buf.CreateMessage().GetBody<createEligibilityRuleSet>(ser); 

這裏是類和子類的請求對象。這些類由svcutil使用現有wsdl中的自頂向下方法生成。我試圖用DataContracts替換XmlTypeAttributes,用DataMembers替換XmlElements沒有區別。它是createEligibilityRuleSet對象上的CreateEligibilityRuleSetSvcRequest實例,該對象爲null。我在底部包含了請求中檢索到的請求

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://RulesEngineServicesLibrary/RulesEngineServices")] 
public partial class createEligibilityRuleSet 
{ 

private CreateEligibilityRuleSetSvcRequest requestField; 

/// <remarks/> 
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = true, Order = 0)] 
public CreateEligibilityRuleSetSvcRequest request 
{ 
    get 
    { 
return this.requestField; 
    } 
    set 
    { 
this.requestField = value; 
    } 
} 
} 

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://RulesEngineServicesLibrary")] 
public partial class CreateEligibilityRuleSetSvcRequest : RulesEngineServicesSvcRequest 
{ 

private string requestField; 

/// <remarks/> 
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 

public string request 
{ 
    get 
    { 
return this.requestField; 
    } 
    set 
    { 
this.requestField = value; 
    } 
} 
} 

[System.Xml.Serialization.XmlIncludeAttribute(typeof(CreateEligibilityRuleSetSvcRequest))] 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(ApplyMemberEligibilitySvcRequest))] 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CreateCompletionCriteriaRuleSetSvcRequest))] 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CopyRuleSetSvcRequest))] 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DeleteRuleSetByIDSvcRequest))] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://RulesEngineServicesLibrary")] 
public partial class RulesEngineServicesSvcRequest : ServiceRequest 
{ 
} 

/// <remarks/> 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(RulesEngineServicesSvcRequest))] 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CreateEligibilityRuleSetSvcRequest))] 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(ApplyMemberEligibilitySvcRequest))] 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CreateCompletionCriteriaRuleSetSvcRequest))] 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CopyRuleSetSvcRequest))] 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DeleteRuleSetByIDSvcRequest))] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://FELibrary")] 
public partial class ServiceRequest 
{ 

private string applicationIdField; 

/// <remarks/> 
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 

public string applicationId 
{ 
    get 
    { 
return this.applicationIdField; 
    } 
    set 
    { 
this.applicationIdField = value; 
    } 
} 
} 

來自客戶端的請求出現在消息正文中,如下所示。在運行時從消息中檢索。

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:rul="http://RulesEngineServicesLibrary/RulesEngineServices"> 
<soap:Header/> 
    <soap:Body> 
     <rul:createEligibilityRuleSet> 
     <request> 
      <applicationId>test</applicationId> 
      <request>Perf Rule Set1</request> 
     </request> 
     </rul:createEligibilityRuleSet> 
    </soap:Body> 
</soap:Envelope> 

回答

2

你看到的具體問題是DataContract不知道如何處理不合格的元素。但是XmlSerializer會這樣做,並且您的類可以正確歸因於XmlSerializer。

所以,你應該使用XmlSerializer的,而不是DataContractSerializer的反序列化正文內容:

public static T GetBodyWithXmlSerializer<T>(this Message msg) 
{ 
    var ser = new XmlSerializer(typeof(T)); 
    T o; 
    using (var reader = msg.GetReaderAtBodyContents()) 
    { 
     o = (T)ser.Deserialize(reader); 
    } 
    return o; 
} 
+0

中的代碼片段: DataContractSerializer的SER =新的DataContractSerializer(新createEligibilityRuleSet().GetType(),knownTypes); createEligibilityRuleSet newReq = buf.CreateMessage()。GetBody (ser); 此請求中的'buf'是從wcf傳遞的System.ServiceModel.Channels.Message對象創建的MessageBuffer。 1.我在使用的Message類中看不到方法「ReadFromBodyContentsToEnd」。我應該使用別的東西嗎? 2.如果我排除了上述調用方法的行,則會出現錯誤,指出'XML文檔中存在錯誤'。 – user324627 2010-04-27 18:23:11

+0

對不起,我修復了代碼。爲了得到它的工作,另外你需要添加以下屬性到你的createEligibilityRuleSet類中: [System.Xml.Serialization.XmlRootAttribute(Namespace =「http:// RulesEngineServicesLibrary/RulesEngineServices」)] – alexdej 2010-04-27 23:16:03

+0

非常感謝!我已經想出了測試中的XmlRootAttribute要求,並且讓你知道,但你也知道了。再次感謝。我唯一的問題是爲什麼我不得不爲這個反序列化添加XmlRoot屬性,但是這些對象被系統正確地反序列化,而沒有通過我的「正常」服務對它進行反序列化? – user324627 2010-04-28 17:05:50

相關問題