Delphi 读取 c# webservice XML的base64编码图片字符串转化图片并显示 在 开发中遇到应用c#及asp.net的在的webservice 保存图片并以xml文件形式现实出来 并用delphi调用 的方法: 1.c#的webservice现实见 http://www.greensoftcode.net/techntxt/20127118441582992373 之前的文章。 2.在客户端用delphi显示 发现asp.net xml形式输出的图片是base64字符串形式。用delphi解析很困难 所以这里我先用c#解析读取图片并显示 然后在用delphi显示主要看看显示的xml图片是否可以显示。 c#的代码是: private void button1_Click(object sender, System.EventArgs e) { long len; byte[] byt = new byte[] { 0x00 }; //string base64String=Convert.ToBase64String(this.textBox1.Text); byt=Convert.FromBase64String(this.textBox1.Text); string str = System.Text.Encoding.Default.GetString( byt ); System.IO.MemoryStream ms=new System.IO.MemoryStream(); ms.Write(byt, 0, byt.Length) ; ms.Seek(0, System.IO.SeekOrigin.Begin) ; len=ms.Length; pictureBox1.Image = Image.FromStream(ms) ; } 图片显示没有问题!这就证明啦asp.net webservice 以XML字符串显示图片没有问题 ,只要delphi的 算法正确就可以。 3.下面用delphi实现说实话我研究啦很长时间终于研究出来啦 结果见: 先引用 EncdDecd单元 EncdDecd单元是delphi自带的 uses EncdDecd var ss:TStringStream; ms:TMemoryStream; JpgFile:TjpegImage ; begin ss:=TStringStream.Create(Memo1.Text); ms:=TMemoryStream.Create; DecodeStream(ss,ms); ms.Position:=0; JpgFile:=TjpegImage.Create ; JpgFile.LoadFromStream(ms); ss.Free; ms.Free; Image1.Picture.Bitmap.Assign(JpgFile); end; 就这样就可以读出c#的webservice 的图片文件
-
delphi读取asp.net webservice 中dataset数据集数据的的方法,并且与dbgrid的绑定
delphi读取asp.net webservice 中dataset数据集数据的的方法并且与dbgrid的绑定 delphi 访问c#中webservice 的函数如果不带dataset数据表那么不是很复杂! 如果访问返回表的函数相对就复杂啦些! 下面我讲下如何用delphi访问c#些的webservice函数 1.web端函数为: [WebMethod] public string gettable(int pageIndex , int pageSize , out int recordCount, out int pageCount ,string keyword) { recordCount=0; pageCount=0; DataTable tb=null; DataSet ds=new DataSet(); if (Validate()) { try { a App=new Pa() ; tb=App.gettable( pageIndex , pageSize , out recordCount, out pageCount , keyword ); } catch { } ds.Tables.Add(tb); } //这里不要return ds; 因为delphi识别C#的webservice函数XMl文档很费劲 所以采用下面的方法 System.Text.StringBuilder strbuilder=new System.Text.StringBuilder(); StringWriter writer=new StringWriter(strbuilder); ds.WriteXml(writer,System.Data.XmlWriteMode.IgnoreSchema); return strbuilder.ToString(); } 2.客户端 SOAP定义端 procedure Sev_gettable(const pageIndex: Integer; const pageSize: Integer; const keyword: WideString; out gettableResult: WideString; out recordCount: Integer; out pageCount: Integer); stdcall; //注意这是个过程不是函数 它的返回值是通过OUT输出参数做到的。 soap定义可以通过DELPHI建立 FILE-new-other-webservice -wsdl impoerts建立这个类把这个类文件加载到你的工程里就OK啦 function Sev_gettable(const pageIndex: Integer; const pageSize: Integer; const keyword: WideString,out recordCount: Integer; out pageCount: Integer): WideString; var HTTPRio : THTTPRIO ; Ahttprio: ClientServiceSoap; val: WideString; begin HTTPRio:= THTTPRIO.Create(Application); Try HTTPRio.WSDLLocation:=''http://www.xxx.com/abc/getab.asmx?wsdl''; Ahttprio := (HTTPRio as Cli entServiceSoap); Ahttprio.gettable( pageIndex, pageSize,keyword,val, recordCount, pageCount) ; Ahttprio:=nil; Pointer(Ahttprio) := nil; soapHeader.Free; finally End; Result:=val; End; 那么通过上面的函数我们可以获得xml数据集文档 下面就对这个文档进行分析与数据的提取 我们建立一个FORM1在上面加入 Tstringlist控件 为什么用 Tstringlist控件不用Tdbgrid能 因为 Tstringlist可以自由的编写行和列 与tdbgrid绑定数据表效果一样 看实现函数 //读取xml数据集到stringlist中 //这个xmlstr参数 就是我们上面函数 Sev_gettable获得asp.ent webservice 返回的数据集 procedure iningrd(strdrg:TStringGrid;xmlstr:string); var fieldval: string; node: IXMLNode; XMLDoc:TXMLDocument; nodeList: IXMLNodeList; nodecount,i,j:integer; begin for i:=0 to strdrg.rowcount-1 do for j:=0 to strdrg.colcount-1 do strdrg.Cells[j,i]:= ''; strdrg.Cells[0,0]:='编号'; strdrg.Cells[1,0]:='类型'; strdrg.Cells[2,0]:='状态'; strdrg.Cells[3,0]:='工号'; strdrg.Cells[4,0]:='姓名'; strdrg.Cells[5,0]:='电话'; strdrg.Cells[6,0]:='所收'; strdrg.Cells[7,0]:='姓名'; strdrg.Cells[8,0]:='电话'; strdrg.Cells[9,0]:='姓名'; strdrg.Cells[10,0]:='电话'; strdrg.Cells[11,0]:='所属'; strdrg.Cells[12,0]:='日期'; strdrg.ColWidths[0]:=100; strdrg.ColWidths[1]:=56; strdrg.ColWidths[2]:=62; strdrg.ColWidths[3]:=70; strdrg.ColWidths[4]:=65; strdrg.ColWidths[5]:=100; strdrg.ColWidths[6]:=120; strdrg.ColWidths[7]:=120; strdrg.ColWidths[8]:=120; strdrg.ColWidths[9]:=80; strdrg.ColWidths[10]:=80; strdrg.ColWidths[11]:=120; strdrg.ColWidths[12]:=120; XMLDoc:=TXMLDocument.Create(Application); XMLDoc.XML.Text:=xmlstr; XMLDoc.Active:=true; nodecount:=XMLDoc.DocumentElement.ChildNodes.Count; for i:=0 to nodecount -1 do begin node := XMLDoc.DocumentElement.ChildNodes[i]; nodeList := node.ChildNodes; for j := 0 to nodeList.Count - 1 do begin //fieldval:= nodeList[j].NodeName; if nodeList[j].IsTextElement then begin fieldval := nodeList[j].NodeValue; strdrg.Cells[j,i+1]:=fieldval; end; end; end; end; 这个现实过程是我通过实践测试成功的 !基本方法全部给出只有你稍加改动就可以现实 !遇到错误不要放弃!
由于项目需要为包括c/s和b/s的多个平台提供统一业务逻辑,写个webservice来完成这个任务,通过webservice封装业务逻辑,为其他平台提供接口,以供调用,于是用delphi写一个webservice,起初没有任何采用任何编码,当然在调用的时候delphi客户端可以正常传输数据,c#网页部分调用却是乱码,肯定是两种语言的编码方式问题,引起的乱码,原因有了,最终也没有想到解决的办法。所以想两端提供一种统一的编码,通过编码和解码来达到编码方式的统一,这样应该就不会有乱码的问题了吧,我选择base64编码方式,base64在网络上良好的性能,这是满足这个所需要的,又折腾了一阵子,终于完成了,各个平台数据的统一,测试代码如下: 1 delphi 部分 : unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,EncdDecd; type TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; Button1: TButton; Button2: TButton; Edit3: TEdit; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var s:AnsiString; begin s:=edit1.text; edit2.Text:= EncodeString((s)); // 超越软件 http://www.cyhlw.com end; procedure TForm1.Button2Click(Sender: TObject); begin edit3.Text:= DecodeString(edit2.text) end; end. 2 c# 部分: using System; using System.Configuration; using System.Data; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Text; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //Response.ContentEncoding = System.Text.Encoding.GetEncoding( "GB2312" ); } protected void Button1_Click(object sender, EventArgs e) { string str=""; localhost.IIHelloservice oserver = new localhost.IIHelloservice(); str=oserver.sayHello("超越软件 http://www.cyhlw.com"); //localhost.WebService1 oService = new localhost.WebService1(); //Label1.Text = oService.About(); this.TextBox1.Text = str; byte[] bytes = System.Convert.FromBase64String(str); str = ""; str = Encoding.Default.GetString(bytes); TextBox2.Text = str; //TextBox1.Text=Encoder.get //byte[] bytes //this.TextBox1.Text = Sys
Base64 三种语言间的加解密问题(delphi、C#、Java)
1. delphi 需要引用EncdDecd单元.
oStream:= TStringStream.Create(sBase64Str); try oStream.Position := 0; oMStream := TMemoryStream.Create; try EncdDecd.DecodeStream(oStream, oMStream); //对二维码进行解base64, EncdDecd为delphi自带的base64单元 oMStream.Position := 0; oMStream.SaveToFile('D:/base64Pic.jpg'); //保存二维码图片 finally oMStream.Free; end; finally oStream.Free; end;
2. C# 调用代码
byte[] imgData = System.Convert.FromBase64String(sBase64Str); //解bas464字符串 FileStream fs = new FileStream("D://OutPic.jpg", FileMode.CreateNew); fs.Write(imgData, 0, (int)imgData.Length); fs.Close(); pictureBox1.Load("D://OutPic.jpg");3. java java的解决办法其实也很简单,把base64字符串的(大括号内的内容) { 
 }全部替换为空即可,即换行符,上代码:
FileInputStream fis = new FileInputStream("d:/base64Img.txt"); int size = fis.available(); byte[] buffer = new byte[size]; fis.read(buffer, 0, size); fis.close(); String tmp = new String(buffer); tmp = tmp.replaceAll("
", ""); byte[] outData = Base64.decodeBase64(tmp); FileOutputStream fos = new FileOutputStream("D:/aaa.jpg"); fos.write(outData, 0, outData.length); fos.close();
在网上看到相关的资料,说的是java中加密生成base64串,delphi在解密base64时需要替换掉换行符,现在却反了过来,不知道是java改了还是delphi 改了。对了,delphi使用的版本为delphi XE1, C# 为 VS2010。