B/S FastReprot使用

来源:https://www.cnblogs.com/wangyq2016/archive/2019/04/17/10724381.html
-Advertisement-
Play Games

FastReport 交流群 群 號:554714044 前言 由於公司開發新產品,前後端分離.netcore +Angular ,之前C/S項目一直使用FastReport ,考慮到員工切換比較困難,而且最最重要的是BS版少了很多內容,例如合計,函數最常用的功能都沒有,所以B/S端列印控制項繼續沿用 ...


 

FastReport 交流群

554714044

前言

由於公司開發新產品,前後端分離.netcore +Angular ,之前C/S項目一直使用FastReport ,考慮到員工切換比較困難,而且最最重要的是BS版少了很多內容,例如合計,函數最常用的功能都沒有,所以B/S端列印控制項繼續沿用C/S模式。

 

一、邏輯視圖

 

二、具體實現

1.Winform設計

如上圖所示,這裡做了一個列印模板與數據源的管理。在這裡可以指定具體頁面要調什麼後端介面,列印什麼數據,列印格式設計。全部WinForm實現。將數據源與列印格式模板存儲到資料庫。後端直接調取即可。

優點:1.與之前WinForm版無縫對接,開發人員不用學習即可使用。

2.做到數據源與列印格式集中化管理,而且可以根據客戶需求,實施人員自己調整添加列印格式,不需要開發程式。

3.數據源多樣化,可以根據特殊需求,自己拼接sql,也可以直接查詢資料庫表。滿足客戶多樣化,個性化需求。

4.可以根據具體單據ID,調試列印格式。

缺點:WinForm 沒有做成網路版,此設計器只能在伺服器端(內網)使用。(本來設計就是要伺服器設計,下麵的人員用不到,缺點還可以接受

以下是部分代碼

  1       /// <summary>
  2         /// 綁定數據明細
  3         /// </summary>
  4         public void BindGridDts()
  5         {
  6             SReportManageDtsRule rule = new SReportManageDtsRule();
  7             DataTable dtDts = rule.RShow(" AND DMainID=" + SysString.ToDBString(HTDataID) + " ORDER BY DSeq", ProcessGrid.GetQueryField(gridView1));
  8 
  9             gridView1.GridControl.DataSource = dtDts;
 10             gridView1.GridControl.Show();
 11         }
 12 
 13         /// <summary>
 14         /// 新增
 15         /// </summary>
 16         public string EntityAdd()
 17         {
 18             SReportManageRule rule = new SReportManageRule();
 19             SReportManage entity = EntityGet();
 20             SReportManageDts[] entitydts = EntityDtsGet();
 21             SReportFile entityFile = new SReportFile();
 22             if (chkMB.Checked)
 23             {
 24                 entityFile.DContext = HttSoft.WinUIBase.FastReportX.ConvertToBinaryByPath(txtFilePath.Text.Trim());
 25                 entityFile.DFileName = entity.DFileName;
 26             }
 27 
 28             rule.RAdd(entity, entitydts, entityFile);
 29             return entity.DID;
 30         }
 31 
 32         /// <summary>
 33         /// 修改
 34         /// </summary>
 35         public void EntityUpdate()
 36         {
 37             SReportManageRule rule = new SReportManageRule();
 38             SReportManage entity = EntityGet();
 39             SReportManageDts[] entitydts = EntityDtsGet();
 40             SReportFile entityFile = new SReportFile();
 41             if (chkMB.Checked)
 42             {
 43                 entityFile.DID = entity.DFileID;
 44                 entityFile.SelectByID();
 45                 entityFile.DContext = HttSoft.WinUIBase.FastReportX.ConvertToBinaryByPath(txtFilePath.Text.Trim());
 46                 entityFile.DFileName = entity.DFileName;
 47             }
 48 
 49             rule.RUpdate(entity, entitydts, entityFile);
 50         }
 51 
 52         /// <summary>
 53         /// 設置
 54         /// </summary>
 55         public void EntitySet()
 56         {
 57             SReportManage entity = new SReportManage();
 58             entity.DID = HTDataID;
 59             bool findFlag = entity.SelectByID();
 60             drpForm.Text = SysConvert.ToString(entity.DMenuID);
 61             txtReportName.Text = entity.DReportName.ToString();
 62             txtDSeq.Text = entity.DSeq.ToString();
 63             txtAPI.Text = entity.DWebApi.ToString();
 64 
 65             BindGridDts();
 66         }
 67 
 68 
 69         /// <summary>
 70         /// 刪除
 71         /// </summary>
 72         public void EntityDelete()
 73         {
 74             SReportManageRule rule = new SReportManageRule();
 75             SReportManage entity = EntityGet();
 76             rule.RDelete(entity);
 77         }
 78 
 79         #region 自定義方法
 80         /// <summary>
 81         /// 獲得實體
 82         /// </summary>
 83         /// <returns></returns>
 84         private SReportManage EntityGet()
 85         {
 86             SReportManage entity = new SReportManage();
 87             entity.DID = HTDataID;
 88             entity.SelectByID();
 89             entity.DMenuID = SysConvert.ToString(drpForm.Text.Trim());
 90             entity.DReportName = txtReportName.Text.Trim();
 91             entity.DSeq = SysConvert.ToInt32(txtDSeq.Text.Trim());
 92             entity.DWebApi = txtAPI.Text.Trim();
 93             entity.DFileName = txtReportName.Text.Trim() + ".frx";
 94 
 95 
 96             return entity;
 97         }
 98 
 99         /// <summary>
100         /// 獲得實體
101         /// </summary>
102         /// <returns></returns>
103         private SReportManageDts[] EntityDtsGet()
104         {
105 
106             int index = 0;
107             for (int i = 0; i < gridView1.RowCount; i++)
108             {
109                 if (SysConvert.ToString(gridView1.GetRowCellValue(i, "SqlName")) != "")
110                 {
111                     index++;
112                 }
113             }
114             SReportManageDts[] entitydts = new SReportManageDts[index];
115             index = 0;
116             for (int i = 0; i < gridView1.RowCount; i++)
117             {
118                 if (SysConvert.ToString(gridView1.GetRowCellValue(i, "SqlName")) != "")
119                 {
120                     entitydts[index] = new SReportManageDts();
121                     entitydts[index].DMainID = SysConvert.ToString(gridView1.GetRowCellValue(i, "DMainID"));
122                     if (entitydts[index].DMainID == HTDataID && HTDataID != "")//已存在表示修改
123                     {
124                         entitydts[index].DID = SysConvert.ToString(gridView1.GetRowCellValue(i, "DID"));
125                         entitydts[index].SelectByID();
126                     }
127                     else//新增
128                     {
129                         entitydts[index].DMainID = HTDataID;
130                         entitydts[index].DSeq = i + 1;
131                     }
132 
133 
134                     entitydts[index].DMainID = SysConvert.ToString(gridView1.GetRowCellValue(i, "DMainID"));
135                     entitydts[index].DSeq = SysConvert.ToInt32(gridView1.GetRowCellValue(i, "DSeq"));
136                     entitydts[index].DataSourceName = SysConvert.ToString(gridView1.GetRowCellValue(i, "DataSourceName"));
137                     entitydts[index].SqlName = SysConvert.ToString(gridView1.GetRowCellValue(i, "SqlName"));
138                     entitydts[index].SqlStr = SysConvert.ToString(gridView1.GetRowCellValue(i, "SqlStr"));
139                     entitydts[index].QueryName = SysConvert.ToString(gridView1.GetRowCellValue(i, "QueryName"));
140                     entitydts[index].SqlFlag = SysConvert.ToInt32(gridView1.GetRowCellValue(i, "SqlFlag"));
141                     entitydts[index].SourceType = SysConvert.ToInt32(gridView1.GetRowCellValue(i, "SourceType"));
142                     entitydts[index].Remark = SysConvert.ToString(gridView1.GetRowCellValue(i, "Remark"));
143 
144 
145                     index++;
146                 }
147             }
148             return entitydts;
149         }
150 
151         #endregion
152 //添加一個基礎模板
153         private void btnLook_Click(object sender, EventArgs e)
154         {
155             try
156             {
157                 if (HTFormStatus == FormStatus.新增 || HTFormStatus == FormStatus.修改)
158                 {
159                     openFileDialog1.FileName = "";
160                     openFileDialog1.Filter = "(*.frx)|*.frx|(*.fr3)|*.fr3|(*.*)|*.*";
161                     openFileDialog1.ShowDialog();
162                     if (openFileDialog1.FileName != string.Empty)
163                     {
164                         txtFilePath.Text = openFileDialog1.FileName;
165                     }
166                 }
167 
168             }
169             catch (Exception E)
170             {
171                 MessageBox.Show(E.Message);
172             }
173         }
174 //窗體載入
175         private void HSPrintEdit_Load(object sender, EventArgs e)
176         {
177             //Common.BindFormID(drpForm);
178             Common.BindReportSource(drpReportSource, true);
179         }
180 //設計
181         private void btnDesign_Click(object sender, EventArgs e)
182         {
183             try
184             {
185                 if (HTDataID == "")
186                 {
187                     MessageBox.Show("請先保存單據");
188                     return;
189                 }
190                 SReportManage reportManage = new SReportManage();
191                 reportManage.DID = HTDataID;
192                 reportManage.SelectByID();
193                 if (reportManage.DFileID == "")
194                 {
195                     MessageBox.Show("沒有找到列印格式");
196                     return;
197                 }
198 
199 
200 
201                 if (!chksql.Checked)
202                 {
203                     if (SysConvert.ToString(txtDataID.Text.Trim()) == "")
204                     {
205                         MessageBox.Show("請輸入數據源ID");
206                         return;
207                     }
208                     FastReport.ReportRun(HTDataID, (int)ReportPrintType.設計, new string[] { "DID", "DMainID" }, new string[] { SysConvert.ToString(txtDataID.Text.Trim()), SysConvert.ToString(txtDataID.Text.Trim()) });
209                 }
210                 else
211                 {
212                     if (SysConvert.ToString(txtsql.Text.Trim()) == "")
213                     {
214                         MessageBox.Show("請輸入數據源sql");
215                         return;
216                     }
217                     DataTable dt = SysUtils.Fill(txtsql.Text.Trim());
218                     FastReport.ReportRunTable(HTDataID, (int)ReportPrintType.設計, dt);
219                 }
220 
221 
222 
223             }
224             catch (Exception E)
225             {
226                 MessageBox.Show(E.Message);
227             }
228         }
229 //預覽
230         private void btnPreview_Click(object sender, EventArgs e)
231         {
232             try
233             {
234                 if (HTDataID == "")
235                 {
236                     MessageBox.Show("請先保存單據");
237                     return;
238                 }
239                 SReportManage reportManage = new SReportManage();
240                 reportManage.DID = HTDataID;
241                 reportManage.SelectByID();
242                 if (reportManage.DFileID == "")
243                 {
244                     MessageBox.Show("沒有找到列印格式");
245                     return;
246                 }
247 
248                 if (!chksql.Checked)
249                 {
250                     if (SysConvert.ToString(txtDataID.Text.Trim()) == "")
251                     {
252                         MessageBox.Show("請輸入數據源ID");
253                         return;
254                     }
255                     FastReport.ReportRun(HTDataID, (int)ReportPrintType.預覽, new string[] { "DID", "DMainID" }, new string[] { SysConvert.ToString(txtDataID.Text.Trim()), SysConvert.ToString(txtDataID.Text.Trim()) });
256                 }
257                 else
258                 {
259                     if (SysConvert.ToString(txtsql.Text.Trim()) == "")
260                     {
261                         MessageBox.Show("請輸入數據源");
262                         return;
263                     }
264                     DataTable dt = SysUtils.Fill(txtsql.Text.Trim());
265                     FastReport.ReportRunTable(HTDataID, (int)ReportPrintType.預覽, dt);
266                 }
267 
268             }
269             catch (Exception E)
270             {
271                 MessageBox.Show(E.Message);
272             }
273         }
View Code

 

 

  2.MVC端

為了將列印格式發佈出去,這裡特意做了一個mvc的程式,放在前端與後端之間,作為橋梁。

因為客戶端只需要預覽和列印,所以這裡我只做了一個預覽+列印的介面。設計在WinForm端處理,這裡不需要。

以下是Preview的代碼實現。

 1      public ActionResult Preview()
 2         {
 3             webReport = new WebReport();
 4             webReport.Width = Unit.Percentage(100);
 5             webReport.Height = Unit.Percentage(100);
 6 
 7             string DataID = Request.QueryString["id"];
 8 
 9             string ReportID = Request.QueryString["rid"];
10 
11             string token = Request.QueryString["token"];
12 
13             ReportModel model = new ReportModel();
14             model.DataID = DataID;
15             model.ReportID = ReportID;
16 
17             String token2 = "Bearer " + token;
18             HttpClient client = new HttpClient();
19             client.BaseAddress = _baseAddress;
20             client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
21 
22             client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
23             //獲取模板文件地址,獲取列印數據源webapi介面地址
24             #region 獲取模板文件地址,獲取列印數據源webapi介面地址
25             var jsonStr = JsonConvert.SerializeObject(model);
26             HttpContent cont = new StringContent(jsonStr);
27             cont.Headers.ContentType = new MediaTypeHeaderValue("application/json");
28 
29 
30             var returnStr = "";
31             HttpResponseMessage resp = client.PostAsync("/api/SReportManage/getdataurl", cont).Result;//post提交數據,
32             if (resp.IsSuccessStatusCode)
33             {
34                 returnStr = resp.Content.ReadAsStringAsync().Result;
35             }
36             ReportResult dtos = JsonConvert.DeserializeObject<ReportResult>(returnStr);
37 
38             #endregion
39 
40             //獲取列印數據源
41             #region 獲取列印數據源
42 
43 
44             HttpClient client2 = new HttpClient();
45             client2.BaseAddress = _baseAddress;
46             client2.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
47 
48             client2.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
49 
50             var jsonStr2 = JsonConvert.SerializeObject(model);
51             HttpContent cont2 = new StringContent(jsonStr2);
52             cont2.Headers.ContentType = new MediaTypeHeaderValue("application/json");
53 
54             var returnStr2 = "";
55             HttpResponseMessage resp2 = client2.PostAsync(dtos.Data.WebApi, cont2).Result;//post提交數據,
56             if (resp2.IsSuccessStatusCode)
57             {
58                 returnStr2 = resp2.Content.ReadAsStringAsync().Result;
59             }
60             ReportSourceResult result = JsonConvert.DeserializeObject<ReportSourceResult>(returnStr2);
61             if (result != null)
62             {
63                 for (int i = 0; i < result.Data.Count; i++)
64                 {
65                     webReport.Report.RegisterData(result.Data[i].dtsource, result.Data[i].TBName);
66                     webReport.Report.GetDataSource(result.Data[i].TBName).Enabled = true;
67                 }
68             }
69 
70             #endregion
71 
72 
73 
74 
75             //webReport.Report.Load(dtos.Data.FileUrl + "Test.frx");
76             webReport.Report.Load(ConfigurationManager.AppSettings["ReportFilePath"] + dtos.Data.FileUrl);
77             webReport.ToolbarStyle = ToolbarStyle.Small;
78             webReport.ToolbarIconsStyle = ToolbarIconsStyle.Blue;
79             webReport.ToolbarBackgroundStyle = ToolbarBackgroundStyle.Custom;
80 
81             //webReport.PrintPdf();
82             
83             webReport.PreviewMode = true;//預覽模式
84             webReport.PrintInPdf = true;//在PDF列印
85 
86             //webReport.DesignerPath = "~/WebReportDesigner/index.html";
87             //webReport.DesignerSavePath = "~/App_Data/DesignedReports";
88             //webReport.DesignerSaveCallBack = "~/Report/SaveDesignedReport";
89             webReport.ID = "DesignReport";
90             ViewBag.WebReport = webReport;
91             return View();
92         }
View Code

其中以下幾點是我做了特殊化的設置

webReport.ToolbarStyle = ToolbarStyle.Small; //將原先的圖標變小(太大太難看了)
webReport.ToolbarIconsStyle = ToolbarIconsStyle.Blue;
webReport.ToolbarBackgroundStyle = ToolbarBackgroundStyle.Custom;

(下拉菜單的漢化還沒有找到,需要研究一下。)
webReport.PreviewMode = true;//預覽模式
webReport.PrintInPdf = true;//在PDF列印

 

這裡就是對接前端的列印介面。前端只需要調取我發佈的網址,並且把我需要的參數(數據ID,列印模板ID,token傳送給我即可。)

3.後端

後端介面主要是實現根據MVC端傳送過來的列印模板ID,將數據源和模板傳送給MVC端。由MVC端進行拼接組裝。

主要代碼如下:

 

 

  1         public List<ReportDataSource> GetDataSource(ReportModel entitydto)
  2         {
  3             try
  4             {
  5                 List<ReportDataSource> lst = new List<ReportDataSource>();
  6                 IDBTransAccess sqlTrans = TransSysUtils.GetDBTransAccess();
  7                 try
  8                 {
  9                     sqlTrans.OpenTrans();
 10 
 11                     lst = this.GetDataSource(entitydto, sqlTrans);
 12 
 13 
 14                     sqlTrans.CommitTrans();
 15                     return lst;
 16                 }
 17                 catch (Exception TE)
 18                 {
 19                     sqlTrans.RollbackTrans();
 20                     throw TE;
 21                 }
 22             }
 23             catch (BaseException)
 24             {
 25                 throw;
 26             }
 27             catch (Exception E)
 28             {
 29                 throw new BaseException(E.Message);
 30             }
 31         }
 32 
 33 
 34         public List<ReportDataSource> GetDataSource(ReportModel entitydto, IDBTransAccess sqlTrans)
 35         {
 36             try
 37             {
 38                 List<ReportDataSource> lst = ReportRun(entitydto.ReportID, new string[] { "DID","DMainID" }, new string[] { entitydto.DataID,entitydto.DataID }, sqlTrans);
 39                 
 40                 return lst;
 41 
 42             }
 43             catch (BaseException)
 44             {
 45                 throw;
 46             }
 47             catch (Exception E)
 48             {
 49                 throw new BaseException(E.Message);
 50             }
 51         }
 52 
 53 
 54 
 55 
 56 
 57 
 58        
 59 
 60 
 61         #endregion
 62 
 63 
 64         public List<ReportDataSource> ReportRun(string reportID, string[] queryName, string[] queryValue, IDBTransAccess sqlTrans)
 65         {
 66             List<ReportDataSource> lst = 	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 使用 ASP.NET Core MVC 創建 Web API 使用 ASP.NET Core MVC 創建 Web API(一) 使用 ASP.NET Core MVC 創建 Web API(二) 使用 ASP.NET Core MVC 創建 Web API(三) 十三、返回值 在上一篇文章(使用 ...
  • 隨意使用非同步的await和Result,被弄得欲仙欲死,然後看了 "Don't Block on Async Code" ,稍許明白,翻譯然後加上自己的理解以加深印象。 會死鎖的兩個例子 UI例子 public static async Task GetJsonAsync(Uri uri) { us ...
  • 在刷LeetCode題庫的時候,看到一個大神寫的for迴圈是這樣的 其實最終的效果和 是一樣的。 那麼他們兩個在什麼情況下是不一樣的呢 比如,假如i的初始值是1,則執行效果如下: 說明: 變數名++計算返回結果與變數相同將變數的值自增1 ++變數名計算返回的結果為變數自增加1將變數的值自增1 參考  ...
  • 為什麼要為值類型重定義相等性 原因主要有以下幾點: 值類型預設無法使用 == 操作符,除非對它進行重寫 再就是性能原因,因為值類型預設的相等性比較會使用裝箱和反射,所以性能很差 根據業務需求,其實際相等性的意義和預設的比較結果可能會不同,但是這種情況可能不較少 所以建議是:所有供外部使用的struc ...
  • 有時,需要將長功能變數名稱轉換為短功能變數名稱,或是為了減少字元量,或是為了隱藏真實網址。在DSAPI中,集成了EPS-GS的短功能變數名稱介面。該功能需要聯接互聯網,從EPS伺服器獲取。 代碼 示例 ...
  • 這個例子是基於客戶端與webapi進行進行交互的身份認證,當然也適用於其他情況下的身份認證。 簡單的交互過程: 1.首先輸入用戶名、密碼進行登錄操作 2.伺服器驗證用戶名、密碼的正確性,驗證通過之後,伺服器對一個json字元串進行加密,加密的內容、加密方法可以自己確定。 本次我加密的內容主要是用戶名 ...
  • Unity 3D本來是由德國的一些蘋果粉絲開發的一款游戲引擎,一直只能用於Mac平臺,所以一直不被業外人士所知曉。但是後來也推出了2.5版,同時發佈了PC版本,並將其發佈方向拓展到手持移動設備。Unity 3D游戲開發學習路線(方法篇)分享給大家。怎麼學Unity 3D游戲開發?要瞭解U3D最重要的 ...
  • 事件(Event)例如:最近的視覺中國‘黑洞事件’。我們大多數人(訂閱者)是通過XX平臺(發佈者)得知的這一消息,然後訂閱者A出售視覺中國的股票(觸發的方法),訂閱者B買入視覺中國的股票。 運行結果: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...