none
反序列化问题: 模型更新后无法反序列化(格式化程序尝试对消息反序列化时引发异常) RRS feed

  • 问题

  • 错误提示: 格式化程序尝试对消息反序列化时引发异常. "info"并非所需参数.所需参数为"_x003C_transfer_trade_no_x003E_k_BackingFiled".. (新手不能发图片...)



    接口请求:

     [OperationContract]

            Return<object> AddDistributeInfo(string outtradeno, WapPayDistributeView info);

    更新前的模型(info):

        [Serializable]

        public class WapPayDistributeView

        {

            [DataMember]

            public string out_bill_no { get; set; }

            [DataMember]

            public string royalty_email { get; set; }

            [DataMember]

            public string royalty_amount { get; set; }

            [DataMember]

            public string royalty_note { get; set; }

            [DataMember]

            public string storeSysNo { get; set; }

            [DataMember]

            public string order_amount { get; set; }

        }



    更新后的模型(info):

        [Serializable]

        public class WapPayDistributeView

        {

            [DataMember]

            public string out_bill_no { get; set; }

            [DataMember]

            public string royalty_email { get; set; }

            [DataMember]

            public string royalty_amount { get; set; }

            [DataMember]

            public string royalty_note { get; set; }

            [DataMember]

            public string storeSysNo { get; set; }

            [DataMember]

            public string order_amount { get; set; }

            [DataMember]

            public string distribute_trade_no { get; set; }

        }



    问题描述:

    (服务器:两台带负载均衡,WCF.Net FrameWork 4.0版本,请求端是.Net FrameWork 4.5版本)

    这个接口(Adddistribute方法)一直是可以用的, 后来在接口的参数(WapPayDistributeView)info里加了一个(string)distribute_trade_no,

    唯一的变化就是新增的这个字段.结果导致接口请求反序列化报错,而且是偶尔报错.当时把模型库dll重新更新了,以排除模型版本问题,但还是偶尔出现接口调用失败.   

    错误提示: "info"并非所需参数,所需参数为"_x003C_transfer_trade_no_x003E_k_BackingFiled".. 

    1是两边的系列化和反序列化对应不上吗? 但是用的都是同一个模型类啊. 

    2这里提示的info是不是默认的DataContract序列化器序列化的,x003C_transfer_trade_no_x003E_k_BackingFiled  是由 Serilizirale特性 指示序列化的?  但是以前的模型类也都是这么写,怎么会偶尔出现调用失败的情况?

    3会不会是请求端和服务端口.Net FrameWork 的版本不一样, 使序列化和反序列化的机制也不一样?但是这是偶然发生的调用失败.如果序列化问题会一直报错吧

    昨天看了一整天还是没找到原因.... 其实我怀疑只是版本更新问题,但是负责发布的经理很确定版本是对的. 后来只能还原这个类了. 找不到原因很难受..  有劳大师们解答一下...不胜感

    2018年8月10日 1:33

全部回复

  • 不要返回object,(Return<object>),要返回具体的类型,比如WapPayDistributeView

    第二,更新接口后,要WCF两边的程序都要更新才可以



    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2018年8月13日 0:36
  • Hi JuliusKingsley,

    根据你的描述,这种错误是偶尔性地发生,我认为客户端和服务端对于数据协定类应该是一致地。否则不可能在某些情况下正常工作。在我看来,不同版本的.netframework不会导致这个问题。默认的序列化器的实现都是基于.netframework4.0的。这种错误应该是其他问题的引起地,比如创建通道的绑定设置,MaxReceivedMessageSize, MaxStringContentLength。 我建议你提供更过关于错误的细节。比如,一般在什么情况下会出现这种错误?

    另外,没必要对Serializable的类的成员使用Datamember特性。它们已经被显式地标记为序列化。DataMemberDataContract一起使用是为了更好的控制序列化字段(名字空间,序列化字段的名字)。我建议你使用DataContract来表明复杂数据类型的序列化格式。这里是官方的描述。

    With [Serializable], all fields become part of the data contract (unless they are marked with [NonSerialized]). With [DataContract], only members marked with [DataMember] are included. Note that if a type has both [DataContract] and [Serializable] attributes on it, it will use the [DataContract] mapping

    https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/data-transfer-and-serialization

    期待你的回复。

    Best Regards

    Abraham
    2018年8月14日 3:29
  • Hi Abraham Qian,

    很感谢你的回复. 这里提供更详细的错误信息 :

    https://social.msdn.microsoft.com/Forums/getfile/1304718

    (报错发生在请求端)

    还有终结点的配置信息:(请求端) 

    <bindings> <basicHttpBinding> <binding name="ServiceForMallBasicHttpBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferSize="2097152" maxReceivedMessageSize="2097152" useDefaultWebProxy="false"> <readerQuotas maxDepth="2097152" maxStringContentLength="2097152" maxArrayLength="2097152" maxBytesPerRead="2097152" maxNameTableCharCount="2097152" /> <security mode="None"> <transport clientCredentialType="None" proxyCredentialType="None" realm=""> <!--<extendedProtectionPolicy policyEnforcement="Never" />--> </transport> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security> </binding> <binding name="WebServiceSoap"> <security mode="Transport" /> </binding> <binding name="WebServiceSoap1" /> </basicHttpBinding> <netTcpBinding> <binding name="ServiceForO2ONetTcpBinding" closeTimeout="00:00:10" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferSize="209715200" maxReceivedMessageSize="209715200"> <readerQuotas maxDepth="64" maxStringContentLength="209715200" maxArrayLength="1638400" maxBytesPerRead="209715200" maxNameTableCharCount="209715200" /> <security mode="None" /> </binding> </netTcpBinding> </bindings> <client>

    <endpoint address="http://localhost:6996/Alipay/AlipayService.svc" binding="basicHttpBinding" bindingConfiguration="ServiceForMallBasicHttpBinding" contract="com.zh.kj.MallWCF.Interfaces.Alipay.ServiceContract.IAlipayService" name="BasicHttpBinding_ICustomerService" /> </client>

    还有终结点的配置信息:(服务端) 

    <bindings>
          <basicHttpBinding>
            <binding name="ServiceForMallBasicHttpBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" useDefaultWebProxy="false">
              <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="1024000" maxNameTableCharCount="1024000" />
              <security mode="None" />
            </binding>
          </basicHttpBinding>
        </bindings>
    <services>
          <service behaviorConfiguration="ServiceForMallhavior" name="com.zh.kj.MallWCF.Service.Alipay.AlipayService">
            <endpoint binding="basicHttpBinding" bindingConfiguration="ServiceForMallBasicHttpBinding" contract="com.zh.kj.MallWCF.Interfaces.Alipay.ServiceContract.IAlipayService"></endpoint>
          </service>
    </services>


    *************** 问题出现的背景:

    WapPayDistributeView 类中新增字段 (string)distribute_trade_no , 更新请求端和服务端dll(未重启), 偶尔会发生请求报反序列化错误,原来的WCF接口代码完全没变,只是在传入模型中多了一个字段 . 

    现在无法重现这个仅在生产环境上出现的问题了....... T_T

    *************************************************

    你的回复对我很有帮助,

    再次表示感谢!

    Best Regards 

    Julius


    2018年8月14日 9:38