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>();
}
}
您是否考虑过应用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>();
}
}
}