WCF中反序列化复杂DTO具有空列表

本文关键字:列表 反序列化 复杂 DTO WCF | 更新日期: 2023-09-27 18:09:23

我们最近从Asp升级了我们的解决方案。Net 4.0到4.5.1,现在我们在反序列化一些复杂的dto时出现了错误。在所有情况下,DTO都有一个未初始化的List<T>属性,并且在尝试向集合添加对象时反序列化失败。我已经确保getter和setter像这样初始化属性:

[DataMember]
public List<objBusinessActivityGroup> BusinessActivities
{
   get { return m_groupList ?? ( m_groupList = new List<objBusinessActivityGroup>()); 
}
set {
      m_groupList = (value != null) ? new List<objBusinessActivityGroup>(value) : new List<objBusinessActivityGroup>();
}
}

,但这没有效果。我们还向每个父dto和子dto添加了[OnDeserializing]属性,以尝试初始化这些属性,但仍然没有帮助。我们检查了所有的类和接口,确保每个[ServiceContract]属性都有一个Namespace值,并且所有的dto都有相同Namespace设置的[DataContract]属性。我添加了一些代码,当[OnDeserializing]回调被调用时生成一个日志条目,并且可以看到回调被调用的位置,但是由于不能保证调用回调的时间,所以我不能说它们是否被及时调用,以便反序列化器将项添加到各自的集合中。

完整的环境是一个WinForms应用程序,它访问由自定义STS保护的WCF服务。就像我说的,在我们将web服务解决方案升级到4.5.1之前,一切都很好。WinForms应用程序仍然使用v4.0客户端配置文件,目前我们无法更改。

这是我们得到的异常:

System.ServiceModel。FaultException 1 was unhandled by user code HResult=-2146233087 Message=The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://sure.amc.faa.gov/ws:far. The InnerException message was 'The get-only collection of type 'System.Collections.Generic.List 1[[GlobalServices.Objects.]objFABusinessActivity, GlobalServices, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'返回空值。如果实例为空,则输入流包含不能添加的集合项。考虑在getter中初始化集合。详情请参见InnerException。源= mscorlibAction = http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher/fault

加:服务器堆栈跟踪:在System.ServiceModel.Channels.ServiceChannel。HandleReply(ProxyOperationRuntime操作,ProxyRpc&rpc)在System.ServiceModel.Channels.ServiceChannel。调用(String action, Boolean单向,ProxyOperationRuntime操作,Object[] in, Object[] outs, TimeSpan timeout)在System.ServiceModel.Channels.ServiceChannel。调用(字符串动作,布尔单向,ProxyOperationRuntime操作,对象[]输入,对象[]输出)在System.ServiceModel.Channels.ServiceChannelProxy。调用方法调用方法调用,ProxyOperationRuntime操作在System.ServiceModel.Channels.ServiceChannelProxy。调用(IMessage消息)[0]异常被重新抛出:在System.Runtime.Remoting.Proxies.RealProxy。HandleReturnMessage(IMessage reqMsg, IMessage retMsg)在System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (MessageData&msgData, Int32类型)在Services.WebServices.FundingAgreementService.IFundingAgreementRepository。SaveRevision(objFundingAgreementR far, Boolean issubmit, Int32 userid)在Services.WebServices.FundingAgreementService.FundingAgreementRepositoryClient。SaveRevision(objFundingAgreementR far, Boolean issubmit, Int32 userid)在c:'Projects'SURe_Client_1_5'Services'Service References'WebServices.FundingAgreementService'Reference.cs:line 4519在Services.Models.IAAModel。DoSaveRevision(对象发送者,DoWorkEventArgs e)在c:'Projects'SURe_Client_1_5'Services'Models' iamodel .cs:行1192在System.ComponentModel.BackgroundWorker。WorkerThreadStart(对象参数)InnerException:

这就是说,父DTO(远)有一个类型为List<objBusinessActivityGroup>的属性。每个objBusinessActivityGroup都有一个类型为List<objFABusinessActivity>的属性。当反序列化器向List<objFABusinessActivity>添加项时,它是空的。

我们是这样初始化集合的:

[DataMember]
public List<objFABusinessActivity> BAList
{
    get
    {
        if (_baList == null)
        {
            _baList = new List<objFABusinessActivity>();
         }
         return _baList;
    }
    set {
            _baList = (value != null) ? new List<objFABusinessActivity>(value) : new List<objFABusinessActivity>();
        }
    }

WCF中反序列化复杂DTO具有空列表<T>

您是否考虑过应用Data Contract Know类型?它允许您提前指定反序列化过程中应该考虑的类型。点击这里查看详情。

[KnownType(typeof(List<objFABusinessActivity>))]
[DataContract]
public class YourDtoClass
{
   [DataMember]
   public List<objFABusinessActivity> BAList
   {
     get
     {
        if (_baList == null)
        {
            _baList = new List<objFABusinessActivity>();
         }
         return _baList;
     }
     set 
     {
            _baList = (value != null) ? new List<objFABusinessActivity>(value) : new List<objFABusinessActivity>();
     }
   }
}