李维关于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;

解决方案 »

  1.   

    上述错误是出现在调用ISAPI的WEBSERVICE(DLL),WAD WEBSERVICE没有这个问题。
      

  2.   

    没有,绝对没有,而且跟数据量大小没关系,无论数据多少,调用ISAPI 的这个WEBSERVICE都会出现这个问题
      

  3.   

    WAD WEBSERVICE也有这种错误提示
      

  4.   

    txinfo ,WAD WebService没有,我用循环测试,不存在这个问题
      

  5.   

    终于找到原因了,这个不是HTTPRIO的原因,而是ISAPI Web Service的问题,
    要把dpr中ISAPIApp和ISAPIThreadPool 单元的引用顺序交换过来,先ISAPIAPP,后ISAPITHREADPOOL,这样编译出来的ISAPI WEBSERVICE不会出现这个错误了。
      

  6.   

    多谢sxgs,只是我奇怪你为什么会知道这城的问题?
      

  7.   

    to sxgs (sxgs) :
    兄弟非常感谢你,因为我也遇到了这样的问题,按你的方法一试,果然很灵,
    为表感谢公开我写的一个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;
      

  8.   

    implementation
      /////////////////////////
      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;
      

  9.   

    function TDxServer.CheckUserExist(user: 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 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.
      

  10.   

    sxgs(sxgs)
    呵呵,佩服你的钻研精神,先谢了
      

  11.   

    其实这个解决方案也不行。因为这样,服务器便不会为多个请求同时服务。这个问题的原因是多线程的处理问题。解决方案是自建一个单元,代码从Delphi6的ThreadPool文件里复制过来,然后把Delphi7的ThreadPool给替换掉,这样便完美了。