WCF 尝试序列化未归因于 [DataMember] 的成员
WCF tries to serialize members that are not attributed with [DataMember]
给定以下数据合同:
[DataContract]
public class GetGameSessionHistory : ValueBaseCasinoIT
{
[DataMember]
public GameSession[] GameSessions => GameSessionsValue.ToArray<GameSession>();
public IEnumerable<GameSession> GameSessionsValue { get; set; }
}
由于 IEnumerable 接口,我仍然收到 GetGameSessionHistory 不可序列化的错误消息。
System.NotSupportedException: Cannot serialize member GetGameSessionHistory.GameSessionsValue of type System.Collections.Generic.IEnumerable`1[[GameSession, Common, Version=3.45.0.11, Culture=neutral, PublicKeyToken=null]] because it is an interface.
我还尝试了删除整个 [DataContract] 属性的方法,并专门忽略了带有 [IgnoreDataMember] 的受影响的成员。但不幸的是,这导致了同样的结果。
更新 1
给定代码中的 Lambda 表达式只是我计划执行的一个步骤。使用以下 DataContract 时问题仍然存在:
[DataContract]
public class GetGameSessionHistory : ValueBaseCasinoIT
{
[DataMember]
public GameSession[] GameSessions { get; set; }
public IEnumerable<GameSession> GameSessionsValue { get; set; }
}
删除 IEnumerable 时,消息消失。所以问题不可能出在GameSession类型上。
目前我正在使用 XmlSerializer。
数据用于以下服务:
IAdapterService:
[ServiceContract, XmlSerializerFormat(Style = OperationFormatStyle.Rpc, Use = OperationFormatUse.Encoded), DispatchByBodyBehavior]
public interface IAdapterService
{
[OperationContract(Name = "GetGameSessionHistoryRequest", Action = ""), DispatchBodyElement("GetGameSessionHistoryRequest", "...")]
GetGameSessionHistory GetGameSessionHistory(AuthenticationToken authenticationToken, string playerId, DateTime fromDate, DateTime toDate);
}
适配器服务:
[SoapDocumentService(SoapBindingUse.Literal, RoutingStyle = SoapServiceRoutingStyle.RequestElement)]
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
public class AdapterService : IAdapterService
{
public GetGameSessionHistory GetGameSessionHistory(AuthenticationToken authenticationToken, string playerId, DateTime fromDate, DateTime toDate)
{ ... }
}
Web.config:
<basicHttpBinding>
<binding name="SoapBinding">
<security mode="None"/>
<readerQuotas maxDepth="4000" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="32768"/>
</binding>
</basicHttpBinding>
<service name="...svc.AdapterService" behaviorConfiguration="svcBehavior" >
<endpoint binding="basicHttpBinding" bindingConfiguration="SoapBinding" contract="...IAdapterService" name="AdapterSoapBinding" behaviorConfiguration="withMessageInspector"/>
</service>
还有什么可能导致此问题?
如果我尝试你的代码,序列化工作正常;反序列化失败:
System.Runtime.Serialization.SerializationException: The get-only collection of type 'GameSession[]' returned a null value. The input stream contains collection items which cannot be added if the instance is null. Consider initializing the collection in the getter.
这是我所期望的,因为它无法为 GameSessions
赋值。如果我添加 set
... 一切正常。这是完整的工作代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
class Program
{
static void Main()
{
var ser = new DataContractSerializer(typeof(GetGameSessionHistory));
using (var ms = new MemoryStream())
{
var orig = new GetGameSessionHistory { GameSessionsValue =
new List<GameSession>() { new GameSession { } } };
ser.WriteObject(ms, orig);
ms.Position = 0;
var clone = (GetGameSessionHistory)ser.ReadObject(ms);
Console.WriteLine(clone?.GameSessionsValue.Count()); // prints 1
}
}
}
[DataContract]
public class GetGameSessionHistory : ValueBaseCasinoIT
{
[DataMember]
public GameSession[] GameSessions
{
get { return GameSessionsValue?.ToArray(); }
set { GameSessionsValue = value; }
}
//[DataMember] // original version; fails with The get-only collection of type
// 'GameSession[]' returned a null value.
//public GameSession[] GameSessions => GameSessionsValue?.ToArray<GameSession>();
public IEnumerable<GameSession> GameSessionsValue { get; set; }
}
[DataContract]
public class ValueBaseCasinoIT
{
}
[DataContract]
public class GameSession
{
}
我认为您可能需要添加更多信息来帮助我们确定问题,因为...它基本上有效。
发现问题:
我正在使用 XmlSerializer(IAdapterService 归因于 [XmlSerializerFormat]),它导致所有 public 属性被序列化。
DataContractSerializer (XmlObjectSerializer) 会考虑序列化过程的 [DataMember] 属性,而 XmlSerializer 会简单地忽略它们。
问题仍然存在,为什么 [XmlIgnore] 属性不能正常工作。
给定以下数据合同:
[DataContract]
public class GetGameSessionHistory : ValueBaseCasinoIT
{
[DataMember]
public GameSession[] GameSessions => GameSessionsValue.ToArray<GameSession>();
public IEnumerable<GameSession> GameSessionsValue { get; set; }
}
由于 IEnumerable 接口,我仍然收到 GetGameSessionHistory 不可序列化的错误消息。
System.NotSupportedException: Cannot serialize member GetGameSessionHistory.GameSessionsValue of type System.Collections.Generic.IEnumerable`1[[GameSession, Common, Version=3.45.0.11, Culture=neutral, PublicKeyToken=null]] because it is an interface.
我还尝试了删除整个 [DataContract] 属性的方法,并专门忽略了带有 [IgnoreDataMember] 的受影响的成员。但不幸的是,这导致了同样的结果。
更新 1
给定代码中的 Lambda 表达式只是我计划执行的一个步骤。使用以下 DataContract 时问题仍然存在:
[DataContract]
public class GetGameSessionHistory : ValueBaseCasinoIT
{
[DataMember]
public GameSession[] GameSessions { get; set; }
public IEnumerable<GameSession> GameSessionsValue { get; set; }
}
删除 IEnumerable 时,消息消失。所以问题不可能出在GameSession类型上。
目前我正在使用 XmlSerializer。
数据用于以下服务:
IAdapterService:
[ServiceContract, XmlSerializerFormat(Style = OperationFormatStyle.Rpc, Use = OperationFormatUse.Encoded), DispatchByBodyBehavior]
public interface IAdapterService
{
[OperationContract(Name = "GetGameSessionHistoryRequest", Action = ""), DispatchBodyElement("GetGameSessionHistoryRequest", "...")]
GetGameSessionHistory GetGameSessionHistory(AuthenticationToken authenticationToken, string playerId, DateTime fromDate, DateTime toDate);
}
适配器服务:
[SoapDocumentService(SoapBindingUse.Literal, RoutingStyle = SoapServiceRoutingStyle.RequestElement)]
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
public class AdapterService : IAdapterService
{
public GetGameSessionHistory GetGameSessionHistory(AuthenticationToken authenticationToken, string playerId, DateTime fromDate, DateTime toDate)
{ ... }
}
Web.config:
<basicHttpBinding>
<binding name="SoapBinding">
<security mode="None"/>
<readerQuotas maxDepth="4000" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="32768"/>
</binding>
</basicHttpBinding>
<service name="...svc.AdapterService" behaviorConfiguration="svcBehavior" >
<endpoint binding="basicHttpBinding" bindingConfiguration="SoapBinding" contract="...IAdapterService" name="AdapterSoapBinding" behaviorConfiguration="withMessageInspector"/>
</service>
还有什么可能导致此问题?
如果我尝试你的代码,序列化工作正常;反序列化失败:
System.Runtime.Serialization.SerializationException: The get-only collection of type 'GameSession[]' returned a null value. The input stream contains collection items which cannot be added if the instance is null. Consider initializing the collection in the getter.
这是我所期望的,因为它无法为 GameSessions
赋值。如果我添加 set
... 一切正常。这是完整的工作代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
class Program
{
static void Main()
{
var ser = new DataContractSerializer(typeof(GetGameSessionHistory));
using (var ms = new MemoryStream())
{
var orig = new GetGameSessionHistory { GameSessionsValue =
new List<GameSession>() { new GameSession { } } };
ser.WriteObject(ms, orig);
ms.Position = 0;
var clone = (GetGameSessionHistory)ser.ReadObject(ms);
Console.WriteLine(clone?.GameSessionsValue.Count()); // prints 1
}
}
}
[DataContract]
public class GetGameSessionHistory : ValueBaseCasinoIT
{
[DataMember]
public GameSession[] GameSessions
{
get { return GameSessionsValue?.ToArray(); }
set { GameSessionsValue = value; }
}
//[DataMember] // original version; fails with The get-only collection of type
// 'GameSession[]' returned a null value.
//public GameSession[] GameSessions => GameSessionsValue?.ToArray<GameSession>();
public IEnumerable<GameSession> GameSessionsValue { get; set; }
}
[DataContract]
public class ValueBaseCasinoIT
{
}
[DataContract]
public class GameSession
{
}
我认为您可能需要添加更多信息来帮助我们确定问题,因为...它基本上有效。
发现问题: 我正在使用 XmlSerializer(IAdapterService 归因于 [XmlSerializerFormat]),它导致所有 public 属性被序列化。
DataContractSerializer (XmlObjectSerializer) 会考虑序列化过程的 [DataMember] 属性,而 XmlSerializer 会简单地忽略它们。
问题仍然存在,为什么 [XmlIgnore] 属性不能正常工作。