前言:
1、公司delphi7開發的傳統軟件還活得好好的,但是大家都知道delphi早已經日落西山了,現在成了后進、追隨者。細細算了已經6、7不用了。新的delphixe7呢,沒有時間成本去適應和研究。
由於大量使用了第3方的組件和控件,想升級估計是吃力不討好的事情...
2、保留原有代碼,開發新功能可調用遠程主機(雲主機)的REST ful風格的api,使用Json交換數據。這樣就趕上了新潮流,復活了。
由於網上搜索了很多次,發現符合需求的文章很少,這里記錄下來,授人以魚吧。
- delphi7使用Json
- delphi7使用msxml 的“IXMLHttpRequest”對象實現發起 Http post get請求,並傳遞Json。
- delphi7使用base64編碼圖片通過Json傳遞
以下是關鍵代碼:
(1)msxml,SuperObject(第3方,delphi7不自帶), EncdDecd 的引用
(2)XMLHttpRequest的使用:
//提交會員開卡信息
procedure TFormMakeCard.btnOKClick(Sender: TObject);
var
url: string;
resultJson,paramsJson: ISuperObject;
begin
if (CheckInput) then
begin
HttpReq := CoXMLHTTPRequest.Create;
//兩種提交請求的方式:Get和Post,Get是通過URL地址傳遞參數如果是中文需要轉碼,需要添加時間戳 Post不需要添加時間戳
//get url := 'http://localhost:5269/api/webmemberapi/NewMemberRegister?timestamp='+inttostr(Windows.GetTickCount);
url := 'http://localhost:5269/api/webmemberapi/NewMemberRegister?';
HttpReq.open('Post', url, False, EmptyParam, EmptyParam);
//http post
HttpReq.setRequestHeader('Accept', 'application/json');
HttpReq.setRequestHeader('Content-Type', 'application/json');
//請求主體
try
paramsJson:= GetMemberEntity();
Memo1.Lines.Clear;
memo1.Text := paramsJson.AsString();
HttpReq.send(paramsJson.AsString());
resultJson:=SO(HttpReq.responseText);
if (resultJson<>nil) then
begin
showmessage(resultJson.S['Message']);
//發卡成功,如果有照片或者簽名則執行上傳
if (resultJson.B['Success']=true) then
begin
if (mbPhoto) then
begin
url := 'http://localhost:5269/api/webmemberapi/UploadMemberImage?';
HttpReq.open('Post', url, False, EmptyParam, EmptyParam);
//http post
HttpReq.setRequestHeader('Accept', 'application/json');
HttpReq.setRequestHeader('Content-Type', 'application/json');
paramsJson:=SO();
paramsJson.S['ImageFileContent']:= BitmapToString(ImageMemberPhoto.Picture.Bitmap);
paramsJson.S['ImageCategory']:='頭像';
paramsJson.S['MemberCardNo']:=self.edtCardNo.Text;
HttpReq.send(paramsJson.AsString());
resultJson:=SO(HttpReq.responseText);
end;
if (mbSign) then
begin
url := 'http://localhost:5269/api/webmemberapi/UploadMemberImage?';
HttpReq.open('Post', url, False, EmptyParam, EmptyParam);
//http post
HttpReq.setRequestHeader('Accept', 'application/json');
HttpReq.setRequestHeader('Content-Type', 'application/json');
paramsJson:=SO();
paramsJson.S['ImageFileContent']:= BitmapToString(ImageMemberSign.Picture.Bitmap);;
paramsJson.S['ImageCategory']:='簽名';
paramsJson.S['MemberCardNo']:=self.edtCardNo.Text;
HttpReq.send(paramsJson.AsString());
resultJson:=SO(HttpReq.responseText);
end;
end;
end;
except
on Ex:Exception do
showmessage(Ex.Message);
end;
end;
end;
//XMLHttpRequest實例化
HttpReq := CoXMLHTTPRequest.Create;
//兩種提交請求的方式:Get和Post,Get是通過URL地址傳遞參數如果是中文需要轉碼,需要添加時間戳 Post不需要添加時間戳
//get url := 'http://localhost:5269/api/webmemberapi/NewMemberRegister?timestamp='+inttostr(Windows.GetTickCount);
url := 'http://localhost:5269/api/webmemberapi/NewMemberRegister?';
// Post或者Get
HttpReq.open('Post', url, False, EmptyParam, EmptyParam);
//http post **這是關鍵代碼**RequestHeader的設置'application/json',服務器端才能識別為Json
HttpReq.setRequestHeader('Accept', 'application/json');
HttpReq.setRequestHeader('Content-Type', 'application/json');
//這是請求的主體
HttpReq.send(paramsJson.AsString());
//把服務器返回的Json字符串反序列化成一個SuperObject對象。
resultJson:=SO(HttpReq.responseText);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Com.Aidpoint.MemberApi.Models
{
/// <summary>
/// Action返回值實體
/// </summary>
public class ApiActionResult
{
public bool Success
{
get;
set;
}
public string Message
{
get;
set;
}
public object Result
{
get;
set;
}
}
}
if (resultJson<>nil) then
begin
showmessage(resultJson.S['Message']);
//發卡成功,如果有照片或者簽名則執行上傳
if (resultJson.B['Success']=true) then ...
end
(3)Josn包含base64編碼的圖片:
//位圖文件轉Base64字符串 function TFormMakeCard.BitmapToString(img:TBitmap):string; var ms:TMemoryStream; ss:TStringStream; s:string; begin ms := TMemoryStream.Create; img.SaveToStream(ms); ss := TStringStream.Create(''); ms.Position:=0; EncodeStream(ms,ss);//將內存流編碼為base64字符流 s:=ss.DataString; ms.Free; ss.Free; result:=s; end; url := 'http://localhost:5269/api/webmemberapi/UploadMemberImage?'; HttpReq.open('Post', url, False, EmptyParam, EmptyParam); //http post HttpReq.setRequestHeader('Accept', 'application/json'); HttpReq.setRequestHeader('Content-Type', 'application/json'); paramsJson:=SO(); paramsJson.S['ImageFileContent']:= BitmapToString(ImageMemberPhoto.Picture.Bitmap); paramsJson.S['ImageCategory']:='頭像'; paramsJson.S['MemberCardNo']:=self.edtCardNo.Text; HttpReq.send(paramsJson.AsString()); resultJson:=SO(HttpReq.responseText);
(4)服務器端的web api
public ApiActionResult NewMemberRegister([FromBody]MemberDTO memberDTO)
{
//初始化返回值
var result = new ApiActionResult()
{
Success = false,
Result = null,
Message = "操作失敗。"
};
if (memberDTO != null)
{
try
{
using (MemberEntities db = new MemberEntities())
{
var dbEntity = CheckMemberExists(memberDTO, db);
if (dbEntity==null)
{
//插入會員表
var entity = DTO2Entity.ConvertToEntityObject<會員表>(memberDTO) as 會員表;
db.AddTo會員表(entity);
//生成儲值流水--w:誤收,d:積分兌換禮品,f:發新卡,c:儲值,q:取款,j:積分消費記錄
var detailRec = new 會員儲值流水表();
detailRec.會員卡號 = memberDTO.卡號;
detailRec.儲值標志 = "f";
detailRec.充值金額 = memberDTO.開卡額.Value;
detailRec.新卡 = "Y";
db.AddTo會員儲值流水表(detailRec);
try
{
db.SaveChanges();
result.Success = true;
result.Result = entity;
result.Message = string.Format("操作成功。新發會員卡[{0}],開卡金額:{1}。", entity.自編號, entity.開卡額);
}
catch (Exception ex)
{
var exx = ex.InnerException == null ? ex : ex.InnerException;
throw new Exception(exx.Message);
}
}
else
{
result.Success = false;
result.Result = null;
result.Message = string.Format("卡號[{0}]已經存在。發卡門店[{1}],持卡人:{2}。",dbEntity.自編號,dbEntity.發行分店編號,dbEntity.姓名);
}
}
}
catch (Exception ex)
{
var exx = ex.InnerException == null ? ex : ex.InnerException;
result.Success = false;
result.Result = exx;
result.Message = string.Format("操作異常,異常消息:{0}。", exx.Message);
}
}
return result;
}
