微信小程式支付功能 C# .NET開發

来源:https://www.cnblogs.com/ws-yizhiduxiu/archive/2019/08/08/11320994.html
-Advertisement-
Play Games

微信小程式支付功能的開發的時候坑比較多,不過對於錢的事謹慎也是好事。網上關於小程式支付的實例很多,但是大多多少有些問題,C#開發的更少。此篇文檔的目的是講開發過程中遇到的問題做一個備註,也方便其他開發的同學作為參考! 1、首先建議把官方文檔支付部分看上三遍,每個細節都不要放過,因為任何一個點和微信要 ...


微信小程式支付功能的開發的時候坑比較多,不過對於錢的事謹慎也是好事。網上關於小程式支付的實例很多,但是大多多少有些問題,C#開發的更少。此篇文檔的目的是講開發過程中遇到的問題做一個備註,也方便其他開發的同學作為參考!

 

       1、首先建議把官方文檔支付部分看上三遍,每個細節都不要放過,因為任何一個點和微信要求不符都會導致支付不成功。https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=3_1

      2、經過驗證的微信支付功能,會需要一些商戶號、支付秘鑰等,不要搞混。

     3、經常遇到的是“簽名錯誤”,請仔細看需要傳送的xml參數及取值規則是否符合微信規則。微信有個驗證工具可以驗證發送的xml欄位是否合法。

 

下麵上代碼:

 

web.config

 

    <add key="ConnectionString" value="server=127.0.0.1;database=;uid=sa;pwd="/>
    <add key="ConnectionString2" value="server=127.0.0.1;database=codematic2;uid=sa;pwd=1"/>
    <add key="appid" value=""/>//appid
    <add key="secret" value=""/>//小程式秘鑰
    <add key="mch_id" value=""/>//商戶號
    <add key="key" value=""/>//支付秘鑰
    <add key="ip" value=""/>//伺服器IP
    <add key="PayResulturl" value=""/>//微信返回接收信息的url地址
  </appSettings>

支付後臺xiadan.ashx

 

 

<%@ WebHandler Language="C#" Class="xiadan" %>

using System;
using System.Web;
using System.Net;
using System.IO;
using System.Configuration;
using Maticsoft.Model;
using Maticsoft.BLL;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;
using System.Xml;
using System.Collections.Generic;
using System.Data;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Linq;
using Newtonsoft.Json;

public class xiadan : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        string openid = context.Request.Params["openid"];
        string ordertime = context.Request.Params["ordertime"];

        string appid = ConfigurationManager.AppSettings["appid"];
        string secret = ConfigurationManager.AppSettings["secret"];
        string key = ConfigurationManager.AppSettings["key"];
        string mch_id = ConfigurationManager.AppSettings["mch_id"];
        string ip = ConfigurationManager.AppSettings["ip"];
        string PayResulturl = ConfigurationManager.AppSettings["PayResulturl"];
        string roomid = context.Request.Params["roomid"];
        string aa = "-押金";////商品描述交易欄位格式根據不同的應用場景按照以下格式:APP——需傳入應用市場上的APP名字-實際商品名稱,天天愛消除-游戲充值。

        string strcode = aa;
        byte[] buffer = Encoding.UTF8.GetBytes(strcode);
        string body = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
        string totalfee = context.Request.Params["totalfee"];
        string output = "";
        if ((context.Request.Params["openid"] != null) && (context.Request.Params["openid"] != ""))
        {
            //OrderInfo order = new OrderInfo();

            //order.appid = appid;

            System.Random Random = new System.Random();



            var dic = new Dictionary<string, string>
{
    {"appid", appid},
    {"mch_id", mch_id},
    {"nonce_str", GetRandomString(20)/*Random.Next().ToString()*/},
    {"body",body},
    {"out_trade_no",roomid + DateTime.Now.ToString("yyyyMMddHHmmssfff") + Random.Next(999).ToString()},//商戶自己的訂單號碼
    {"total_fee",totalfee},
    {"spbill_create_ip",ip},//伺服器的IP地址
    {"notify_url",PayResulturl},//非同步通知的地址,不能帶參數
    {"trade_type","JSAPI" },
    {"openid",openid}
};
      //加入簽名
            dic.Add("sign", GetSignString(dic));

            var sb = new StringBuilder();
            sb.Append("<xml>");


            foreach (var d in dic)
            {
                sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
            }
            sb.Append("</xml>");
            var xml = new XmlDocument();
            //  xml.LoadXml(GetPostString("https://api.mch.weixin.qq.com/pay/unifiedorder", sb.ToString()));
            CookieCollection coo = new CookieCollection();
            Encoding en = Encoding.GetEncoding("UTF-8");

            HttpWebResponse response = CreatePostHttpResponse("https://api.mch.weixin.qq.com/pay/unifiedorder", sb.ToString(), en);
            //列印返回值
            Stream stream = response.GetResponseStream();   //獲取響應的字元串流
            StreamReader sr = new StreamReader(stream); //創建一個stream讀取流
            string html = sr.ReadToEnd();   //從頭讀到尾,放到字元串html
                                            //Console.WriteLine(html);
            xml.LoadXml(html);
            //對請求返回值 進行處理

            var root = xml.DocumentElement;

            DataSet ds = new DataSet();
            StringReader stram = new StringReader(html);
            XmlTextReader reader = new XmlTextReader(stram);
            ds.ReadXml(reader);
            string return_code = ds.Tables[0].Rows[0]["return_code"].ToString();
            if (return_code.ToUpper() == "SUCCESS")
            {
                //通信成功
                string result_code = ds.Tables[0].Rows[0]["result_code"].ToString();//業務結果
                if (result_code.ToUpper() == "SUCCESS")
                {
                    var res = new Dictionary<string, string>
{
    {"appId", appid},
    {"timeStamp", GetTimeStamp()},
    {"nonceStr", dic["nonce_str"]},
    {"package",  "prepay_id="+ds.Tables[0].Rows[0]["prepay_id"].ToString()},
    {"signType", "MD5"}
};

                    //在伺服器上簽名
                    res.Add("paySign", GetSignString(res));
                    // string signapp = res.ToString();
                    string signapp = JsonConvert.SerializeObject(res);
                    if ((context.Request.Params["openid"] != null) && (context.Request.Params["openid"] != ""))
                    { 
                    //存儲訂單信息
                    Maticsoft.Model.order_history oh = new Maticsoft.Model.order_history();
                    //oh.shop_id =
                    oh.room_id = Convert.ToInt32(roomid);
                    oh.pay_price = Convert.ToDecimal(totalfee);
                    oh.out_trade_no = dic["out_trade_no"];
                    oh.order_timestart = Convert.ToDateTime(ordertime);
                    oh.openid = openid;
                    oh.creating_date = DateTime.Now;

                    Maticsoft.BLL.order_history bll = new Maticsoft.BLL.order_history();
                    bll.Add(oh);

                }
                context.Response.Write(signapp);
            }
        }




    }
    context.Response.Write(output);
    }

public bool IsReusable
{
    get
    {
        return false;
    }
}

public string GetMd5Hash(String input)
{
    if (input == null)
    {
        return null;
    }

    MD5 md5Hash = MD5.Create();

    // 將輸入字元串轉換為位元組數組並計算哈希數據  
    byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

    // 創建一個 Stringbuilder 來收集位元組並創建字元串  
    StringBuilder sBuilder = new StringBuilder();

    // 迴圈遍歷哈希數據的每一個位元組並格式化為十六進位字元串  
    for (int i = 0; i < data.Length; i++)
    {
        sBuilder.Append(data[i].ToString());
    }

    // 返回十六進位字元串  
    return sBuilder.ToString();
}
/// <summary>  
/// 對象序列化成 XML String  
/// </summary>  
public static string XmlSerialize<T>(T obj)
{
    string xmlString = string.Empty;
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
    using (MemoryStream ms = new MemoryStream())
    {
        xmlSerializer.Serialize(ms, obj);
        xmlString = Encoding.UTF8.GetString(ms.ToArray());
    }
    return xmlString;
}
/// <summary>
/// 從字元串里隨機得到,規定個數的字元串.
/// </summary>
/// <param name="allChar"></param>
/// <param name="CodeCount"></param>
/// <returns></returns>
public static string GetRandomString(int CodeCount)
{
    string allChar = "1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,i,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
    string[] allCharArray = allChar.Split(',');
    string RandomCode = "";
    int temp = -1;
    Random rand = new Random();
    for (int i = 0; i < CodeCount; i++)
    {
        if (temp != -1)
        {
            rand = new Random(temp * i * ((int)DateTime.Now.Ticks));
        }
        int t = rand.Next(allCharArray.Length - 1);
        while (temp == t)
        {
            t = rand.Next(allCharArray.Length - 1);
        }
        temp = t;
        RandomCode += allCharArray[t];
    }

    return RandomCode;
}


public static string GetWebClientIp()
{
    string userIP = "IP";

    try
    {
        if (System.Web.HttpContext.Current == null
    || System.Web.HttpContext.Current.Request == null
    || System.Web.HttpContext.Current.Request.ServerVariables == null)
            return "";

        string CustomerIP = "";

        //CDN加速後取到的IP   
        CustomerIP = System.Web.HttpContext.Current.Request.Headers["Cdn-Src-Ip"];
        if (!string.IsNullOrEmpty(CustomerIP))
        {
            return CustomerIP;
        }

        CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];


        if (!String.IsNullOrEmpty(CustomerIP))
            return CustomerIP;

        if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
        {
            CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (CustomerIP == null)
                CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
        }
        else
        {
            CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

        }

        if (string.Compare(CustomerIP, "unknown", true) == 0)
            return System.Web.HttpContext.Current.Request.UserHostAddress;
        return CustomerIP;
    }
    catch { }

    return userIP;
}




private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
    return true; //總是接受   
}

public static HttpWebResponse CreatePostHttpResponse(string url, string datas, Encoding charset)
{
    HttpWebRequest request = null;
    //HTTPSQ請求
    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
    request = WebRequest.Create(url) as HttpWebRequest;
    request.ProtocolVersion = HttpVersion.Version10;
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";

    //如果需要POST數據   
    //if (!(parameters == null || parameters.Count == 0))
    //{
    StringBuilder buffer = new StringBuilder();
    //int i = 0;
    //foreach (string key in parameters.Keys)
    //{
    //    if (i > 0)
    //    {
    //        buffer.AppendFormat("&{0}={1}", key, parameters[key]);
    //    }
    //    else
    //    {
    //        buffer.AppendFormat("{0}={1}", key, parameters[key]);
    //    }
    //    i++;
    //}
    buffer.AppendFormat(datas);
    byte[] data = charset.GetBytes(buffer.ToString());
    using (Stream stream = request.GetRequestStream())
    {
        stream.Write(data, 0, data.Length);
    }
    //}
    return request.GetResponse() as HttpWebResponse;
}


public string GetSignString(Dictionary<string, string> dic)
{
    string key = System.Web.Configuration.WebConfigurationManager.AppSettings["key"].ToString();//商戶平臺 API安全裡面設置的KEY  32位長度
                                                                                                //排序
    dic = dic.OrderBy(d => d.Key).ToDictionary(d => d.Key, d => d.Value);
    //連接欄位
    var sign = dic.Aggregate("", (current, d) => current + (d.Key + "=" + d.Value + "&"));
    sign += "key=" + key;
    //MD5
    // sign = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sign, "MD5").ToUpper();
    System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
    sign = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(sign))).Replace("-", null);
    return sign;
}


/// <summary>  
/// 獲取時間戳  
/// </summary>  
/// <returns></returns>  
public static string GetTimeStamp()
{
    TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
    return Convert.ToInt64(ts.TotalSeconds).ToString();
}

}




 

      微信返回信息接收後臺頁面notify_url.ashx

 

<%@ WebHandler Language="C#" Class="notify_url" %>

using System;
using System.Web;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Xml;
using System.Net;
public class notify_url : IHttpHandler
{
    public string return_result = "";
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.Write("Hello World");


        String xmlData = getPostStr();//獲取請求數據
        if (xmlData == "")
        {

        }
        else
        {
            var dic = new Dictionary<string, string>
{
    {"return_code", "SUCCESS"},
    {"return_msg","OK"}

};
            var sb = new StringBuilder();
            sb.Append("<xml>");


            foreach (var d in dic)
            {
                sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
            }
            sb.Append("</xml>");





            //把數據重新返回給客戶端
            DataSet ds = new DataSet();
            StringReader stram = new StringReader(xmlData);
            XmlTextReader datareader = new XmlTextReader(stram);
            ds.ReadXml(datareader);
            if (ds.Tables[0].Rows[0]["return_code"].ToString() == "SUCCESS")
            {


                string wx_appid = "";//微信開放平臺審核通過的應用APPID
                string wx_mch_id = "";//微信支付分配的商戶號

                string wx_nonce_str = "";// 	隨機字元串,不長於32位
                string wx_sign = "";//簽名,詳見簽名演算法
                string wx_result_code = "";//SUCCESS/FAIL

                string wx_return_code = "";
                string wx_openid = "";//用戶在商戶appid下的唯一標識
                string wx_is_subscribe = "";//用戶是否關註公眾賬號,Y-關註,N-未關註,僅在公眾賬號類型支付有效
                string wx_trade_type = "";// 	APP
                string wx_bank_type = "";// 	銀行類型,採用字元串類型的銀行標識,銀行類型見銀行列表
                string wx_fee_type = "";// 	貨幣類型,符合ISO4217標準的三位字母代碼,預設人民幣:CNY,其他值列表詳見貨幣類型


                string wx_transaction_id = "";//微信支付訂單號
                string wx_out_trade_no = "";//商戶系統的訂單號,與請求一致。
                string wx_time_end = "";// 	支付完成時間,格式為yyyyMMddHHmmss,如2009年12月25日9點10分10秒錶示為20091225091010。其他詳見時間規則
                int wx_total_fee = -1;// 	訂單總金額,單位為分
                int wx_cash_fee = -1;//現金支付金額訂單現金支付金額,詳見支付金額


                #region  數據解析
                //列 是否存在
                string signstr = "";//需要前面的字元串
                                    //wx_appid
                if (ds.Tables[0].Columns.Contains("appid"))
                {
                    wx_appid = ds.Tables[0].Rows[0]["appid"].ToString();
                    if (!string.IsNullOrEmpty(wx_appid))
                    {
                        signstr += "appid=" + wx_appid;
                    }
                }

                //wx_bank_type
                if (ds.Tables[0].Columns.Contains("bank_type"))
                {
                    wx_bank_type = ds.Tables[0].Rows[0]["bank_type"].ToString();
                    if (!string.IsNullOrEmpty(wx_bank_type))
                    {
                        signstr += "&bank_type=" + wx_bank_type;
                    }
                }
                //wx_cash_fee
                if (ds.Tables[0].Columns.Contains("cash_fee"))
                {
                    wx_cash_fee = Convert.ToInt32(ds.Tables[0].Rows[0]["cash_fee"].ToString());

                    signstr += "&cash_fee=" + wx_cash_fee;
                }

                //wx_fee_type
                if (ds.Tables[0].Columns.Contains("fee_type"))
                {
                    wx_fee_type = ds.Tables[0].Rows[0]["fee_type"].ToString();
                    if (!string.IsNullOrEmpty(wx_fee_type))
                    {
                        signstr += "&fee_type=" + wx_fee_type;
                    }
                }

                //wx_is_subscribe
                if (ds.Tables[0].Columns.Contains("is_subscribe"))
                {
                    wx_is_subscribe = ds.Tables[0].Rows[0]["is_subscribe"].ToString();
                    if (!string.IsNullOrEmpty(wx_is_subscribe))
                    {
                        signstr += "&is_subscribe=" + wx_is_subscribe;
                    }
                }

                //wx_mch_id
                if (ds.Tables[0].Columns.Contains("mch_id"))
                {
                    wx_mch_id = ds.Tables[0].Rows[0]["mch_id"].ToString();
                    if (!string.IsNullOrEmpty(wx_mch_id))
                    {
                        signstr += "&mch_id=" + wx_mch_id;
                    }
                }

                //wx_nonce_str
                if (ds.Tables[0].Columns.Contains("nonce_str"))
                {
                    wx_nonce_str = ds.Tables[0].Rows[0]["nonce_str"].ToString();
                    if (!string.IsNullOrEmpty(wx_nonce_str))
                    {
                        signstr += "&nonce_str=" + wx_nonce_str;
                    }
                }

                //wx_openid
                if (ds.Tables[0].Columns.Contains("openid"))
                {
                    wx_openid = ds.Tables[0].Rows[0]["openid"].ToString();
                    if (!string.IsNullOrEmpty(wx_openid))
                    {
                        signstr += "&openid=" + wx_openid;
                    }
                }

                //wx_out_trade_no
                if (ds.Tables[0].Columns.Contains("out_trade_no"))
                {
                    wx_out_trade_no = ds.Tables[0].Rows[0]["out_trade_no"].ToString();
                    if (!string.IsNullOrEmpty(wx_out_trade_no))
                    {
                        signstr += "&out_trade_no=" + wx_out_trade_no;
                    }
                }

                //wx_result_code 
                if (ds.Tables[0].Columns.Contains("result_code"))
                {
                    wx_result_code = ds.Tables[0].Rows[0]["result_code"].ToString();
                    if (!string.IsNullOrEmpty(wx_result_code))
                    {
                        signstr += "&result_code=" + wx_result_code;
                    }
                }

                //wx_result_code 
                if (ds.Tables[0].Columns.Contains("return_code"))
                {
                    wx_return_code = ds.Tables[0].Rows[0]["return_code"].ToString();
                    if (!string.IsNullOrEmpty(wx_return_code))
                    {
                        signstr += "&return_code=" + wx_return_code;
                    }
                }

                //wx_sign 
                if (ds.Tables[0].Columns.Contains("sign"))
                {
                    wx_sign = ds.Tables[0].Rows[0]["sign"].ToString();
                    //if (!string.IsNullOrEmpty(wx_sign))
                    //{
                    //    signstr += "&sign=" + wx_sign;
                    //}
                }

                //wx_time_end
                if (ds.Tables[0].Columns.Contains("time_end"))
                {
                    wx_time_end = ds.Tables[0].Rows[0]["time_end"].ToString();
                    if (!string.IsNullOrEmpty(wx_time_end))
                    {
                        signstr += "&time_end=" + wx_time_end;
                    }
                }

                //wx_total_fee
                if (ds.Tables[0].Columns.Contains("total_fee"))
                {
                    wx_total_fee = Convert.ToInt32(ds.Tables[0].Rows[0]["total_fee"].ToString());

                    signstr += "&total_fee=" + wx_total_fee;
                }

                //wx_trade_type
                if (ds.Tables[0].Columns.Contains("trade_type"))
                {
                    wx_trade_type = ds.Tables[0].Rows[0]["trade_type"].ToString();
                    if (!string.IsNullOrEmpty(wx_trade_type))
                    {
                        signstr += "&trade_type=" + wx_trade_type;
                    }
                }

                //wx_transaction_id
                if (ds.Tables[0].Columns.Contains("transaction_id"))
                {
                    wx_transaction_id = ds.Tables[0].Rows[0]["transaction_id"].ToString();
                    if (!string.IsNullOrEmpty(wx_transaction_id))
                    {
                        signstr += "&transaction_id=" + wx_transaction_id;
                    }
                }

                #endregion

                //追加key 密鑰
                signstr += "&key=" + System.Web.Configuration.WebConfigurationManager.AppSettings["key"].ToString();
                //簽名正確
                string orderStrwhere = "ordernumber='" + wx_out_trade_no + "'";



                if (wx_sign == System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(signstr, "MD5").ToUpper())
                {
                    //簽名正確   處理訂單操作邏輯


                }
                else
                {
                    //追加備註信息

                }

            }
            else
            {
                // 返回信息,如非空,為錯誤原因  簽名失敗 參數格式校驗錯誤
                string return_msg = ds.Tables[0].Rows[0]["return_msg"].ToString();

            }


            return_result = sb.ToString();
        }
    }


    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

    //獲得Post過來的數據
    public string getPostStr()
    {
        Int32 intLen = Convert.ToInt32(System.Web.HttpContext.Current.Request.InputStream.Length);
        byte[] b = new byte[intLen];
        System.Web.HttpContext.Current.Request.InputStream.Read(b, 0, intLen);
        return System.Text.Encoding.UTF8.GetString(b);
    }
}

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

-Advertisement-
Play Games
更多相關文章
  • 有時候我們可能需要將雲上資料庫下載到本地,下麵是我們在操作MongoDB資料庫時遇到的五個小問題。 其實現在RDS的 幫助文檔 寫的都比較詳細了,大家在第一次操作時,可以細讀一下,避免一些不必要的問題。 Problem 1 通過wget命令下載 雲MongoDB物理備份文件 時,url 中間有特殊字 ...
  • 1、 將win32_11gR2_database_1of2.zip與win32_11gR2_database_1of2.zip 解壓到當前目錄 PS:選中兩個壓縮包後右鍵解壓到當前文件夾;必須同時解壓,不能單獨解壓否則會覆蓋文件) 2、 解壓完成後設置文件相容性: 進入 database文件夾 點擊 ...
  • SQL Server直接執行.sql文件 客戶的資料庫數據被篡改,利用Log Explorer工具根據日誌生成的回滾腳本有200多M,不可能一下子扔到查詢分析器里去執行,於是想是否SQL Server是否可以像Oracle那樣直接執行.sql文件。講過查資料,測試,發現可以在cmd視窗中執行如下命令 ...
  • SELECT *FROM ( SELECT TOP (@count1) a.* FROM Article AS a WITH (NOLOCK)LEFT JOIN Article_Type AS at WITH (NOLOCK)ON a.ArticleType=at.ArticleTypeIdWHER ...
  • 點擊下載PLSQL,本次安裝的PLSQL版本為12.0.7,建議安裝64位。 點擊下載PLSQL,本次安裝的PLSQL版本為12.0.7,建議安裝64位。 下載PLSQL時,版本旁邊會有個“Language pack”的鏈接,點擊後左側選擇“Chinese”即可下載漢化包。 註冊碼 下載PLSQL時 ...
  • 前言 開心一刻 有一天,麻雀遇見一隻烏鴉。 麻雀問:你是啥子鳥喲 ? 烏鴉說:我是鳳凰。 麻雀說:哪有你龜兒子這麼黢黑的鳳凰 ? 烏鴉說:你懂個鏟鏟,老子是燒鍋爐的鳳凰。 子查詢 講子查詢之前,我們先來看看視圖,何謂視圖 ? 視圖是基於 SQL 語句的結果集的可視化的表,包含行和列,就像一個真實的表 ...
  • 在調試一塊全志A83T安卓工控板(已root),啟動後,安卓系統正常,設置好乙太網 的靜態IP地址:192.168.1.181,並接好網線,同時開發電腦WIN7系統IP地址 也是129.168.1.x, 在同一網段。win系統的cmd命令視窗中,先進行網路連接 測試,輸入 ping 192.168. ...
  • 版權聲明:本文為xing_star原創文章,轉載請註明出處! 本文同步自http://javaexception.com/archives/183 很久之前寫了一篇Java讀取文本文件內容,鏈接地址是http://javaexception.com/archives/128 本篇是它的續集,這篇的重 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...