李维关于WEBSERVICE 结合数据库编程一节中有个例子是关于客户端分别调用COM+,WAD WebService,ISAPI WebService获取服务器数据。COM+和WAD WebService都没问题,ISAPI WebService,客户端程序如下
var Intf:IComService;
iStart,iEnd:LongInt;
vData:string;
begin
ClientDataSet1.Active:=False;
iStart:=GetTickCount;
Intf:=HTTPRIO1 as IComService; //IComService为调用的Webservice接口
vData:=Intf.QueryData('select * from t_purchase_apply');
with ClientDataSet1 do
begin
XMLData:=vData;
end;
iEnd:=GetTickCount;
Edit2.Text:=InttoStr(iEnd-iStart);
Intf:=nil;
end;
执行的时候出现了怪问题,第一遍执行能够正常获取数据,但当我不停点击按钮重复获取数据时,开始几遍还正常,后来突然报如下错误:
Received Content of Invalid Content-Type Setting:Text/Html-SOAP Expect
"Text/xml"。意思是说收到的数据CONTENT-TYPE类型不正确。而且一旦出现,这个错误将出现的很频繁,经常第一次点击执行就报这个错误。
如果将上述程序改成循环执行数次(10次),则必定报这个错误,请高手指点,为啥会出现这个问题。
另调用的ISAPI WEBSERVICE应该是正确的,也考虑了线程问题,加了CoInitialize(nil),这个WEBSERVICE实现了激活COM+对象,并通过COM+对象获取数据返回客户端。
中间层相应的代码如下:
function TComService.QueryData(const sData:string):string;
var ComObj:TDemoCom;
aData:OleVariant;
begin
CoInitialize(nil);
try
ComObj:=TDemoCom.Create(nil);
ComObj.QueryData(sData,aData);
Result:=aData;
finally
CoUnInitialize;
end;
end;
var Intf:IComService;
iStart,iEnd:LongInt;
vData:string;
begin
ClientDataSet1.Active:=False;
iStart:=GetTickCount;
Intf:=HTTPRIO1 as IComService; //IComService为调用的Webservice接口
vData:=Intf.QueryData('select * from t_purchase_apply');
with ClientDataSet1 do
begin
XMLData:=vData;
end;
iEnd:=GetTickCount;
Edit2.Text:=InttoStr(iEnd-iStart);
Intf:=nil;
end;
执行的时候出现了怪问题,第一遍执行能够正常获取数据,但当我不停点击按钮重复获取数据时,开始几遍还正常,后来突然报如下错误:
Received Content of Invalid Content-Type Setting:Text/Html-SOAP Expect
"Text/xml"。意思是说收到的数据CONTENT-TYPE类型不正确。而且一旦出现,这个错误将出现的很频繁,经常第一次点击执行就报这个错误。
如果将上述程序改成循环执行数次(10次),则必定报这个错误,请高手指点,为啥会出现这个问题。
另调用的ISAPI WEBSERVICE应该是正确的,也考虑了线程问题,加了CoInitialize(nil),这个WEBSERVICE实现了激活COM+对象,并通过COM+对象获取数据返回客户端。
中间层相应的代码如下:
function TComService.QueryData(const sData:string):string;
var ComObj:TDemoCom;
aData:OleVariant;
begin
CoInitialize(nil);
try
ComObj:=TDemoCom.Create(nil);
ComObj.QueryData(sData,aData);
Result:=aData;
finally
CoUnInitialize;
end;
end;
要把dpr中ISAPIApp和ISAPIThreadPool 单元的引用顺序交换过来,先ISAPIAPP,后ISAPITHREADPOOL,这样编译出来的ISAPI WEBSERVICE不会出现这个错误了。
兄弟非常感谢你,因为我也遇到了这样的问题,按你的方法一试,果然很灵,
为表感谢公开我写的一个IsApi的soap的代码,不要见效:
unit DxServerImpl;interfaceuses InvokeRegistry, Types, XSBuiltIns, DxServerIntf,sysinfo, usercatalog,
userinfo,usercube,SysUtils,Windows;const
UserFile ='userinfo.xml' ;
SysFile ='sysinfo.xml';
CatalogFile='usercatalog.xml';
CubeFile ='usercube.xml';type { TDxServer }
TDxServer = class(TInvokableClass, IDxServer)
public
//////////////////////////////////////////
function CheckUserExist(user:string):boolean;stdcall;//¼ì²âÓû§ÊÇ·ñ´æÔÚ
function CheckUserPass(user,pass:string):boolean;stdcall;//ÃÜÂëÊÇ·ñÕýÈ·£»
function UpdateUserPass(user,pass:string):boolean;stdcall;//ÐÞ¸ÄÓû§ÃÜÂë
function GetUserCatalogs(user:string):TstringDynArray;stdcall;//È¡µÃÓû§µÄÊý¾Ý¿â
function GetUserCubes(user,catalog:string):TstringDynArray;stdcall;//È¡µÃÓû§µÄÁ¢·½Ìå
function AddUserCatalog(user,catalog:string):Boolean; stdcall;
function AddUserCube(user,catalog,cube:string):boolean;stdcall;
procedure DelUserCatalog(user,catalog:string); stdcall;
procedure DelUserCube(user,catalog,cube:string); stdcall;
////////////////////////////////////////////
function GetUserSysID(user:string):string;stdcall;
function GetSysPass(sysid:string):string;stdcall;
function GetUserSysInfo(user,sysid,syspass:string):boolean;stdcall;
function SetSysPass(sysid,syspass:string):Boolean;stdcall;
function AddSysMember(sysid,syspass:string):boolean;stdcall;
procedure DelSysMember(sysid:string); stdcall;
////////////////////////////////////////////////
function Test:string;stdcall;
////////////////////////////////////////////////
function GetSysInfoData: IXMLSysInfoType;
function GetCatalogData:IXMLUserCatalogType;
function GetCubeData:IXMLUserCubeType;
function GetUserInfoData:IXMLUserInfoType;
////////////////////////////////////////////////
end;
function GetDataDir:string;
function GetFile(const FileName:string):string;
/////////////////////////
function GetDataDir:string;
var
S: string;
P:Pchar;
begin
SetLength(S, 255); // when casting to a PChar, be sure the string is not empty
SetLength(S, GetModuleFilename(Hinstance , PChar(S), Length(S) ) );
P := StrRScan(pchar(S), '\');
if P = nil then
begin
P := StrRScan(pchar(S), ':');
if P = nil then P := pchar(S);
end;
if p<>nil then
SetLength(S,Length(S)-strLen(p)+1);
// S:=S+'data\';
Result:=S; end;
function GetFile(const FileName:string):string;
begin
Result :=GetDataDir+FileName;
//Result:=ExtractFileName(FileName); HMODULE
end;{ TDxServer }
////////////////////////
//
////////////////////////
function TDxServer.AddSysMember(sysid,syspass: string): boolean;
var
XMLData:IXMLSysInfoType;
XMLMember:IXMLDxSysesType;
begin
Result :=False;
try
XMLData:=GetSysInfoData;
XMLMember:=XMLData.Add ;
XMLMember.SysID:=sysid;
XMLMember.SysPass:=syspass;
XMLData.OwnerDocument.SaveToFile(SysFile);
Result:=True;
except
end;end;function TDxServer.AddUserCatalog(user,catalog: string): Boolean;
var
XMLData:IXMLUserCatalogType;
XMLMember:IXMLDxCatalogsType;
i:integer;
flag:Boolean;
begin
flag :=False;
XMLData:=GetCatalogData;
for i:=0 to XMLData.Count-1 do
begin
XMLMember:=XMLData.DxCatalogs[i];
if XMLMember.UserName=user then
begin
XMLMember.Add(catalog);
flag:=True;
break;
end;
end;
if not flag then
begin
XMLMember:=XMLData.Add;
XMLMember.UserName:=user;
XMLMember.Add(catalog);
flag:=True;
end;
XMLData.OwnerDocument.SaveToFile(GetFile(CatalogFile));
Result:=flag;end;function TDxServer.AddUserCube(user, catalog, cube: string): boolean;
var
XMLData:IXMLUserCubeType;
XMLMember:IXMLDxCubesType;
i:integer;
flag:Boolean;
begin
flag :=False;
XMLData:=GetCubeData;
for i:=0 to XMLData.Count-1 do
begin
XMLMember:=XMLData.DxCubes[i];
if (XMLMember.UserName= user) and (XMLMember.CatalogName=catalog) then
begin
XMLMember.Add(cube);
flag:=True;
break;
end;
end;
if not flag then
begin
XMLMember:=XMLData.Add ;
XMLMember.UserName :=user;
XMLMember.CatalogName:=catalog;
XMLMember.Add(cube);
flag:=True;
end;
XMLData.OwnerDocument.SaveToFile(Getfile(CubeFile));
Result:=flag;
end;
var
XMLData:IXMLUserInfoType;
XMLMember:IXMLDxUsersType;
i:integer;
begin
Result :=False;
XMLData:=GetUserInfoData;
for i:=0 to XMLData.Count-1 do
begin
XMLMember:=XMLData.DxUsers[i];
if XMLMember.UserName=user then
Result:=True;
Exit;
end;
end;function TDxServer.CheckUserPass(user, pass: string): boolean;
var
XMLData:IXMLUserInfoType;
XMLMember:IXMLDxUsersType;
i:integer;
begin
Result :=False;
XMLData:=GetUserInfoData;
for i:=0 to XMLData.Count-1 do
begin
XMLMember:=XMLData.DxUsers[i];
if (XMLMember.UserName=user) and (XMLMember.PassWord=pass)then
Result:=True;
Exit;
end;
end;procedure TDxServer.DelSysMember(sysid: string);
var
XMLData:IXMLSysInfoType;
//XMLMember:IXMLDxSysesType;
i:integer;
begin
XMLData:=GetSysInfoData;
for i:=0 to XMLData.Count-1 do
begin
if XMLData.DxSyses[i].SysID=sysid then
XMLData.Delete(i);
end;
XMLData.OwnerDocument.SaveToFile(GetFile(SysFile));
end;procedure TDxServer.DelUserCatalog(user, catalog: string);
var
XMLData:IXMLUserCatalogType;
// XMLMember:IXMLDxCatalogsType;
i,k:integer;
begin
XMLData:=GetCatalogData;
for i:=0 to XMLData.Count-1 do
begin
if XMLData.DxCatalogs[i].UserName=user then
begin
for k:=0 to XMLData.DxCatalogs[i].Count-1 do
if XMLData.DxCatalogs[i].CatalogName[k]=catalog then
begin
XMLData.DxCatalogs[i].Delete(k);
break;
end;
break;
end;
end;
XMLData.OwnerDocument.SaveToFile(GetFile(CatalogFile));
end;procedure TDxServer.DelUserCube(user,catalog, cube: string);
var
XMLData:IXMLUserCubeType;
i,k:integer;
begin
XMLData:=GetCubeData;
for i:=0 to XMLData.Count-1 do
begin
if (XMLData.DxCubes[i].UserName =user)
and (XMLData.DxCubes[i].CatalogName=catalog) then
begin
for k:=0 to XMLData.DxCubes[i].Count-1 do
begin
if XMLData.DxCubes[i].CubeName[k]=cube then
XMLdata.DxCubes[i].Delete(k);
break;
end;
break;
end;
end;
XMLData.OwnerDocument.SaveToFile(GetFile(CubeFile));
end;function TDxServer.GetCatalogData: IXMLUserCatalogType;
begin
if FileExists(GetFile(CatalogFile)) then
Result:=LoadUserCatalog(GetFile(CatalogFile))
else
Result:=NewUserCatalog;
end;function TDxServer.GetCubeData: IXMLUserCubeType;
begin
if FileExists(GetFile(CubeFile)) then
Result:=LoadUserCube(GetFile(CubeFile))
else
Result:=NewUserCube;
end;function TDxServer.GetSysInfoData: IXMLSysInfoType;
begin
if FileExists(GetFile(SysFile)) then
Result:=LoadSysInfo(GetFile(SysFile))
else
Result:=NewSysInfo;
end;function TDxServer.GetSysPass(sysid: string): string;
var
XMLData:IXMLSysInfoType;
i:integer;
begin
Result:='';
XMLData:=GetSysInfoData;
for i:=0 to XMLData.Count-1 do
begin
if XMLData.DxSyses[i].SysID=sysid then
begin
Result:=XMLData.DxSyses[i].SysPass;
Exit;
end;
end;
end;function TDxServer.GetUserCatalogs(user: string): TstringDynArray;
var
XMLData:IXMLUserCatalogType;
i,k,Size:integer;
begin try
SetLength(Result,0);
XMLData:=GetCatalogData;
for i:=0 to XMLData.Count-1 do
begin
if XMLData.DxCatalogs[i].UserName=user then
begin
for k:=0 to XMLData.DxCatalogs[i].Count-1 do
begin
Size:=Length(Result)+1;
SetLength(Result,Size);
Result[Size-1]:=XMLData.DxCatalogs[i].CatalogName[k];
end;
break;
end;
end;
except
SetLength(Result,0);
end;
end;function TDxServer.GetUserCubes(user, catalog: string): TstringDynArray;
var
XMLData:IXMLUserCubeType;
i,k,Size:integer;
begin
try
SetLength(Result,0);
XMLData:=GetCubeData;
for i:=0 to XMLData.Count-1 do
begin
if (XMLData.DxCubes[i].UserName=user)
and (XMLData.DxCubes[i].CatalogName=catalog) then
begin
for k:=0 to XMLData.DxCubes[i].Count-1 do
begin
Size:=Length(Result)+1;
SetLength(Result,Size);
Result[Size-1]:=XMLData.DxCubes[i].CubeName[k];
end;
break;
end;
end;
except
SetLength(Result,0);
end;end;function TDxServer.GetUserInfoData: IXMLUserInfoType;
begin
if FileExists(GetFile(UserFile)) then
Result:=LoadUserInfo(GetFile(UserFile))
else
Result:=NewUserInfo;
end;function TDxServer.GetUserSysID(user: string): string;
var
XMLData:IXMLUserInfoType;
i:integer;
begin try
XMLData:=GetUserInfoData;
for i:=0 to XMLData.Count-1 do
begin
if XMLData.DxUsers[i].UserName=user then
Result:=XMLData.DxUsers[i].SysID;
Exit;
end;
except
Result:='';
end;
end;function TDxServer.GetUserSysInfo(user, sysid, syspass: string): boolean;
begin
try
sysid:=GetUserSysId(user);
syspass:=GetSysPass(sysid);
Result:=True;
except
Result:=False;
end;
end;function TDxServer.SetSysPass(sysid, syspass: string): Boolean;
var
XMLData:IXMLSysInfoType;
i:integer;
begin
XMLData:=GetSysInfoData;
for i:=0 to XMLData.Count-1 do
begin
if XMLData.DxSyses[i].SysID=sysid then
begin
XMLData.DxSyses[i].SysPass:=syspass;
break;
end;
end;
XMLData.OwnerDocument.SaveToFile(GetFile(SysFile));
Result:=True;
end;function TDxServer.Test: string;
begin
Result:=GetFile(UserFile);
end;function TDxServer.UpdateUserPass(user, pass: string): boolean;
var
XMLData:IXMLUserInfoType;
i:integer;
begin
//Result:=False;
XMLData:= GetUserInfoData;
for i:=0 to XMLData.Count-1 do
begin
if XMLData.DxUsers[i].UserName =user then
begin
XMLData.DxUsers[i].PassWord:=pass;
break;
end;
end;
XMLData.OwnerDocument.SaveToFile(GetFile(UserFile));
Result:=True;
end;initialization
{ Invokable classes must be registered }
InvRegistry.RegisterInvokableClass(TDxServer);end.
呵呵,佩服你的钻研精神,先谢了