用VC++2005调用用ASP.NET(C#)做的WebSerice接口进行操作数据库
作者:木水于(shemney_yang@qq.com)
关键字:VS2005 VC++2005 ASP.NET(C#) WebSerice 数据库 ADO XML
(代码下载:http://download.csdn.net/source/719983 资源名称为VC++2005 WebService)
一、 前言
最近在做毕业设计时,要对远程数据库进行查询,更新,删除等操作。
因此我利用WebService技术。
WebService技术主要目的是为了夸平台相互通信,不受语言的限制。为了达到这一目标,WebService采用了基于XML(可扩展标记语言)、XSD(XMLSchema)等独立于平台、独立于软件供应商的标准。
既然如此,我一开始以为只要WebService提供操作数据库的接口,然后在客户端远程调用这些接口就可以达到我的目的。这想法是对的,说起来简单,但是做起来可不是这么简单了。尤其是我们有用VC MFC的开发人员。
我花了几乎一周的时间来研究这个问题,在网上找的例子很简单,也很零散。但不符合我的要求,只说了调用WebService的一个很简单的接口,没有数据库操作。还有说用gsoap(WebService应用的一种),我觉得这个方法比较麻烦。
好了费话少说,下面介绍我的做法,这也是对网上所说的一些技术总结,因为在网上我没有找到一个具体例子,所以写这篇文章,为那些没有用过这种技术的人能够快速掌握这种技术,尽一点微薄之力。
二、 开发环境
开发平台:VS2005
操作系统:Windows 2003 (提供了方便的IIS管理,如果是使用XP的用户就请安装IIS吧)
开发语言:C++, C#
三、 主要解决思路
1、利用VS2005创建一个asp.net(C#)的web 服务网站,定义操作数据库的函数(也说是WebService接口)。
2、将创建的网站放到IIS虚拟目录中。
3、利用VC++2005创建一个基于对话框的程序,调用WebSerive接口。
四、 创建WebService网站(ASP.NET C#)
1、 打开VS2005,新建一个网站。请看下图:
图一
如上图,选择模板“ASP.NET WEB服务”,语言“Visual C#”,单击“浏览”更改项目的存放位置,更改项目名称“WS”,单击“确定”。
2、在解决方案中展开“App_Code”,找到“Service.cs”,双击打开,如下图所示:
图二
3、为了与VC++ 客户端更好的通信,在这里决定使用ADO(注意不是ADO.NET)操作数据库,所以要添加COM组件。
方法如下:在解决方法中,右击鼠标右键,单击“添加引用”,单击“COM”,找到“Microsoft ActiveX Data Objects Libarary 2.7”,选择它,单击确定。如下图所示:
图三
4、编写代码:
(1)、添加引用空间:
Using ADODB;
(2)、添加public属性:
public static ADODB.Connection conn = new ADODB.Connection();
public static ADODB.Recordset rs = new ADODB.Recordset();
public string strConn ="Provider=SQLOLEDB;Data Source=你的服务端IP;Persist Security Info=False;Integrated Security=SSPI;User_ID=用户名;Password=用户密码;Initial Catalog=数据库名";
(3)、设计接口:
[WebMethod]
public string ExecSQL(string strSQL)
{
conn.ConnectionString = strConn;
//连接数据库
try
{
conn.Open(strConn, "", "", -1);
}
catch (Exception e)
{
conn.Close();
return (e.ToString());
}
ADODB.Stream stream = new ADODB.Stream();
try
{
rs.Open(strSQL, conn, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic, (int)ADODB.CommandTypeEnum.adCmdText);
rs.Save(stream, PersistFormatEnum.adPersistXML); //将查询结果以XML形式保存到Stream对象中
}
catch (Exception e1)
{
conn.Close();
return e1.ToString();
}
conn.Close();
return stream.ReadText(stream.Size); //返回XML字符串
}
(5)、单击“生成网站”,如下图:
图四
然后,单击“调试”,再单击“开始执行(不调试)”,我们IE浏览器上右看如下图所示:
图五
(6)、在浏览器中成功看到WebService网页后,将WS添加到IIS的虚拟目录中。接着为WS创建应用程序池。
方法如下:打开“WS属性”,单击“创建”,单击确定。如下图所示:
图六
(7)、在IIS中,单击“Service.asmx”,单击鼠标右键,单击“浏览”。在浏览器中成功看网页后,得到见网址:http://localhost/WS/Service.asmx。(localhost这是在本地机器测试时用的,如果不是本地机器,将IP替换它)。
5、好了服务器的编程就到这,下面介绍VC++2005编写客户端,对于熟悉VC++的人来说,我就不把步骤写得那么详细了。
五、创建客户端(VC++2005 MFC 非托管)
1、创建一个基于对话框的MFC应用程序,工程名为WebService。为对话框资源添加一个名为“查询”的按钮,并添加鼠标单击事件处理。
2、在解决方案资源管理器中右击鼠标,单击“添加Web引用”,如下图所示:
图七
如上图,在“URL(u)”中写上WebService的网址:http://localhost/WS/Service.asmx,单击“前往”,Web引用名可以随便取,我取“MyWebService”,单击“添加引用”。可以看到解决方案管理器中的变化:
图八
技巧说明:如果Web服务器上的WebService有改变时,可以在右击“MyWebService”,单击“更新Web引用”,重新编译。或者删除重新添加WEB引用。
3、在类视图中:
图九
如上图,有一类CserviceT<Tclient>,函数ExexSQL(BSTR strSQL,BSTR *ExecSQLResult)这是我们需要用到的。注意:这里我们可以看得出来,VC++是通过COM组件的方式调用WebService的接口的。
4、在stdafx.h中添加下面语句:
#import “C:/Program Files/Common Files/System/ado/msado15.dll” no_namespace rename(“EOF”,”rsEOF”)
在WebServiceDlg.cpp中添加引用文件如下:
#include "WebService.h"
using namespace Service;
5、编写调用代码,如下:
void CWebServiceDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CoInitialize(NULL);
_StreamPtr pStream;
pStream.CreateInstance(__uuidof(Stream));
_RecordsetPtr pRst(_uuidof(Recordset));
HRESULT hr = S_OK;
CComBSTR Result;
CComBSTR sql = "Select Nickname from User1 where User_ID = '000'";
CService* service = new CService(); // 代理对象
// 可以调用SetUrl动态设置Web服务地址
// debug->SetUrl("http://blog.eray.cn/debug.asmx");
hr = service->ExecSQL(sql,&Result);
if(FAILED(hr))
{
MessageBox(L"调用失败");
}
else
{
CString str;
_variant_t varOptional(DISP_E_PARAMNOTFOUND,VT_ERROR);
pStream->raw_Open(varOptional, adModeUnknown, adOpenStreamUnspecified,NULL,NULL);
pStream->put_Type(adTypeText);
pStream->WriteText((_bstr_t)Result,adWriteChar); //将返回的XML字符串,读入Stream对象中
pStream->Position = 0;
//打开含有XML序列化信息的Stream,vtMissing是不用我们自己定义的
pRst->Open(pStream.GetInterfacePtr(),vtMissing,
adOpenForwardOnly,adLockReadOnly,adCmdFile);
while(!pRst->rsEOF)
{
str = pRst->GetCollect("Nickname");
pRst->MoveNext();
}
MessageBox(str,L"查询结果");
pRst->Close();
pRst.Release();
pStream->Close();
pStream.Release();
}
delete service;
CoUninitialize();
}
6、好了,该写的代码都已经写完了,编译成功,运行测试,OK成功!
六、结束语
这是我经过好几天努的成果,在这里班门弄斧了,如果有什么不对的地方,请指正。希望能给读者门一点帮助。