前言:
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; }