我们最近将我们的解决方案从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都具有[DataContract]
属性并具有相同的Namespace
设置。我添加了一些在[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]]'返回空值。输入流包含集合项,如果实例为null,则无法添加这些集合项。考虑在getter中初始化集合。'有关更多详细信息,请参阅InnerException。 来源= mscorlib程序 行动= http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher/fault堆栈跟踪: 服务器堆栈跟踪: 在System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime操作,ProxyRpc&amp; rpc) 在System.ServiceModel.Channels.ServiceChannel.Call(String action,Boolean oneway,ProxyOperationRuntime operation,Object [] ins,Object [] outs,TimeSpan timeout) 在System.ServiceModel.Channels.ServiceChannel.Call(String action,Boolean oneway,ProxyOperationRuntime operation,Object [] ins,Object [] outs) 在System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime操作) 在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage消息) 在[0]处重新抛出异常: 在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg) 在System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData,Int32 type) 在Services.WebServices.FundingAgreementService.IFundingAgreementRepository.SaveRevision(objFundingAgreementR far,Boolean issubmit,Int32 userid) at Services.WebServices.FundingAgreementService.FundingAgreementRepositoryClient.SaveRevision(objFundingAgreementR far,Boolean issubmit,Int32 userid)in c:\ Projects \ SURe_Client_1_5 \ Services \ Service References \ WebServices.FundingAgreementService \ Reference.cs:line 4519 at Services.Models.IAAModel.DoSaveRevision(Object sender,DoWorkEventArgs e)位于c:\ Projects \ SURe_Client_1_5 \ Services \ Models \ IAAModel.cs:第1192行 在System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object参数) 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>();
}
}
答案 0 :(得分:0)
您是否考虑过应用Data Contract Know类型?它允许您事先指定在反序列化期间应包括的类型以供考虑。查看更多详情here。
[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>();
}
}
}