将单个枚举值传递给 WCF 服务时,protobuf-net 引发有关无效线路类型的异常

Posted

技术标签:

【中文标题】将单个枚举值传递给 WCF 服务时,protobuf-net 引发有关无效线路类型的异常【英文标题】:protobuf-net throws exception about invalid wire-type, when passing single enum values to WCF service 【发布时间】:2013-02-28 21:46:39 【问题描述】:

在我的 wcf 服务上调用以下方法……

ObservableCollection<PatientViewModel> Search(List<string> searchTerms, SearchNature nature, SearchMode mode, List<SearchField> fields)

导致以下异常...

ProtoBuf.ProtoException, protobuf-net, Version=2.0.0.627, Culture=neutral, PublicKeyToken=75e2634e27c46854

Invalid wire-type; this usually means you have over-written a file without truncating or setting the length; see http://***.com/q/2152978/23354

ProtoBuf.ProtoReader.ReadInt32()
proto_4(Object , ProtoReader )
ProtoBuf.ServiceModel.XmlProtoSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)
System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.PartInfo.ReadObject(XmlDictionaryReader reader, XmlObjectSerializer serializer)
System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)
System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, Object[] parameters, Boolean isRequest)
System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)
System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)
System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

注意: 如果我删除第二个和第三个参数。所以方法是……

ObservableCollection<PatientViewModel> Search(List<string> searchTerms, List<SearchField> fields)

这很好用。

参数字段是一个枚举列表,反序列化没有问题。

为什么单个枚举值会导致上述异常?

提前致谢。

供您参考...

[DataContract]
public enum SearchNature

    [EnumMember] None,
    [EnumMember] Letters,
    [EnumMember] Numbers


[DataContract]
public enum SearchMode

    [EnumMember] None,
    [EnumMember] BeginsWith,
    [EnumMember] Contains


[DataContract]
public enum SearchField

    [EnumMember] None,
    [EnumMember] FirstName,
    [EnumMember] LastName,
    [EnumMember] PatientId,
    [EnumMember] PriorId,
    [EnumMember] PhoneNumber,
    [EnumMember] DateOfBirth

编辑:

此外,如果我将 ProtoOperationBehavior 更改为在类型为枚举而不是 XmlProtoSerializer 时使用默认序列化程序,则服务调用工作正常。

public override XmlObjectSerializer CreateSerializer(Type type, System.Xml.XmlDictionaryString name, System.Xml.XmlDictionaryString ns, IList<Type> knownTypes)

    if (type.IsEnum) return base.CreateSerializer(type, name, ns, knownTypes);
    if (model == null) throw new InvalidOperationException("No Model instance has been assigned to the ProtoOperationBehavior");
    return XmlProtoSerializer.TryCreate(model, type) ?? base.CreateSerializer(type, name, ns, knownTypes);

【问题讨论】:

此外,如果我将第二个和第三个参数转换为整数......它工作正常。我只是在调用方法时转换为 int,一旦在 wcf 服务的方法内部,我分别转换为 enum。 尝试让你的枚举继承自 Int public enum SearchField : int @paul,将枚举类型指定为 int 是多余的,因为默认情况下,int 是枚举成员的默认管理类型。显然,我可以使用强制转换为 int 并强制转换回枚举来实现这一点。我最终试图理解为什么枚举没有反序列化。 【参考方案1】:

枚举、int、double、string 等本身不是有效的协议缓冲区消息。您必须将它们设为对象的字段或属性,然后序列化该对象。

【讨论】:

【参考方案2】:

如果您创建一个课程并将其传递到您的搜索中,那么您应该会得到您需要的东西。希望这会有所帮助。

如果您安装了序列化程序,它将返回一个可操作的类对象。

[ProtoContract()]
public class PatientSearch

    public PatientSearch()
    
        searchTerms = new List<string>();
        fields = new List<SearchField>();
    
    [ProtoMember(1)]
    public List<string>searchTerms get;private set;

    [ProtoMember(2)]
    public SearchNature Nature get; set;
    [ProtoMember(3)]
    public SearchMode Nature get; set;
    [ProtoMember(4)]
    public  List<SearchField> fields get; private set;


【讨论】:

以上是关于将单个枚举值传递给 WCF 服务时,protobuf-net 引发有关无效线路类型的异常的主要内容,如果未能解决你的问题,请参考以下文章

迁移到 tomcat 后,将枚举值作为参数从 JSF 页面传递给 bean 方法失败

WCF如何传递令牌进行身份验证?

如何将(声明)安全令牌传递给启用 WIF 的 WCF 服务?

将 JSON 数组传递给 WCF Web 服务

通过 GET 将数组传递给 WCF 服务

传递大字节 [] 时 WCF 服务错误 413“实体太大”