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

.NET Core C# SOAP客户端请求体非字符串字段丢失问题排查

.NET Core SOAP客户端非字符串字段请求体丢失问题

问题场景

在.NET Core环境下使用C#开发SOAP客户端,核心代码如下:

string endpointURL = "xxxx";
var remoteAddress = new ServiceReference.Endpoint(endpointURL);
var bind = new System.ServiceModel.BasicHTTPSBinding();
ServiceReference.ServiceReferenceClient client= new ServiceReference.ServiceReferenceClient(bind, remoteAddress);
AddData request = new AddData();
request.authentication = authentication;
request.transaction_id = transaction_id;
request.subjects = Subjects; 
request.students = Students; 
addDataResponse = await client.addData(request);

自动生成的Reference.cs中实体类定义:

public class students
{
    public string name{get;set;}
    public string @class{get;set;} // class为C#关键字,需加@转义
    public bool IsGraduate{get;set;}
    public int Marks{get;set;} 
}
public class subjects
{
    public string name{get;set;}
    public string description{get;set;}
    public bool IsRequired{get;set;}
    public int Count{get;set;} 
    public int Test{get;set;} 
}

构造请求时,Subjects和Students已从数据库获取完整数据,调试可见请求对象包含所有字段值,但发送的SOAP请求体仅保留字符串类型字段,bool、int等非字符串字段缺失:

期望的请求体XML:

<?xml version="1.0" encoding="UTF-8"?>
<student>
 <name>Tom Hnaks</name>
 <class>High</class>
 <IsGraduate>No</IsGraduate>
 <Marks>100</Marks>
</student>
<subjects>
 <name>Botany</name>
 <description>High</description>
 <IsRequired>No</IsRequired>
 <Test>100</Test>
 <Count>100</Count>
</subjects>

实际的请求体XML:

<?xml version="1.0" encoding="UTF-8"?>
<student>
 <name>Tom Hnaks</name>
 <class>High</class>
</student>
<subjects>
 <name>Botany</name>
 <description>High</description>
</subjects>

原因分析

  • 默认序列化规则:.NET Core下的WCF客户端默认使用DataContractSerializer,对于bool、int等值类型,若字段值为类型默认值(如bool的false、int的0),序列化器会自动忽略这些字段,不写入XML请求体。
  • 实体类特性缺失:自动生成的实体类未标记[DataMember(EmitDefaultValue = true)]特性,无法强制序列化默认值字段。

解决方案

方案1:修改实体类序列化特性

在自动生成的Reference.cs中,为每个非字符串字段添加[DataMember(EmitDefaultValue = true)]特性,同时确保类标记[DataContract]:

[DataContract]
public class students
{
    [DataMember]
    public string name{get;set;}
    [DataMember]
    public string @class{get;set;}
    [DataMember(EmitDefaultValue = true)]
    public bool IsGraduate{get;set;}
    [DataMember(EmitDefaultValue = true)]
    public int Marks{get;set;} 
}

[DataContract]
public class subjects
{
    [DataMember]
    public string name{get;set;}
    [DataMember]
    public string description{get;set;}
    [DataMember(EmitDefaultValue = true)]
    public bool IsRequired{get;set;}
    [DataMember(EmitDefaultValue = true)]
    public int Count{get;set;} 
    [DataMember(EmitDefaultValue = true)]
    public int Test{get;set;} 
}

注意:若通过Add Service Reference更新服务引用,修改会被覆盖,需重新添加特性或用方案2配置。

方案2:更新服务引用时配置序列化选项

添加/更新服务引用时,点击高级按钮,在弹出的对话框中勾选「总是生成消息契约」,或配置EmitDefaultValue为true,让自动生成的代码自带强制序列化特性。

方案3:检查字段实际值

确认非字符串字段的实际值是否为类型默认值(比如Marks是否为0、IsGraduate是否为false),若业务上需要传递默认值,必须通过EmitDefaultValue = true强制序列化。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:57:32