C,C#,WebService结构体数组返回问题--谐解

本文讨论了如何在嵌入式设备中通过webservice服务实现数据库查询,并将查询结果转换为JSON格式以供C#客户端解析。解决了C#客户端无法解析XML转换成数组的问题,同时介绍了手动写wsdl生成C#端代码的方法。并通过提供的WSDL文件展示了一个具体的查询接口定义,以及如何使用C#解析JSON数据和处理二进制数据返回。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

应用需求:嵌入式设备提供数据库查询结果,webservice 服务,c#平台作为客户端查询远端设备的记录,即分布式查询。

        遇到问题:1.基于gsoap的基本webservice开发就不废话了,网上一大堆。痛点,查询多条记录结果返回给c#。c#客户端无法解析xml转换成数组。

    2.多个二进制数据同时返回给c#。

先说我的解决方法:1. 查询结果,转换成json串,用string 类型返回(高手提醒)。c端,采用cJson库解析创建json串(简单)。

                                            2. 手动写wsdl 分别生成从,c, c#端代码。(自动生成c#代码,自动分解c#返回值)

        WSDL文件:

<?xml version="1.0" encoding="UTF-8"?>

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:tns="http://www.jshwx.com/sbox/"
             xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SboxRecordServer"
             targetNamespace="http://www.jshwx.com/sbox/">
  <types>
    <xsd:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.jshwx.com/sbox/"
                targetNamespace="http://www.jshwx.com/sbox/" version="1.0">
				
		<!--卡口索引查询接口参数-->		
		<xsd:element name="kkQueryRecordIdxReq" type="tns:kkQueryRecordIdxReq"/>
		<xsd:element name="kkQueryRecordIdxRsp" type="tns:kkQueryRecordIdxRsp"/>
		<xsd:complexType name="kkQueryRecordIdxReq">
			<xsd:sequence>
				<xsd:element minOccurs="0" maxOccurs="1" name="startTime" type="xsd:string" />
				<xsd:element minOccurs="0" maxOccurs="1" name="endTime" type="xsd:string" />
				<xsd:element minOccurs="1" maxOccurs="1" name="chId" type="xsd:int" />
				<xsd:element minOccurs="0" maxOccurs="1" name="plateNum" type="xsd:string" />
				<xsd:element minOccurs="1" maxOccurs="1" name="maxResultNum" type="xsd:int" />
				<xsd:element minOccurs="1" maxOccurs="1" name="timeOut" type="xsd:int" />
			</xsd:sequence>
		</xsd:complexType>
		<xsd:complexType name="kkQueryRecordIdxRsp" >
			<xsd:sequence>
				<xsd:element minOccurs="1" maxOccurs="1" name="kkQueryRecordResult" type="xsd:int" />
				<xsd:element minOccurs="1" maxOccurs="1" name="recordNum" type="xsd:int" />
				<xsd:element minOccurs="0" maxOccurs="1" name="recordIdxJson" type="xsd:string" />
			</xsd:sequence>
		</xsd:complexType>
		
		<!--卡口数据获取接口参数-->	
		<xsd:element name="kkGetRecordDataReq" type="tns:kkGetRecordDataReq"/>
		<xsd:element name="kkGetRecordDataRsp" type="tns:kkGetRecordDataRsp"/>
		<xsd:complexType name="kkGetRecordDataReq">
			<xsd:sequence>
				<xsd:element minOccurs="0" name="recordId" type="xs:int" />
			</xsd:sequence>
		</xsd:complexType>
        <xsd:complexType name="kkGetRecordDataRsp">
			<xsd:sequence>
				<xsd:element minOccurs="1" maxOccurs="1" name="kkGetRecordDataResult" type="xsd:int" />
				<xsd:element minOccurs="0" name="recordName" type="xs:string" />
				<xsd:element minOccurs="0" name="idxFile" nillable="true" type="xs:base64Binary" />
				<xsd:element minOccurs="0" name="jpgFile" nillable="true" type="xs:base64Binary" />
			</xsd:sequence>
		</xsd:complexType>
    </xsd:schema>
  </types>
  
  <!--卡口索引查询接口参数-->	
  <message name="kkQueryRecordIdxReq">
	<part element="tns:kkQueryRecordIdxReq" name="parameters" />
  </message>
  <message name="kkQueryRecordIdxRsp">
	<part element="tns:kkQueryRecordIdxRsp" name="parameters" />
  </message>
  <!--卡口数据获取接口参数-->	
  <message name="kkGetRecordDataReq">
	<part element="tns:kkGetRecordDataReq" name="parameters" />
  </message>
  <message name="kkGetRecordDataRsp">
	<part element="tns:kkGetRecordDataRsp" name="parameters" />
  </message>
   <!--端口-->	
  <portType name="SboxRecordServerDelegate">
	<operation name="kkQueryRecordIdx">
		<input message="tns:kkQueryRecordIdxReq" />
		<output message="tns:kkQueryRecordIdxRsp" />
	</operation>
	<operation name="kkGetRecordData">
		<input message="tns:kkGetRecordDataReq" />
		<output message="tns:kkGetRecordDataRsp" />
	</operation>
  </portType>
   <!--绑定接口-->	
  <binding name="SboxRecordServerBinding" type="tns:SboxRecordServerDelegate">
	<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
	<operation name="kkQueryRecordIdx">
		<soap:operation soapAction="" />
		<input>
			<soap:body use="literal" />
		</input>
		<output>
			<soap:body use="literal" />
		</output>
	</operation>
	<operation name="kkGetRecordData">
		<soap:operation soapAction="" />
		<input>
			<soap:body use="literal" />
		</input>
		<output>
			<soap:body use="literal" />
		</output>
	</operation>
  </binding>
  
  <!--声明服务-->	
  <service name="SboxRecordServer">
	<port binding="tns:SboxRecordServerBinding" name="SboxRecordServer">
		<soap:address location="http://localhost:8080/" />
	</port>
  </service>
</definitions>

详细说明一下 c#生成的接口,天生的支持数组,

返回json数据

 public int kkQueryRecordIdx(<span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] string startTime,</span><span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] string endTime, </span><span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] int chId,</span><span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] string plateNum,</span><span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] int maxResultNum,</span><span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] int timeOut,</span><span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] out int recordNum, </span><span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] out string recordIdxJson) {</span>
        object[] results = this.Invoke("kkQueryRecordIdx", new object[] {
                    startTime,
                    endTime,
                    chId,
                    plateNum,
                    maxResultNum,
                    timeOut});
        recordNum = ((int)(results[1]));
        recordIdxJson = ((string)(results[2]));
        return ((int)(results[0]));
    }

返回多个二进制数据组

//自动把返回的结构体分解成多个输出,自动关联xml解析类型。如果使用c# 自动生成接口简单的多(但无法解决数据的问题)

 public int kkGetRecordData(<span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] int recordId,</span><span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] [System.Xml.Serialization.XmlIgnoreAttribute()] bool recordIdSpecified,</span><span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] out string recordName,</span><span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="base64Binary", IsNullable=true)] out byte[] idxFile,</span><span style="font-family: Arial, Helvetica, sans-serif;">[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="base64Binary", IsNullable=true)] out byte[] jpgFile) </span><span style="font-family: Arial, Helvetica, sans-serif;">{</span>
        object[] results = this.Invoke("kkGetRecordData", new object[] {
                    recordId,
                    recordIdSpecified});
        recordName = ((string)(results[1]));
        idxFile = ((byte[])(results[2]));
        jpgFile = ((byte[])(results[3]));
        return ((int)(results[0]));
    }
下面是C#自己生成wsdl和接口代码,c#高手可以看看为啥他们不同,帮我解释一下(我不会c#)<span style="font-family: Arial, Helvetica, sans-serif;">//没有把返回结构分解</span>
 public int kkQueryRecord(kkQueryRecordReq req, out kkQueryRecordRsp rsp) {
        object[] results = this.Invoke("kkQueryRecord", new object[] {
                    req});
        rsp = ((kkQueryRecordRsp)(results[1]));
        return ((int)(results[0]));
    }


       c端的接口很正常,没什么问题

我把代码代码打包上传到 路径:http://download.youkuaiyun.com/detail/zhujinghao09/9480345

为了解决这个问题,废了九牛二虎之力,如果有简单的方法,欢迎分享。

参考链接:http://www.cnblogs.com/linyc/archive/2011/12/20/2295040.html

    http://my.oschina.net/jacobin/blog/143452?fromerr=R7swAZoN

谢谢这两位博主,启发很大。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值