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

迁移至SOSS为DTO添加[Serializable()]后反序列化异常求助

问题背景

项目从inproc会话迁移至SOSS(State Server Service),给多数模型/DTO添加[Serializable]特性后序列化正常,但其中一个YourDTO出现反序列化错误:

System.Exception: An service exception has occured the exception was System.ServiceModel.Dispatcher.NetDispatcherFaultException: The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:GetAllAttachmentsResult. The InnerException message was 'Error in line 1 position 686. 'EndElement' 'YourDTO' from namespace 'http://schemas.datacontract.org/2004/07/Business.Objects.Message' is not expected. Expecting element '_x003C_AttachmentDate_x003E_k__BackingField'.'. Please see InnerException for more details. ---> System.Runtime.Serialization.SerializationException: Error in line 1 position 686. 'EndElement' 'YourDTO' from namespace 'http://schemas.datacontract.org/2004/07/Business.Objects.Message' is not expected. Expecting element '_x003C_AttachmentDate_x003E_k__BackingField'.

对应的DTO代码(通过NuGet包引入):

namespace Business.Objects.Message
{
    [Serializable()]
    public class YourDTO
    {
       public long Id { get; set; }
       public FileType Type{ get; set; }
       public string Name { get; set; }
       public DateTime AttachmentDate { get; set; }
       public string UserName { get; set; }

       public YourDTO()
       {
           Id = 0;
           Name = string.Empty;
           Type = FileType.Unknown;
           AttachmentDate = DateTime.MinValue;
           UserName = string.Empty;
       }
    }
}

已知信息:

  • 已尝试给DTO添加[DataContract]特性但无效
  • 仅修改了web.config中的SessionState为SOSS,并给DTO添加[Serializable]特性后出现问题
解决思路

1. 统一序列化器,解决BinaryFormatter与DataContractSerializer冲突

错误里的_x003C_AttachmentDate_x003E_k__BackingField是BinaryFormatter序列化自动属性时生成的编译器字段名,而WCF默认用DataContractSerializer,两者格式不匹配导致反序列化失败。

方案:修改WCF绑定为Binary编码

在web.config的WCF绑定配置中添加binaryEncoding,强制使用BinaryFormatter:

<bindings>
  <basicHttpBinding>
    <binding name="YourServiceBinding">
      <security mode="None"/>
      <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"/>
      <binaryEncoding/>
    </binding>
  </basicHttpBinding>
</bindings>

确保服务端点使用这个绑定配置。

2. 替换自动属性为显式字段,消除编译器生成的backing field问题

自动属性的backing field是编译器自动生成的,跨程序集(比如NuGet包)时可能出现序列化行为不一致。修改DTO为显式字段:

namespace Business.Objects.Message
{
    [Serializable()]
    public class YourDTO
    {
       private long _id;
       private FileType _type;
       private string _name;
       private DateTime _attachmentDate;
       private string _userName;

       public long Id { get { return _id; } set { _id = value; } }
       public FileType Type{ get { return _type; } set { _type = value; } }
       public string Name { get { return _name; } set { _name = value; } }
       public DateTime AttachmentDate { get { return _attachmentDate; } set { _attachmentDate = value; } }
       public string UserName { get { return _userName; } set { _userName = value; } }

       public YourDTO()
       {
           _id = 0;
           _name = string.Empty;
           _type = FileType.Unknown;
           _attachmentDate = DateTime.MinValue;
           _userName = string.Empty;
       }
    }
}

注意:需要更新NuGet包的代码后重新发布,再重新引用。

3. 检查SOSS的Session序列化配置

确认SOSS使用的序列化方式和WCF一致,在web.config的SessionState节点添加serialization mode="Binary":

<sessionState mode="Custom" customProvider="SOSSProvider">
  <providers>
    <add name="SOSSProvider" type="SOSS.Web.SessionState.SossSessionStateProvider, SOSS.Web"/>
  </providers>
  <serialization mode="Binary"/>
</sessionState>

4. 清理NuGet缓存,确保[Serializable]特性生效

旧的NuGet包缓存可能保留了未添加[Serializable]的DTO版本,导致运行时不生效:

  • 执行命令清理缓存:.NET Framework用nuget locals all -clear,.NET Core/.NET 5+用dotnet nuget locals all --clear
  • 删除解决方案中的NuGet引用,重新安装最新版本

5. 显式标记[DataContract]和[DataMember],对齐序列化字段名

如果必须用DataContractSerializer,给每个属性指定和backing field一致的名称:

namespace Business.Objects.Message
{
    [Serializable]
    [DataContract(Name = "YourDTO", Namespace = "http://schemas.datacontract.org/2004/07/Business.Objects.Message")]
    public class YourDTO
    {
       [DataMember(Name = "_x003C_Id_x003E_k__BackingField")]
       public long Id { get; set; }
       [DataMember(Name = "_x003C_Type_x003E_k__BackingField")]
       public FileType Type{ get; set; }
       [DataMember(Name = "_x003C_Name_x003E_k__BackingField")]
       public string Name { get; set; }
       [DataMember(Name = "_x003C_AttachmentDate_x003E_k__BackingField")]
       public DateTime AttachmentDate { get; set; }
       [DataMember(Name = "_x003C_UserName_x003E_k__BackingField")]
       public string UserName { get; set; }

       public YourDTO()
       {
           Id = 0;
           Name = string.Empty;
           Type = FileType.Unknown;
           AttachmentDate = DateTime.MinValue;
           UserName = string.Empty;
       }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:04:56