【问题标题】:Only root object on request is deserialized when using Message.GetBody<>使用 Message.GetBody<> 时,仅对请求的根对象进行反序列化
【发布时间】:2023-04-01 12:15:01
【问题描述】:

我正在尝试创建一个接受任何输入 (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 实例。我已经在底部包含了从请求中检索到的请求

/// <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;
    }
}
}

来自客户端的请求来自消息正文,如下所示。在运行时从 Message 中检索。

<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>

【问题讨论】:

    标签: c# wcf serialization


    【解决方案1】:

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

    【讨论】:

    • 在sn-p代码中:DataContractSerializer ser = new DataContractSerializer(new createEligibilityRuleSet ().GetType(), knownTypes); createEligibilityRuleSet newReq = buf.CreateMessage().GetBody(ser);此请求中的“buf”是从 wcf 传递的 System.ServiceModel.Channels.Message 对象创建的 MessageBuffer。 1. 我在使用的 Message 类上没有看到方法“ReadFromBodyContentsToEnd”。我应该使用别的东西吗? 2. 如果我排除调用上述方法的行,我会收到一条错误消息,指出“XML 文档中存在错误”。
    • 抱歉,我修复了代码。要使其正常工作,您还需要在 createEligibilityRuleSet 类中添加以下属性: [System.Xml.Serialization.XmlRootAttribute(Namespace = "RulesEngineServicesLibrary/RulesEngineServices")]
    • 非常感谢!我已经在测试中弄清楚了 XmlRootAttribute 要求并来告诉你,但你也明白了。再次感谢。我剩下的唯一问题是为什么我必须添加 XmlRoot 属性才能使这个反序列化工作,但是这些对象在没有我的“正常”服务的情况下被系统正确反序列化了?
    • 在执行 new XmlSerializer(Type) 时使用 XmlRootAttribute 来指定根元素的名称/命名空间。 WCF 以不同的方式指定此值(使用 XmlSerializer.FromMappings)。
    • 你能举例说明 XmlSerializer.FromMappings 是如何工作的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    相关资源
    最近更新 更多