You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#调用Oracle SOA Soap服务时空值处理及反序列化异常排查

C#调用Oracle SOAP服务反序列化异常排查与解决

调用代码

CallCenterServiceReference.CallCenterService_pttClient client = new CallCenterServiceReference.CallCenterService_pttClient();
client.ClientCredentials.UserName.UserName = "";
client.ClientCredentials.UserName.Password = "";
CallCenterServiceReference.isPowerCutForNotPay obj = new CallCenterServiceReference.isPowerCutForNotPay();
CallCenterServiceReference.authStruct auth = new CallCenterServiceReference.authStruct();

obj.agreeNo = serviceIdTextBox.Text;
obj.DEVID = null;
obj.FRF = null;
auth.systemID = 123;
auth.authKey = "";
auth.systemIDSpecified = true;
obj.auth = auth;

var response = client.isPowerCutForNotPay(obj).isPowerCutForNotPayResult;
MessageBox.Show("ResultCode is :-"+response.resultCode);

异常触发于 var response = client.isPowerCutForNotPay(obj).isPowerCutForNotPayResult; 行。

SOAP请求报文

<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <isPowerCutForNotPay
            xmlns="http://www.J.com/SampleApplication/CallCenterSystem">
            <agreeNo>3456</agreeNo>
            <DEVID xsi:nil="true"/>
            <FRF xsi:nil="true"/>
            <auth>
                <authKey>1234565</authKey>
                <systemID>2005</systemID>
            </auth>
        </isPowerCutForNotPay>
    </s:Body>
</s:Envelope>

SOAP响应报文

<env:Envelope
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <env:Header>
        <wsa:Action>isPowerCutForNotPay</wsa:Action>
        <wsa:MessageID>urn:1d0f3f85-8963-11ee-a4bb-5254003edad5</wsa:MessageID>
        <wsa:ReplyTo>
            <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
            <wsa:ReferenceParameters>
                <instra:tracking.ecid
                    xmlns:instra="http://xmlns.oracle.com/sca/tracking/1.0">f99958a9-fe21-4f48-871e-eef4aadfc448-007192ac
                </instra:tracking.ecid>
                <instra:tracking.FlowEventId
                    xmlns:instra="http://xmlns.oracle.com/sca/tracking/1.0">70056562
                </instra:tracking.FlowEventId>
                <instra:tracking.FlowId
                    xmlns:instra="http://xmlns.oracle.com/sca/tracking/1.0">122084
                </instra:tracking.FlowId>
                <instra:tracking.CorrelationFlowId
                    xmlns:instra="http://xmlns.oracle.com/sca/tracking/1.0">0000OjsFbzE6iKG6yzvX6G1_8zCF0000ax
                </instra:tracking.CorrelationFlowId>
                <instra:tracking.quiescing.SCAEntityId
                    xmlns:instra="http://xmlns.oracle.com/sca/tracking/1.0">70096
                </instra:tracking.quiescing.SCAEntityId>
            </wsa:ReferenceParameters>
        </wsa:ReplyTo>
        <wsa:FaultTo>
            <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
        </wsa:FaultTo>
    </env:Header>
    <env:Body>
        <isPowerCutForNotPayResponse
            xmlns:ns1="http://xmlns.oracle.com/CallCenter/JDECOCallCenter/JDECOCallCenterService"
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
            xmlns:wsp="http://www.w3.org/ns/ws-policy"
            xmlns:wssutil="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
            xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
            xmlns:ouaf="http://ouaf.oracle.com/"
            xmlns:tns="http://www.J.com/SampleApplication/CallCenterSystem"
            xmlns="http://www.J.com/SampleApplication/CallCenterSystem">
            <tns:isPowerCutForNotPayResult>
                <tns:resultCode>-1</tns:resultCode>
                <tns:resultStringA/>
                <tns:resultStringE>Invalid Account ID</tns:resultStringE>
                <tns:resultStringH/>
                <tns:customMessageA/>
                <tns:customMessageE/>
                <tns:customMessageH/>
                <tns:trans>
                    <tns:DEVID/>
                    <tns:FRF/>
                    <tns:JRF>1373</tns:JRF>
                    <tns:systemID>2005</tns:systemID>
                </tns:trans>
                <tns:value/>
            </tns:isPowerCutForNotPayResult>
        </isPowerCutForNotPayResponse>
    </env:Body>
</env:Envelope>

异常信息

See the end of this message for details on invoking just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text ************** System.ServiceModel.CommunicationException: Error in deserializing body of reply message for operation 'isPowerCutForNotPay'. ---> System.InvalidOperationException: There is an error in XML document (1, 2104). ---> System.FormatException: The string '' is not a valid Boolean value. at System.Xml.XmlConvert.ToBoolean(String s) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderJDECOCallCenterService_ptt.Read5_Utils_ResultClassOfboolean(Boolean isNullable, Boolean checkType) at


问题分析

异常核心是空字符串无法转换为布尔值:从响应报文可见,<tns:value/>是空节点,但服务引用自动生成的实体类中,value字段被定义为非可空的bool类型。反序列化时,空节点被解析为空字符串,无法匹配布尔值的有效取值(仅true/false),因此抛出格式异常。

解决方案

方案1:修改服务引用生成规则

重新添加服务引用时,进入高级设置,勾选「允许生成可空值类型」。生成的实体类中value字段会变为bool?(可空布尔类型),空节点会被解析为null,避免转换错误。

方案2:手动修改生成的实体类

找到自动生成的结果实体类(如Utils_ResultClassOfboolean),将value字段的类型从bool改为bool?,确保序列化配置支持空值解析。

方案3:拦截SOAP响应修正XML

实现IClientMessageInspector接口,在反序列化前拦截响应报文,将空的<tns:value/>节点替换为<tns:value xsi:nil="true"/>(标记为空值)或<tns:value>false</tns:value>(赋予默认布尔值)。

示例拦截代码片段:

public class SoapResponseInterceptor : IClientMessageInspector
{
    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        var buffer = reply.CreateBufferedCopy(int.MaxValue);
        var msg = buffer.CreateMessage();
        var reader = msg.GetReaderAtBodyContents();
        var xml = reader.ReadOuterXml();
        
        // 替换空value节点为带nil标记的节点
        xml = xml.Replace("<tns:value/>", "<tns:value xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>");
        
        var newMsg = Message.CreateMessage(reply.Version, null, XmlReader.Create(new StringReader(xml)));
        newMsg.Headers.CopyHeadersFrom(reply.Headers);
        newMsg.Properties.CopyProperties(reply.Properties);
        reply = newMsg;
        buffer.Close();
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        return null;
    }
}

之后通过行为扩展将拦截器绑定到客户端端点即可生效。


内容的提问来源于stack exchange,提问作者M Muneer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 20:50:56