C#(VS2022/.NET 6) HTTPS 通訊程式 模組

C#(VS2022/.NET 6) HTTPS 通訊程式 模組

C#(VS2022/.NET 6) HTTPS 通訊程式 模組


JSON和Class資料類別

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CS_VPOS
{ 
	/*
	{
		"client_id": "g4f3edb0-b96f-11ec-8689-97b3100ea64y",
		"client_secret": "gd23bb799b566da98e19f0de72108e2b2c784e6535bd62813c358563d3f357fy"
	}
	*/
	public class oauthInput
	{
		public string client_id { get; set; }
		public string client_secret { get; set; }
	}

	/*
	{
		"status": "OK",
		"message": "",
		"data": "",
		"access_token": "gyJpdiI6InVPcnQ0RU1uNFVrUlI1Y2oxOGM2elE9PSIsInZhbHVlIjoiYU5OZU83aHNsUWJPdUFWR0RNejJvd3lzL21GaFU3STFObUNOMm1UbEhDdlErbENsd05VQmN0QThpNzI2c09VRkRNR3U2eUJVcy9taml4UzJvVWZLb09LTjI4ZVBZZEM3TTlVdzhsQTNqam5JRFQ2WnJqSG8vUXdKOVZ1dTNVdE1iTmlJZnkzUHBjaUFZZ2VrNjVkS3FPcjFKSExKUnFPMEFmT2ZhUjBkUzRWcm0vTHZFQ2xlQlBseGJOL3Q4UkZPc1pMWnZVUWMzV0RyMDYxdmRRMXNpYjVldm10TjNPQWcvakx1a3hCUGZ6TkQ0WFJVbUpDdCt4VDVVaDFUZndiWFRFd2EwSWhrbitwa0cyUnZIVTN3RVMwaUx2dmRXaGJIUjBHRXRnL2k4M01CN2dvVVhOd0dPUTY2a094ZzhsMHBVaTR6SUN4VlpLNHJIU1ZOK01aMkszTjlyTXZuRXlLUGloeUFvQ1FTcmszeUladFYxbmdhU290RzVBV0N4UTBnRFJGc0c0VnNFTHk2amNtdk1NK0tFTlZiRTdscytHTXd5RXBZRHZvSDh0SnBaTjQxNjZBVmdsbkpJUDdTWUU0eVFtMFZQT1EyRHVzay85aWZRKzNOU2VmbndudldsT1RQNUJMK0tJNFU1cjVBUkF3d1NYTGZXaHJsWWcrOHRyNS9aTTN6UkVDTzE0V0VlRU9HZDlXNFpDdXFpcmRQNEloSDhyeS85cEZUYlVwNnF5b3hkc2YxVXcyMGFMTkdTUEdod3dQREVTd3M2L1RaKzZNTFA1STkzdlozN1hrWFFqUEw1S3NlcGxCWFZnZy95dm1ZcVcrY1ZNdWdZeGZnVFpUNyt4OTlEUitKaHErcXErenVsWU16YW1yN20zNXFMK25mdjBmb29WTDFRMjFMZ3N3OEVtVXJ0blE0dk5sZ3grbjl4cGxvdzhaRzJBVDQ5RURBOFZ0SjU2ei81VTN2V3JBNXg5dU5IanVEZEJJMFlBdlMxZkVOUmk0ZXFzRHY4RlErdVB6THpKWGF0UVdkUDZDZVNpODlDR29tUkJXWi9DQXFWOU1LRjdWUlViVmhjNm9VNS9CRUk1a1pBRkxUUEJBWkFJNUNSTVorSndrNmVPcUVFa0crZ3dUKzVFaHBXMXpJYlR1c2ZUaUtPaFFHN0pwcVQrNVNsbTFsalY5Qks0MGJVWUdMZTFFMWliTk9IZFltdjJSRVhRPT0iLCJtYWMiOiIyNzE2NTVmZmM5MjU0ZmI5ZTQ5NWMzOTBmYmI4ZTQ2MGExZDhiOWQ0ZTkxNTljY2VhNjJjOGQ0YTVhYzE4ZGYwIny=",
		"expires_time": "2022-05-26 14:15:59",
		"expires_unixtime": 1653545759,
		"terminal_sid": "VT-POS-2020-00002"
	}
	*/
	public class oauthResult
	{
		public string status { get; set; }
		public string message { get; set; }
		public string data { get; set; }
		public string access_token { get; set; }
		public string expires_time { get; set; }
		public int expires_unixtime { get; set; }
		public string terminal_sid { get; set; }
	}
} 



JSON和Class轉換類別

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//---
//using Newtonsoft.Json;//使用外部函式庫-Newtonsoft.Json.dll (VS2010- .net4X )
//.net6 內建支援json
//https://docs.microsoft.com/zh-tw/dotnet/standard/serialization/system-text-json-how-to?pivots=dotnet-6-0
using System.Text.Json;
//---.net6 內建支援json

namespace CS_VPOS
{
    public class JsonClassConvert
    {
        //---
        //oauth API
        public static String oauthInput2String(oauthInput inputbuf)
        {
            String StrResult = "";
            StrResult = JsonSerializer.Serialize(inputbuf);
            return StrResult;
        }
        public static oauthResult oauthResult2Class(String inputbuf)
        {
            oauthResult oauthResult = JsonSerializer.Deserialize<oauthResult>(inputbuf);
            return oauthResult;
        }
        //---oauth API
    }//JsonClassConvert
} 



檔案相關通用類別

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Compression;//C# 透過程式壓縮資料夾為zip檔[NET4.5 版本 內建的方法]
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CS_VPOS
{
    public class FileLib
    {
        public static bool DBBackup(String StrName = "")
        {
            bool blnAns = false;

            if (StrName.Length == 0)
            {
                StrName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".zip";
            }

            String StrSrcFullFilePath = String.Format("{0}\\{1}", path, "mysql\\data\\v8_workstation");
            string StrOutPath = String.Format("{0}\\{1}", path, "DBBackup\\");
            CreateDirectory(StrOutPath);
            CreateDirectory(StrOutPath + "v8_workstation\\");
            DirectoryCopy(StrSrcFullFilePath, StrOutPath + "v8_workstation\\", true);
            ZipFile.CreateFromDirectory(StrOutPath + "\\v8_workstation", StrOutPath + StrName);
            DeleteDirectory(StrOutPath + "v8_workstation\\", true);

            return blnAns;
        }

        //刪除目錄,recursive為True時,直接刪除目錄及其目錄下所有文件或子目錄;recursive為False時,需先將目錄下所有文件或子目錄刪除
        private static void DeleteDirectory(string path, bool recursive)
        {
            if (Directory.Exists(path))
            {
                if (recursive)
                {
                    Directory.Delete(path, true);
                }
            }
        }

        public static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
        {
            // Get the subdirectories for the specified directory.
            DirectoryInfo dir = new DirectoryInfo(sourceDirName);

            if (!dir.Exists)
            {
                throw new DirectoryNotFoundException(
                    "Source directory does not exist or could not be found: "
                    + sourceDirName);
            }

            DirectoryInfo[] dirs = dir.GetDirectories();
            // If the destination directory doesn't exist, create it.
            if (!Directory.Exists(destDirName))
            {
                Directory.CreateDirectory(destDirName);
            }

            // Get the files in the directory and copy them to the new location.
            FileInfo[] files = dir.GetFiles();
            foreach (FileInfo file in files)
            {
                string temppath = Path.Combine(destDirName, file.Name);
                file.CopyTo(temppath, false);
            }

            // If copying subdirectories, copy them and their contents to new location.
            if (copySubDirs)
            {
                foreach (DirectoryInfo subdir in dirs)
                {
                    string temppath = Path.Combine(destDirName, subdir.Name);
                    DirectoryCopy(subdir.FullName, temppath, copySubDirs);
                }
            }
        }

        //建立目錄
        private static void CreateDirectory(string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }

        public static string path = System.Windows.Forms.Application.StartupPath;
        public static bool IsUTF8File(String StrName)
        {
            bool blnAns = false;

            Stream reader = File.Open(StrName, FileMode.Open, FileAccess.Read);
            Encoding encoder = null;
            byte[] header = new byte[4];
            // 讀取前四個Byte
            reader.Read(header, 0, 4);
            if (header[0] == 0xFF && header[1] == 0xFE)
            {
                // UniCode File
                reader.Position = 2;
                encoder = Encoding.Unicode;
            }
            else if (header[0] == 0xEF && header[1] == 0xBB && header[2] == 0xBF)
            {
                // UTF-8 File
                reader.Position = 3;
                encoder = Encoding.UTF8;
                blnAns = true;
            }
            else
            {
                // Default Encoding File
                reader.Position = 0;
                encoder = Encoding.Default;
            }

            reader.Close();
            // .......... 接下來的程式

            return blnAns;
        }
        public static String ImageFile2Base64String(String StrDestFilePath)
        {
            String StrAns = "";
            try
            {
                //開啟檔案
                FileStream file = File.Open(StrDestFilePath, FileMode.Open, FileAccess.Read);
                //引用myReader類別
                BinaryReader read = new BinaryReader(file);
                int len = System.Convert.ToInt32(file.Length);
                //讀取位元陣列
                byte[] data = read.ReadBytes(len);
                StrAns = Convert.ToBase64String(data);
                //讀取資料
                //釋放資源
                read.Close();
                read.Dispose();
                file.Close();
                //file.Flush();

            }
            catch
            {
            }
            return StrAns;
        }
        public static void Base64String2ImageFile(String StrDestFilePath, String StrImageData)
        {
            byte[] data = Convert.FromBase64String(StrImageData);
            CreateFile(StrDestFilePath, data);
        }
        public static void CreateFile(String StrDestFilePath, byte[] byteSource)
        {
            FileLib.DeleteFile("temp.png");
            FileLib.DeleteFile(StrDestFilePath, false);
            try
            {
                //開啟建立檔案
                FileStream file = File.Open(StrDestFilePath, FileMode.Create, FileAccess.ReadWrite);
                BinaryWriter write = new BinaryWriter(file);
                write.Write(byteSource);
                write.Close();
                write.Dispose();
                write.Flush();

                file.Close();
                file.Flush();
                file.Dispose();
            }
            catch
            {

            }
        }
        public static void CopyFile(String StrSourceFilePath, String StrDestFilePath)
        {
            System.IO.File.Copy(StrSourceFilePath, StrDestFilePath, true);
        }
        public static void DeleteFile(String StrFileName, bool blnAtRoot = true)
        {
            String FilePath = "";
            if (blnAtRoot == true)
            {
                FilePath = path + "\\" + StrFileName;
            }
            else
            {
                FilePath = StrFileName;
            }
            if (System.IO.File.Exists(FilePath))
            {
                try
                {
                    System.IO.File.Delete(FilePath);
                }
                catch
                {
                }
            }
        }
        public static void WriteTxtFile(String StrFileName, String StrData)
        {
            StreamWriter sw = new StreamWriter(StrFileName);
            sw.WriteLine(StrData);// 寫入文字
            sw.Close();// 關閉串流
        }
        public static String ReadTxtFile(String StrFileName, bool blnOneLine = true)
        {
            String StrResult = "";
            String StrData = "";
            StreamReader sr = new StreamReader(StrFileName);
            while (!sr.EndOfStream)
            {
                if (StrResult.Length > 0)
                {
                    StrResult += "\n";
                }

                StrData = sr.ReadLine();// 寫入文字
                StrResult += StrData;

                if (blnOneLine)
                {
                    break;
                }
            }
            sr.Close();// 關閉串流
            return StrResult;
        }
        public static void TxtFile(String StrFileName, String StrData)
        {
            StreamWriter sw = new StreamWriter(StrFileName);
            sw.WriteLine(StrData);// 寫入文字
            sw.Close();// 關閉串流
        }

        public static void logFile(String StrFileName, String StrData, bool blnAutoTime = true)
        {
            FileStream fs = new FileStream(StrFileName, FileMode.Append);
            StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
            if (blnAutoTime == true)
            {
                sw.WriteLine(DateTime.Now.ToString("HH:mm:ss - ") + StrData);// 寫入文字
            }
            else
            {
                sw.WriteLine(StrData);// 寫入文字
            }

            sw.Close();// 關閉串流
        }

        //---
        //除錯(DEBUG)專用 log函式庫
        public static bool g_blnDebug = false;
        public static StreamWriter g_sw;
        public static void createLogFile()
        {
            if (g_blnDebug == true)
            {
                g_sw = new StreamWriter(Application.StartupPath + "\\" + DateTime.Now.ToString("yyyy-MM-dd-HHmm") + ".log");
                writeLogFile("createLogFile");
            }
        }
        public static void writeLogFile(String msg)
        {
            if (g_blnDebug == true)
            {
                g_sw.WriteLine(msg + ",\t" + DateTime.Now.ToString("yyyy/MM/dd/HH:mm:ss"));
            }
        }
        public static void closeLogFile()
        {
            if (g_blnDebug == true)
            {
                writeLogFile("closeLogFile");
                g_sw.Close();// 關閉串流
            }
        }
        //---除錯(DEBUG)專用 log函式庫

        //---
        //縮圖
        public static bool ImageResize(String strImageSrcPath, String strImageDesPath, int intWidth = 0, int intHeight = 0)
        {
            /*
            ImageFormat IF_Png = ImageFormat.Png; 
            bool blnAns = true;
            Image objImage = Image.FromFile(strImageSrcPath);
            if (intWidth > objImage.Width)
            {
                intWidth = objImage.Width;
            }
            if (intHeight > objImage.Height)
            {
                intHeight = objImage.Height;
            }
            if ((intWidth == 0) && (intHeight == 0))
            {
                intWidth = objImage.Width;
                intHeight = objImage.Height;
            }
            else if ((intHeight == 0) && (intWidth != 0))
            {
                intHeight = (int)(objImage.Height * intWidth / objImage.Width);
            }
            else if ((intWidth == 0) && (intHeight != 0))
            {
                intWidth = (int)(objImage.Width * intHeight / objImage.Height);
            }
            Bitmap imgOutput = new Bitmap(objImage, intWidth, intHeight);
            imgOutput.Save(strImageDesPath, IF_Png);//imgOutput.Save(strImageDesPath, objImage.RawFormat);
            objImage.Dispose();
            objImage = null;
            imgOutput.Dispose();
            imgOutput = null;
            return blnAns;
            */
            Process m_pro;
            String StrVar = String.Format("\"{0}\" \"{1}\" {2}", strImageSrcPath, strImageDesPath, intWidth);
            ProcessStartInfo startInfo = new ProcessStartInfo("CS_cmd_ImageResize.exe", StrVar);
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;

            try
            {
                m_pro = Process.Start(startInfo);
            }
            catch
            {
                return false;//找不到執行檔的防呆 at 2017/06/16
            }
            if (m_pro != null)
            {
                m_pro.WaitForExit();//下載SERVER資料
                m_pro = null;
            }

            return true;
        }

        //---縮圖
    }

}

https API 存取基底類別

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Cache;
using System.Text;
using System.Threading.Tasks;

namespace CS_VPOS
{
    public class HttpsFun
    {
        private static bool m_blnlogfile = true;
        private static bool m_blnTestMode = true;
        private static String m_StrDomain = "https://jashliao.eu/wordpress/test";
        public static void setDomainMode(bool blnTestMode=true)
        {
            m_blnTestMode=blnTestMode;
            m_StrDomain = (m_blnTestMode) ? "https://jashliao.eu/wordpress/test" : "https://jashliao.eu/wordpress";
        }
        public static void setHeader(ref HttpWebRequest request,String StrHeaderName,String StrHeaderValue)//新增HTTP/HTTPS的Header參數
        {
            if((StrHeaderName.Length>0)&&(StrHeaderValue.Length>0))
            {
                request.Headers[StrHeaderName] = StrHeaderValue;
            }
        }

        public static String RESTfulAPI_get(String path)
        {
            //string url= "http://192.168.1.68:24410/syris/sydm/controller";
            String StrHeaderName = "";
            String StrHeaderValue = "";
            String StrData = "";
            String url = m_StrDomain + path;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                setHeader(ref request, StrHeaderName, StrHeaderValue);
                request.KeepAlive = false;
                //--
                //定義此req的緩存策略
                //https://msdn.microsoft.com/zh-tw/library/system.net.webrequest.cachepolicy(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
                HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
                request.CachePolicy = noCachePolicy;
                //--
                request.Method = "GET";//request.Method = "POST";
                //request.ContentType = "application/x-www-form-urlencoded";

                Thread.Sleep(100);
                System.Net.ServicePointManager.DefaultConnectionLimit = 200;
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                string encoding = response.ContentEncoding;

                if (encoding == null || encoding.Length < 1)
                {
                    encoding = "UTF-8"; //預設編碼
                }

                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));

                StrData = reader.ReadToEnd();

                response.Close();
                //---
                //手動強制執行當呼叫完 CG API 的強制關閉連線補強措施
                request.Abort();
                response = null;
                request = null;
                GC.Collect();//手動記憶體回收
                //---手動強制執行當呼叫完 CG API 的強制關閉連線補強措施
            }
            catch (Exception e)
            {
                StrData += e.Message;
            }

            if (m_blnlogfile)//記錄所有V09_API呼叫log
            {
                FileLib.logFile(DateTime.Now.ToString("yyyyMMdd") + ".log", "RESTfulAPI_get :" + url + ";" + StrData);
            }
            return StrData;
        }

        public static String RESTfulAPI_postBody(String path, String StrInput)
        {
            String StrHeaderName = "";
            String StrHeaderValue = "";
            String StrData = "";
            String url = m_StrDomain + path;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                setHeader(ref request, StrHeaderName, StrHeaderValue);
                request.KeepAlive = false;
                //--
                //定義此req的緩存策略
                //https://msdn.microsoft.com/zh-tw/library/system.net.webrequest.cachepolicy(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
                HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
                request.CachePolicy = noCachePolicy;
                //--
                request.Method = "POST";

                //--
                //request.ContentType = "application/x-www-form-urlencoded";//一般POST
                request.ContentType = "application/json; charset=UTF-8";//POST to AJAX [is_ajax_request()]
                //request.Accept = "application/json, text/javascript";//POST to AJAX [is_ajax_request()]
                //request.UserAgent = "";//POST to AJAX [is_ajax_request()]
                //request.Headers.Add("X-Requested-With", "XMLHttpRequest");//POST to AJAX [is_ajax_request()]
                //--


                //request.ContentLength = data1.Length;
                //StreamWriter writer = new StreamWriter(request.GetRequestStream());//CS2PHPrestfulapi 傳送全部改為UTF8
                //writer.Write(StrInput);
                //writer.Flush();
                using (var streamWriter = new StreamWriter(request.GetRequestStream()))
                {
                    streamWriter.Write(StrInput);
                    streamWriter.Flush();
                }

                Thread.Sleep(100);
                System.Net.ServicePointManager.DefaultConnectionLimit = 200;
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                string encoding = response.ContentEncoding;
                if (encoding == null || encoding.Length < 1)
                {
                    encoding = "UTF-8"; //默认编码
                }

                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));

                StrData = reader.ReadToEnd();

                response.Close();

                //---
                //手動強制執行當呼叫完 CG API 的強制關閉連線補強措施
                request.Abort();
                response = null;
                request = null;
                GC.Collect();//手動記憶體回收
                //---手動強制執行當呼叫完 CG API 的強制關閉連線補強措施
            }
            catch (Exception e)
            {
                StrData = e.Message;
            }

            if (m_blnlogfile)//記錄所有V09_API呼叫log
            {
                FileLib.logFile(DateTime.Now.ToString("yyyyMMdd") + ".log", "RESTfulAPI_postBody :" + StrInput + ";" + StrData);
            }
            return StrData;
        }
    }
}


GUI 測試程式

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace CS_VPOS
{
    public partial class test_buf : Form
    {
        //---
        //把http API呼叫換成支援https API模式
        public bool ValidateServerCertificate(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }

        public void CS_https_tls_setting()
        {
            //REF: https://stackoverflow.com/a/39534068/288936
            ServicePointManager.SecurityProtocol =
                SecurityProtocolType.Tls | SecurityProtocolType.Tls13 |
                SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;//.net6 不支援SecurityProtocolType.Ssl3執行會報錯

            //REF: https://docs.microsoft.com/zh-tw/dotnet/api/system.net.servicepointmanager.expect100continue?view=netframework-4.7.2
            //REF: https://www.cnblogs.com/dudu/p/the_remote_certificate_is_invalid_according_to_the_validation_procedure.html
            ServicePointManager.UseNagleAlgorithm = true;
            ServicePointManager.Expect100Continue = true;
            ServicePointManager.CheckCertificateRevocationList = false;//The remote certificate is invalid according to the validation procedure
            ServicePointManager.DefaultConnectionLimit = ServicePointManager.DefaultPersistentConnectionLimit;

            //REF: http://libraclark.blogspot.com/2007/06/ssl.html
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
        }
        //---把http API呼叫換成支援https API模式
        public test_buf()
        {
            InitializeComponent();
        }


        private void test_buf_Load(object sender, EventArgs e)
        {
            CS_https_tls_setting();
            HttpsFun.setDomainMode();

            oauthInput oauthInputBuf=new oauthInput();
            oauthInputBuf.client_id = "y4f3edb0-b96f-11ec-8689-97b3100ea64g";
            oauthInputBuf.client_secret = "gd23bb799b566da98e19f0de72108e2b2c784e6535bd62813c358563d3f357fy";
            String StrData = JsonClassConvert.oauthInput2String(oauthInputBuf);
            
            String StrResult = HttpsFun.RESTfulAPI_postBody("/api/oauth", StrData);
            oauthResult oauthResultBuf=JsonClassConvert.oauthResult2Class(StrResult);

            MessageBox.Show(oauthResultBuf.access_token+ "\n\n"+oauthResultBuf.expires_time);
        }
    }
}

One thought on “C#(VS2022/.NET 6) HTTPS 通訊程式 模組

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *