0

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

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

导致以下异常...</p>

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://stackoverflow.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)

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

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
}

编辑:

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

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);
}
4

2 回答 2

1

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

于 2013-02-28T22:14:13.157 回答
0

If you make a class and pass that into your search instead you should get what you need. Hopefully this will help.

If you then have the serializer in place it will give you back an operational class object.

[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;}

}
于 2013-02-28T23:06:56.590 回答