none
soap库连接webservice传二进制文件 RRS feed

  • 问题

  • webservice端的代码,用于接收和保存二进制图片文件

    [WebMethod]
        public void SaveDocument(byte[] docbinaryarray, string docname)
        {
            string strdocPath;
            strdocPath = "D:\\test\\share\\" + docname;
            FileStream objfilestream = new FileStream(strdocPath, FileMode.Create, FileAccess.ReadWrite);
            objfilestream.Write(docbinaryarray, 0, docbinaryarray.Length);
            objfilestream.Close();
        }

    客户端用的soap库

    //pfilebuff  dwfilelength 为读出的二进制图片
    BOOL CTrayDlg::WebServiceCall(char *pFileBuff, DWORD dwFileLength, CString& strRet)
    {
    	HRESULT hRet = FALSE;
    	CoInitialize(NULL);
    
    	ISoapSerializerPtr Serializer;
    	ISoapReaderPtr Reader;
    	ISoapConnectorPtr Connector;
    
    	try
    	{
    		HRESULT hr;
    		BSTR str = strImgName.AllocSysString();
    
    		//与服务器连接
    		hr = Connector.CreateInstance(__uuidof(HttpConnector30));
    		if( FAILED(hr) )
    		{
    			TRACE("\nSoap 功能缺失! -请确认您的机器上安装有soap3.0或3.0以上版本补丁包, 以及msxml4.0或4.0以上的版本\n");
    			return FALSE;
    		}
    
    		//调用页面 
    		Connector->Property["EndPointURL"] = _T("http://localhost:53455/manwangchina/Service.asmx?wsdl"); 
    
    		//使用浏览器的代理设置
    		Connector->Property["ProxyServer"] = "<CURRENT_USER>"; 
    
    		//连接
    		hr = Connector->Connect();
    
    		//响应函数
    		Connector->Property["SoapAction"] = _T("http://tempuri.org/SaveDocument");
    
    		//启动消息句柄
    		hr = Connector->BeginMessage();
    
    		//SoapSerializer对象
    		hr = Serializer.CreateInstance(__uuidof(SoapSerializer30));
    		if( FAILED(hr) )
    		{
    			TRACE("\nSoap 功能缺失!请确认您的机器上安装有soap3.0或3.0以上版本补丁包, 以及msxml4.0或4.0以上的版本\n");
    			return FALSE;
    		}
    
    		//SoapSerializer
    		hr = Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));
    
    		//创建SOAP消息 
    		hr = Serializer->StartEnvelope(_T(""),_T(""),_T(""));
    		hr = Serializer->StartBody(_T(""));
    
    		//找到函数名
    		hr = Serializer->StartElement(_T("SaveDocument"), _T("http://tempuri.org/"), _T("NONE"), _T(""));
    
    		//找到第一个参数
    		hr = Serializer->StartElement(_T("docbinaryarray"), _T("http://tempuri.org/"), _T("NONE"), _T(""));
    
    		IDataEncoderFactoryPtr encoderFc;
    		encoderFc.CreateInstance(__uuidof(DataEncoderFactory30));
    		DWORD *len1=new DWORD;
    		IDataEncoderPtr encoder=encoderFc->GetDataEncoder(L"base64");
    		encoder->raw_SizeToEncode(pFileBuff,dwFileLength,len1);
    		byte *data = new byte[dwFileLength+1];
    
    		//输入参数值
    		hr = Serializer->WriteBuffer(dwFileLength, (byte*)data);
    		//结束
    		hr = Serializer->EndElement();
    
    		//找到第二个参数
    		hr = Serializer->StartElement(_T("docname"), _T("http://tempuri.org/"), _T("NONE"), _T(""));
    		//输入参数值
    		hr = Serializer->WriteString(str);
    		//结束
    		hr = Serializer->EndElement();
    
    		//----------------------------------
    		hr = Serializer->EndElement();
    		hr = Serializer->EndBody();
    		hr = Serializer->EndEnvelope();
    
    		//将该消息发送给web服务
    		hr = Connector->EndMessage();
    		hr = Connector->InputStream;
    
    		SysFreeString(str);
    
    		//读取响应 
    		hr = Reader.CreateInstance(__uuidof(SoapReader30));
    
    		//将reader联接到connector的输出字符串
    		Reader->Load(_variant_t((IUnknown*)Connector->OutputStream), _T(""));
    
    		//结果
    		strRet = (const char*)Reader->RpcResult->text;
    		hRet = TRUE;
    //		AfxMessageBox(strRet);
    	}
    	catch (_com_error e)
    	{
    		TRACE("接口调用失败:%s\n", strMethod);
    		return FALSE;
    	}
    	catch (...)
    	{
    		return FALSE;
    	}
    	return hRet;
    }

    程序总是提示调用SaveDocument失败, 可能出错的代码是

    hr = Serializer->WriteBuffer(dwFileLength, (byte*)data);找几天都没有找到出错的原因

    2014年2月13日 3:35

答案

  • 做好了, 留给后人一个借鉴的代码

    BOOL CTrayDlg::WebServiceCall(char *pFileBuff, DWORD dwFileLength, CString& strRet)

     {   

        HRESULT hRet = FALSE;

        CoInitialize(NULL);

        ISoapSerializerPtr Serializer;
        ISoapReaderPtr Reader;
        ISoapConnectorPtr Connector;
        IDataEncoderFactoryPtr encoderFc;

        try
        {
            HRESULT hr;
            BSTR str = strImgName.AllocSysString();

            //与服务器连接
            hr = Connector.CreateInstance(__uuidof(HttpConnector30));
            if( FAILED(hr) )
            {
                TRACE("\nSoap 功能缺失! -请确认您的机器上安装有soap3.0或3.0以上版本补丁包, 以及msxml4.0或4.0以上的版本\n");
                return FALSE;
            }

            //调用页面
           Connector->Property["EndPointURL"] = _T("http://localhost:53455/manwangchina/Service.asmx?wsdl");

            //使用浏览器的代理设置
            Connector->Property["ProxyServer"] = "<CURRENT_USER>";

            //连接
            hr = Connector->Connect();

            //响应函数
            Connector->Property["SoapAction"] = _T("http://tempuri.org/SaveDocument");

            //启动消息句柄
            hr = Connector->BeginMessage();

            //SoapSerializer对象
            hr = Serializer.CreateInstance(__uuidof(SoapSerializer30));
            if( FAILED(hr) )
            {
                TRACE("\nSoap 功能缺失!请确认您的机器上安装有soap3.0或3.0以上版本补丁包, 以及msxml4.0或4.0以上的版本\n");
                return FALSE;
            }

            //SoapSerializer
            hr = Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));

            //创建SOAP消息
            hr = Serializer->StartEnvelope(_T(""),_T(""),_T(""));
            hr = Serializer->StartBody(_T(""));

            //找到函数名
            hr = Serializer->StartElement(_T("SaveDocument"), _T("http://tempuri.org/"), _T(""), _T(""));

            //找到第一个参数
            hr = Serializer->StartElement(_T("docbinaryarray"), _T("http://tempuri.org/"), _T(""), _T(""));

            encoderFc.CreateInstance(__uuidof(DataEncoderFactory30));
            DWORD *len1=new DWORD;
            IDataEncoderPtr encoder=encoderFc->GetDataEncoder(L"base64");
            encoder->raw_SizeToEncode(pFileBuff,dwFileLength,len1);
            int lon = *len1;
            byte *data = new byte[lon+1];
            hr=encoder->Encode(pFileBuff,dwFileLength,data,len1);
            if(FAILED(hr)){
                TRACE("Encode error! ");
            }
            int len2 = *len1;
            //输入参数值
            hr = Serializer->WriteBuffer(len2, (byte*)data);
            delete len1;
            delete[] data;
            delete[] pFileBuff;
            //结束
            hr = Serializer->EndElement();

            //找到第二个参数
            hr = Serializer->StartElement(_T("docname"), _T("http://tempuri.org/"), _T(""), _T(""));
            //输入参数值
            hr = Serializer->WriteString(str);
            //结束
            hr = Serializer->EndElement();

            //----------------------------------
            hr = Serializer->EndElement();
            hr = Serializer->EndBody();
            hr = Serializer->EndEnvelope();
            //将该消息发送给web服务
            hr = Connector->EndMessage();

            SysFreeString(str);

            //读取响应
            hr = Reader.CreateInstance(__uuidof(SoapReader30));
            //将reader联接到connector的输出字符串
            Reader->Load(_variant_t((IUnknown*)Connector->OutputStream), _T(""));
            //结果
            strRet = (const char*)Reader->RpcResult->text;
            hRet = TRUE;
        }
        catch (_com_error e)
        {
            TRACE("接口调用失败:%s\n", strMethod);
            return FALSE;
        }
        catch (...)
        {
            return FALSE;
        }
        return hRet;
    }


    2014年2月13日 7:57

全部回复

  • 做好了, 留给后人一个借鉴的代码

    BOOL CTrayDlg::WebServiceCall(char *pFileBuff, DWORD dwFileLength, CString& strRet)

     {   

        HRESULT hRet = FALSE;

        CoInitialize(NULL);

        ISoapSerializerPtr Serializer;
        ISoapReaderPtr Reader;
        ISoapConnectorPtr Connector;
        IDataEncoderFactoryPtr encoderFc;

        try
        {
            HRESULT hr;
            BSTR str = strImgName.AllocSysString();

            //与服务器连接
            hr = Connector.CreateInstance(__uuidof(HttpConnector30));
            if( FAILED(hr) )
            {
                TRACE("\nSoap 功能缺失! -请确认您的机器上安装有soap3.0或3.0以上版本补丁包, 以及msxml4.0或4.0以上的版本\n");
                return FALSE;
            }

            //调用页面
           Connector->Property["EndPointURL"] = _T("http://localhost:53455/manwangchina/Service.asmx?wsdl");

            //使用浏览器的代理设置
            Connector->Property["ProxyServer"] = "<CURRENT_USER>";

            //连接
            hr = Connector->Connect();

            //响应函数
            Connector->Property["SoapAction"] = _T("http://tempuri.org/SaveDocument");

            //启动消息句柄
            hr = Connector->BeginMessage();

            //SoapSerializer对象
            hr = Serializer.CreateInstance(__uuidof(SoapSerializer30));
            if( FAILED(hr) )
            {
                TRACE("\nSoap 功能缺失!请确认您的机器上安装有soap3.0或3.0以上版本补丁包, 以及msxml4.0或4.0以上的版本\n");
                return FALSE;
            }

            //SoapSerializer
            hr = Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));

            //创建SOAP消息
            hr = Serializer->StartEnvelope(_T(""),_T(""),_T(""));
            hr = Serializer->StartBody(_T(""));

            //找到函数名
            hr = Serializer->StartElement(_T("SaveDocument"), _T("http://tempuri.org/"), _T(""), _T(""));

            //找到第一个参数
            hr = Serializer->StartElement(_T("docbinaryarray"), _T("http://tempuri.org/"), _T(""), _T(""));

            encoderFc.CreateInstance(__uuidof(DataEncoderFactory30));
            DWORD *len1=new DWORD;
            IDataEncoderPtr encoder=encoderFc->GetDataEncoder(L"base64");
            encoder->raw_SizeToEncode(pFileBuff,dwFileLength,len1);
            int lon = *len1;
            byte *data = new byte[lon+1];
            hr=encoder->Encode(pFileBuff,dwFileLength,data,len1);
            if(FAILED(hr)){
                TRACE("Encode error! ");
            }
            int len2 = *len1;
            //输入参数值
            hr = Serializer->WriteBuffer(len2, (byte*)data);
            delete len1;
            delete[] data;
            delete[] pFileBuff;
            //结束
            hr = Serializer->EndElement();

            //找到第二个参数
            hr = Serializer->StartElement(_T("docname"), _T("http://tempuri.org/"), _T(""), _T(""));
            //输入参数值
            hr = Serializer->WriteString(str);
            //结束
            hr = Serializer->EndElement();

            //----------------------------------
            hr = Serializer->EndElement();
            hr = Serializer->EndBody();
            hr = Serializer->EndEnvelope();
            //将该消息发送给web服务
            hr = Connector->EndMessage();

            SysFreeString(str);

            //读取响应
            hr = Reader.CreateInstance(__uuidof(SoapReader30));
            //将reader联接到connector的输出字符串
            Reader->Load(_variant_t((IUnknown*)Connector->OutputStream), _T(""));
            //结果
            strRet = (const char*)Reader->RpcResult->text;
            hRet = TRUE;
        }
        catch (_com_error e)
        {
            TRACE("接口调用失败:%s\n", strMethod);
            return FALSE;
        }
        catch (...)
        {
            return FALSE;
        }
        return hRet;
    }


    2014年2月13日 7:57
  • 你好:

    谢谢你对VC++中文论坛的支持!

    2014年2月15日 11:52
    版主