You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WSDL的object[]数组赋值Guid数组时编译及序列化失败求助

问题描述

使用VS2022「添加连接服务」引入第三方不可修改的WSDL服务,服务版本更新后要求传入数组而非单一值。其中CancelIndiciumRequest类的Items属性为object[]类型,厂商推荐赋值Guid[]而非string[],但遇到以下问题:

  • 直接赋值Guid[]出现编译错误:Cannot implicitly convert type 'System.Guid[]' to 'object[]'
  • 转换为object[]后运行时触发XML序列化错误:The type System.Guid may not be used in this context

相关代码

主调用方法

internal int CancelLabel(string trackNum)
{
    CancelIndiciumRequest req = new CancelIndiciumRequest
    {
        Item = GetCredsType(),
        // 以下是尝试过的赋值方式(均有问题)
        // Items = (object[]) new Guid[] { new Guid(trackNum) }, // 编译错误
        // Items = (new List<Guid> { new Guid(trackNum) }).ToArray(), // 运行时错误
        // Items = GetArrayGuid(trackNum), // 运行时错误
        // Items = GetGuids(trackNum).ToArray(); // 运行时错误
    };
    // ... 省略其他代码
    resp = GetResponse(req);
}

支持方法

private List<Guid> GetGuids(string TxID)
{
    return new List<Guid> { new Guid(TxID) };
}

private object[] GetArrayGuid(string sGuid)
{
    object[] oAry = new object[1];
    oAry[0] = new Guid(sGuid);
    return oAry;
}

调用代码

private CancelIndiciumResponse GetResponse(CancelIndiciumRequest req)
{
    XSoap x = sFactory.CreateChannel();
    CancelIndiciumResponse resp = null;
    int retry = 0;

    while (resp == null && retry < 1)
    {
        try
        {
            resp = x.CancelIndicium(req); // 调用自动生成的连接服务代码
            _authToken = resp.Authenticator;
        }
        catch (FaultException ex)
        {
            // ... 错误处理代码
        }
        catch (Exception ex)
        {
            // ... 错误处理代码
        }
        retry++;
    }

    return resp;
}

连接服务生成的代码(简化版)

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="CancelIndicium", WrapperNamespace="http://x.com/xml/namespace/2023/07/x/x", IsWrapped=true)]
public partial class CancelIndiciumRequest {
    
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://x.com/xml/namespace/2023/07/x/x", Order=0)]
    [System.Xml.Serialization.XmlElementAttribute("Authenticator", typeof(string))]
    [System.Xml.Serialization.XmlElementAttribute("Credentials", typeof(Credentials))]
    public object Item;
    
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://x.com/xml/namespace/2023/07/x/x", Order=1)]
    [System.Xml.Serialization.XmlElementAttribute("xTxIDs", typeof(System.Guid[]))]
    [System.Xml.Serialization.XmlElementAttribute("xNumbers", typeof(string[]))]
    public object[] Items;
    
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://x.com/xml/namespace/2023/07/x/x", Order=2)]
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
    public System.Nullable<bool> SendEmail;
    
    public CancelIndiciumRequest() { }
    
    public CancelIndiciumRequest(object Item, object[] Items, System.Nullable<bool> SendEmail) {
        this.Item = Item;
        this.Items = Items;
        this.SendEmail = SendEmail;
    }
}

完整异常信息

System.ServiceModel.CommunicationException: There was an error in serializing body of message CancelIndiciumRequest: 'There was an error generating the XML document.'.  Please see InnerException for more details. ---> System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type System.Guid may not be used in this context.
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterSwsimV135Soap.Write269_CancelIndicium(Object[] p)
   at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer72.Serialize(Object objectToSerialize, XmlSerializationWriter writer)
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   at System.ServiceModel.Dispatcher.XmlSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, XmlSerializer serializer, MessagePartDescription returnPart, MessagePartDescriptionCollection bodyParts, Object returnValue, Object[] parameters)
   at System.ServiceModel.Dispatcher.XmlSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest)
   --- End of inner exception stack trace ---

Server stack trace: 
   at System.ServiceModel.Dispatcher.XmlSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest)
   at System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(XmlDictionaryWriter writer, MessageVersion version, Object[] parameters, Object returnValue, Boolean isRequest)
   at System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.BodyWriterMessage.OnWriteBodyContents(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(Message message, BufferManager bufferManager, Int32 initialOffset, Int32 maxSizeQuota)
   at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
   at System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message, Boolean shouldRecycleBuffer)
   at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
   at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at USPostal.SWSIM.SwsimV135Soap.CancelIndicium(CancelIndiciumRequest request)
   at USPostal.StampsApiInterface.GetResponse(CancelIndiciumRequest req) in C:\Users\lawre\Source\Repos\USPostalAPI\USPostal\InterfaceClasses\StampsApiInterface.cs:line 1954
解决方案

问题核心在于对Items属性序列化规则的误解:生成的代码中,Items的XmlElementAttribute指定了允许的元素类型是Guid[]或string[],而非单个Guid或string。也就是说,Items数组中需要存放的是Guid[]对象(对应XML元素<xTxIDs>),而非将每个Guid转成object存入数组。

正确赋值方式

将Guid[]作为一个元素放入object[]中,这样XML序列化器就能匹配到对应的属性配置,正确生成服务端期望的XML结构:

Items = new object[] { new Guid[] { new Guid(trackNum) } }

解释为什么之前的方式错误

  1. 直接赋值Guid[]给object[]:编译错误是因为值类型数组(如Guid[])不支持协变转换为object[],只有引用类型数组(如string[])才能隐式转换。
  2. 将单个Guid转成object存入数组:运行时错误是因为序列化器找不到单个Guid对应的XML元素定义——属性配置仅允许Guid[]或string[]类型作为Items的元素。

扩展:传入多个Guid的情况

如果需要传入多个Guid,只需扩展内部的Guid[]即可:

Items = new object[] { new Guid[] { new Guid(trackNum1), new Guid(trackNum2) } }

内容的提问来源于stack exchange,提问作者user2832940

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 23:49:52