关于soap调用ISAPI出现编码错误问题,请大侠们一定要捧场哦!(200分)

  • 主题发起人 主题发起人 skyon
  • 开始时间 开始时间
S

skyon

Unregistered / Unconfirmed
GUEST, unregistred user!
我的系统架构模式是:
Soap Client -> Soap Server -> ISAPI -> COM+ -> Database
在通过接口调用ISAPI时,出现了以下错误:
“Received content of invalid Content-Type setting:text/html
- Soap expects "text/xml"”
调用接口代码如下:
var
aIntf: IISAPIService;
vData: Variant;
begin
HTTPRIO1.HTTPWebNode.UseUTF8InHeader := True;
HTTPRIO1.WSDLLocation := 'http://137.21.1.31/Scripts/ISAPITest.dll/wsdl/IISAPIService';
HTTPRIO1.Service := 'IISAPIServiceservice';
HTTPRIO1.Port := 'IISAPIServicePort';
aIntf := HTTPRIO1 as IISAPIService;
try
aIntf.QueryData('select * from g_codelist', vData);
Self.ClientDataSet1.XMLData := vData;
finally
aIntf := nil;
end;
end;
高分求救大侠们帮忙,谢谢!
 
原来好的吗?
是不是装了其他的软件,如MSTOOLKIT3。0
参看1456571
 
是不是IIS运行环境太低了,或是XML解析器坏了
 
[8D]我的开发环境是:Windows 2000 Professional + Delphi 7 + PWS
应该不是其他工具引起的,因为我没安装其他工具,我运行的程序在本机是好的,但是在
其它机器进行远程调用本机时出现了上述问题,而且还有一个奇怪的现象。就是一次成功,
一次失败交替出现,错误信息就是:
“Received content of invalid Content-Type setting:text/html
- Soap expects "text/xml"”
我想可能是什么地方属性没有设置正确,要么就是Delphi的Bug,在Delphi 6中确实有这个
Bug,但我想Delphi 7应该是进行了改进,不应该还有这个问题,请哪位碰到类似问题的
朋友给我指点一下好吗?我的Email:apollo@skyon.com.cn
 
PWS支持XML吗,我的程序又一次运行在没有Service Pack2的2000server上都不行,
装了XML4.0和Service Pack2、IE6后就没事了,也不知道是哪个版本不对,你可以
试试
 
这是我COM+中一个模块的代码,就是得到返回的XML格式的数据,
用了AnsiToUtf8函数进行编码后,出现了乱码,所以不能用这个函数。
各位大虾还有什么好的办法吗?
procedure TDelphi7ADOServer.QueryMyData(const sSQLCommand: WideString;
var vData: OleVariant);
begin
with Self.ClientDataSet1do
begin
Active := False;
CommandText := sSQLCommand;
try
Active := True;
try
vData := XMLData;
finally
Active := False;
end;
SetComplete;
except
on Exceptiondo
SetAbort;
end;
end;
end;
 
把vData用BASE64编码,然后压缩一下。客户端收到后解压缩,然后解码。试一试。
我做的WS返回一个XML时就是这么做的,不过服务器没用clientdataset,xml文件是手工生成
的标准XML,客户段收到后再解析。
 
怎样进行手工编码生成XML?我的记录是从数据库中获取的,能把范例发给我看看吗?
要是解决了,你将得到所有的积分,谢谢:)
 
1、生成XML的例子
function TBSCWS.GetBUYDS(Search_Condition: string): String;
var ts:Tstringlist;
begin
ts:=Tstringlist.Create;
ts.Add ('<?xml version="1.0"?>');
ts.add('<!--购货数据-->');
ts.add('<BILLS>');
with dm1.INFOS_QUERYdo
begin
sql.Text :='select Bill_id,Coal_id,Vehicle_count,mark_weight,trim_weight,buy_date,rs_id,vehicle_number from tlb_buy '+Search_condition+' order by bill_ID';
open;
while not eofdo
begin
ts.add('<BILL BILL_ID="'+fieldbyname('bill_id').asstring+'">');
ts.add('<BUY_DATE>'+formatdatetime('yyyy-mm-dd',fieldbyname('BUY_DATE').AsDateTime) +'</BUY_DATE>');
ts.add('<RS_ID>'+fieldbyname('RS_ID').AsString +'</RS_ID>');
ts.add('<COAL_ID>'+fieldbyname('coal_id').AsString+'</COAL_ID>');
ts.add('<VEHICLE_COUNT>'+fieldbyname('vehicle_count').AsString +'</VEHICLE_COUNT>');
ts.add('<MARK_WEIGHT>'+fieldbyname('MARK_weight').AsString +'</MARK_WEIGHT>');
ts.add('<TRIM_WEIGHT>'+fieldbyname('trim_weight').AsString +'</TRIM_WEIGHT>');
ts.add('<PAL>'+currtostr(fieldbyname('trim_weight').AsCurrency-fieldbyname('MARK_weight').AsCurrency)+'</PAL>');
ts.add('<VEHICLE_NUMBER>'+fieldbyname('VEHICLE_NUMBER').AsString +'</VEHICLE_NUMBER>');
ts.add('</BILL>');
next
end;
close;
end;
ts.add('</BILLS>');
result:=xttocompressSoapPacket(ts.DelimitedText);
ts.Free;
end;

解释,根据表生成XML,需注意的是XML是大小写敏感的。
2、用到的函数库,我用的是李维那本SOAP书里带的库
unit uSoapPacketComUnCompressor;
interface
uses
SysUtils, Classes;
function XTToCompressSoapPacket(const spPacket: string): string;
function XTToUnCompressSoapPacket(const spPacket: string): string;
function XTCompressedSize(const spPacket: string): Integer;
implementation
uses Zlib, EncdDecd;
function XTToCompressSoapPacket(const spPacket: string): string;
var
msCompressed : TMemoryStream;
zlibCompressor : TCompressionStream;
ssData : TStringStream;
begin
msCompressed := TMemoryStream.Create;
ssData := TStringStream.create('');
try
zlibCompressor := TCompressionStream.Create(clDefault,
msCompressed);
zlibCompressor.Write(spPacket[1], length(spPacket));
finally
FreeAndNil(zlibCompressor);
end;
try
msCompressed.Position := 0;
EncodeStream(msCompressed, ssData);
Result := sSData.Datastring;
finally
FreeAndNil(msCompressed);
FreeAndNil(ssData);
end;
end;

function XTToUnCompressSoapPacket(const spPacket: string): string;
var
msData : TMemoryStream;
msEncoded : TMemoryStream;
zlibUnCompressor : TDeCompressionStream;
fBufLen : integer;
fBuffer : array[0..16383] of byte;
begin
msData := TMemoryStream.create;
msEncoded := TMemoryStream.create;
try
msData.size := length(spPacket);
move(spPacket[1], msData.memory^, msData.size);
msData.position := 0;
DecodeStream(msData, msEncoded);
msData.size := 0;
msEncoded.position := 0;
zlibUnCompressor := TDeCompressionStream.create(msEncoded);
try
fBufLen := zlibUnCompressor.Read(fBuffer, SizeOf(fBuffer));
while fBufLen > 0do
begin
msData.Write(fBuffer, fBufLen);
fBufLen := zlibUnCompressor.Read(fBuffer, SizeOf(fBuffer));
end;
finally
FreeAndNil(zlibUnCompressor);
end;
msData.position := 0;
SetLength(Result, msData.size);
move(msData.memory^, Result[1], msData.size);
finally
FreeAndnil(msEncoded);
FreeAndNil(msData);
end;
end;

function XTCompressedSize(const spPacket: string): Integer;
var
msCompressed : TMemoryStream;
zlibCompressor : TCompressionStream;
begin
msCompressed := TMemoryStream.Create;
try
zlibCompressor := TCompressionStream.Create(clDefault,
msCompressed);
zlibCompressor.Write(spPacket[1], length(spPacket));
finally
FreeAndNil(zlibCompressor);
end;
try
msCompressed.Position := 0;
Result := msCompressed.Size;
finally
FreeAndNil(msCompressed);
end;
end;
end.
3、客户端接收到数据后的处理
procedure TBuyListForm.Button1Click(Sender: TObject);
var
ts:Tstringlist;
s:string;
begin
screen.Cursor:=crhourglass;
try
clientdataset1.Close;
ts:=Tstringlist.Create;
s:=bsc.GetBUYDS(' where year(buy_date)='+inttostr(year)+' and '
+'month(buy_date)='+inttostr(month));
ts.DelimitedText:=AnsiToUtf8(xtTOUncompressSoapPacket(s));
ts.SaveToFile(extractfilepath(application.ExeName)+'temp/buytemp.xml');
XmlTp.XMLDataFile:=extractfilepath(application.ExeName)+'temp/buytemp.xml';
XmlTp.TransformRead.TransformationFile:=extractfilepath(application.ExeName)+'xml/buy_todp.xtr';
clientdataset1.Open;
label1.Caption :=inttostr(year)+'年'+inttostr(month)+'月';
finally
ts.Free;
screen.Cursor :=crdefault;
end;
end;
解释
ts.DelimitedText:=AnsiToUtf8(xtTOUncompressSoapPacket(s));
将收到后的数据解压缩并UTF8编码。xtTOUncompressSoapPacket为解码并解压缩函数。
ts.SaveToFile(extractfilepath(application.ExeName)+'temp/buytemp.xml');
保存临时文件
XmlTp.XMLDataFile:=extractfilepath(application.ExeName)+'temp/buytemp.xml';
XmlTp.TransformRead.TransformationFile:=extractfilepath(application.ExeName)+'xml/buy_todp.xtr';
clientdataset1.Open;
根据临时文件解析XML到DATASET,这里你需要使用DELPHI带的XML MAPPER工具,生成一个TODP
的XMLTRANSFORMATIONFILE(就是如何把XML映射到数据集的文件)
这里的XMLTP是一个XML TRANSFORMPROVIDER控件,在DATA ACCESS面板上。CLIENTDATASET的
ProviderName就设为它。
bsc:是WEBSERVICE的接口
4、这个数据的流程为
数据库-->xml-->压缩并编码-->通过HTTP传递到客户-->解码并解压缩-->到临时文件-->通过 XmlTransformProvider解析并向clientDataset提供数据。
 
还是有同样的问题,不过还是谢谢你,为你加分吧!
我想可能是由于我使用了ISAPI调用COM+的问题,所以我决定不用COM+来实现,直接封装在
ISAPI中调用,李维那本书我没看完,所以还有很多技巧没有掌握,都怪自己学艺不精呀,
再次谢谢你!
 
后退
顶部