c# - 使用 Message.GetBody<> 时,仅根据请求反序列化根对象

标签 c# wcf serialization

我正在尝试创建一个接受任何输入 (Action="*") 的 wcf 服务,然后在确定其类型后反序列化消息。为了测试反序列化的目的,我目前正在对测试服务的类型进行硬编码。

我从反序列化过程中没有收到任何错误,但在反序列化发生后仅填充外部对象。所有内部字段均为空。我可以成功处理针对原始 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>

最佳答案

您看到的具体问题是 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;
}

关于c# - 使用 Message.GetBody<> 时,仅根据请求反序列化根对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2702179/

相关文章:

c#:编写 v1 的更短方式! ? v2 : !v2

wcf - IIS 托管 WCF 服务不回收 TCP 端口 "Insufficient winsock resources"

ios - 单点触控 : How to serialize a type (like CLLocation) not marked as Serializable?

php - 您不能在 laravel 中序列化或反序列化 PDO 实例

c# - 如何模拟/单元测试 HTTP 客户端 - restease

c# - 我应该在继承链中包含所有接口(interface)吗?

c# - 如何使用 WCF NetHttpBinding (WebSockets) 通过服务器向所有客户端广播(推送)一个客户端发送的消息?

wcf - WCF 流式处理问题

linq - 将 LINQ 对象序列化为 JSON 字符串 - 巨大的字符串

c# - 如何覆盖 DataContext.SubmitChanges()?