主頁 > .NET開發 > c#與js的rsa加密互通

c#與js的rsa加密互通

2021-04-01 15:21:04 .NET開發

ASN.1

 抽象語法表示(標記)ASN.1(Abstract Syntax Notation One )一種資料定義語言,描述了對資料進行表示、編碼、傳輸和解碼的資料格式,網路管理系統中的管理資訊庫(MIB)、應用程式的資料結構、協議資料單元(PDU)都是用ASN.1定義的,

可以理解為ASN.1是對密鑰結構定義的一種規范

密鑰結構型別

PKCS#1

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

PKCS#8

PublicKeyInfo ::= SEQUENCE {
  algorithm       AlgorithmIdentifier,
  PublicKey       BIT STRING ; 其中的BIT STRING是某個演算法自己指定的二進制格式
                             ; RSA演算法的話,就是上面的RSAPublicKey
}

AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}

PrivateKeyInfo ::= SEQUENCE {
  version         Version,
  algorithm       AlgorithmIdentifier,
  PrivateKey      BIT STRING
}

AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}

密鑰編碼型別

der格式

二進制格式

pem格式

把der格式的資料用base64編碼后,然后再在頭尾加上一段“-----”開始的標記

證書型別

X.509證書

X.509只包含公鑰,沒有私鑰,這種證書一般公開發布,可用于放在客服端使用,用于加密、驗簽

PKCS#12證書

因為X.509證書只包含公鑰,但有些時候我們需要把私鑰和公鑰合并成一個證書,放在服務端使用,用于解密、簽名,

PKCS#12就定義了這樣一種證書,它既包含了公鑰有包含了私鑰,典型的入pfx、p12證書就是PKCS#12證書,

PKCS#7證書

當你收到一個網站的證書后,你需要驗證其真實性,因為一個X.509證書包含了公鑰、持有人資訊、簽名,為了驗證其真實性,你需要簽證其簽名,而驗證簽名則需要簽發的CA機構的公鑰證書,同樣原理,當你拿到CA機構的公鑰證書后,你也需要驗證該CA機構的真實性,而驗證該CA機構的證書,你需要該CA上級機構的CA公鑰證書...以此類推,你需要一直驗證到根證書為止,所以為了驗證一個網站證書的真實性,你需要的不僅一張證書,而是一個證書鏈,而PKCS#7就定義了這樣一個證書鏈的型別結構,典型如p7b后綴名的證書就是這樣的格式,

證書后綴

.cer/.crt:存放公鑰,沒有私鑰,就是一個X.509證書,二進制形式存放

.pfx/.p12:存放公鑰和私鑰,通常包含保護密碼,二進制方式

證書與密鑰關系

數字證書和私鑰是匹配的關系,就好比鑰匙牌和鑰匙的關系,在數字證書簽發的時候,數字證書簽發系統(CA系統),在生成數字證書的同時,還會隨機生成一對密鑰,一個私鑰,一個公鑰,數字證書標示用戶身份, 相匹配的私鑰和公鑰,則是用來保障用戶身份的可認證性,就好比咱們拿著一串鑰匙,每個鑰匙上都標明有時某某房間的鑰匙,但是否是真的,還需要看能不能打開相應的房門,

密鑰生成

   /// <summary>
        /// 取得私鑰和公鑰 XML 格式,回傳陣列第一個是私鑰,第二個是公鑰.
        /// </summary>
        /// <param name="size">密鑰長度,默認1024,可以為2048</param>
        /// <returns></returns>
        public static string[] CreateXmlKey(int size = 1024)
        {
            //密鑰格式要生成pkcs#1格式的  而不是pkcs#8格式的
            RSACryptoServiceProvider sp = new RSACryptoServiceProvider(size);
            string privateKey = sp.ToXmlString(true);//private key
            string publicKey = sp.ToXmlString(false);//public  key
            return new string[] { privateKey, publicKey };
        }

        /// <summary>
        /// 取得私鑰和公鑰 CspBlob 格式,回傳陣列第一個是私鑰,第二個是公鑰.
        /// </summary>
        /// <param name="size"></param>
        /// <returns></returns>
        public static string[] CreateCspBlobKey(int size = 1024)
        {
            //密鑰格式要生成pkcs#1格式的  而不是pkcs#8格式的
            RSACryptoServiceProvider sp = new RSACryptoServiceProvider(size);
            string privateKey = System.Convert.ToBase64String(sp.ExportCspBlob(true));//private key
            string publicKey = System.Convert.ToBase64String(sp.ExportCspBlob(false));//public  key 

            return new string[] { privateKey, publicKey };
        }
        /// <summary>
        /// 匯出PEM PKCS#1格式密鑰對,回傳陣列第一個是私鑰,第二個是公鑰.
        /// </summary>
        public static string[] CreateKey_PEM_PKCS1(int size = 1024)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(size);
            string privateKey = RSA_PEM.ToPEM(rsa, false, false);
            string publicKey = RSA_PEM.ToPEM(rsa, true, false);
            return new string[] { privateKey, publicKey };
        }

        /// <summary>
        /// 匯出PEM PKCS#8格式密鑰對,回傳陣列第一個是私鑰,第二個是公鑰.
        /// </summary>
        public static string[] CreateKey_PEM_PKCS8(int size = 1024, bool convertToPublic = false)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(size);
            string privateKey = RSA_PEM.ToPEM(rsa, false, true);
            string publicKey = RSA_PEM.ToPEM(rsa, true, true);
            return new string[] { privateKey, publicKey };

        }

后端加/解密方法使用

   /// <summary>
        /// RSA加密
        /// </summary>
        /// <param name="Data">原文</param>
        /// <param name="PublicKeyString">公鑰</param>
        /// <param name="KeyType">密鑰型別XML/PEM</param>
        /// <returns></returns>
        public static string RSAEncrypt(string Data,string PublicKeyString,string KeyType)
        {
            byte[] data = https://www.cnblogs.com/yanpeng19940119/p/Encoding.GetEncoding("UTF-8").GetBytes(Data);
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            switch (KeyType)
            {
                case "XML":
                    rsa.FromXmlString(PublicKeyString);
                    break;
                case "PEM":
                    rsa = RSA_PEM.FromPEM(PublicKeyString);
                    break;
                default:
                    throw new Exception("不支持的密鑰型別");
            }
            //加密塊最大長度限制,如果加密資料的長度超過 秘鑰長度/8-11,會引發長度不正確的例外,所以進行資料的分塊加密
            int MaxBlockSize = rsa.KeySize / 8 - 11;
            //正常長度
            if (data.Length <= MaxBlockSize)
            {
                byte[] hashvalueEcy = rsa.Encrypt(data, false); //加密
                return System.Convert.ToBase64String(hashvalueEcy);
            }
            //長度超過正常值
            else
            {
                using (MemoryStream PlaiStream = new MemoryStream(data))
                using (MemoryStream CrypStream = new MemoryStream())
                {
                    Byte[] Buffer = new Byte[MaxBlockSize];
                    int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
                    while (BlockSize > 0)
                    {
                        Byte[] ToEncrypt = new Byte[BlockSize];
                        Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize);

                        Byte[] Cryptograph = rsa.Encrypt(ToEncrypt, false);
                        CrypStream.Write(Cryptograph, 0, Cryptograph.Length);
                        BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
                    }
                    return System.Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None);
                }
            }
        }

        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="Data">密文</param>
        /// <param name="PrivateKeyString">私鑰</param>
        /// <param name="KeyType">密鑰型別XML/PEM</param>
        /// <returns></returns>
        public static string RSADecrypt(string Data,string PrivateKeyString, string KeyType)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            switch (KeyType)
            {
                case "XML":
                    rsa.FromXmlString(PrivateKeyString);
                    break;
                case "PEM":
                    rsa = RSA_PEM.FromPEM(PrivateKeyString);
                    break;
                default:
                    throw new Exception("不支持的密鑰型別");
            }
            int MaxBlockSize = rsa.KeySize / 8;    //解密塊最大長度限制
            //正常解密
            if (Data.Length <= MaxBlockSize)
            {
                byte[] hashvalueDcy = rsa.Decrypt(System.Convert.FromBase64String(Data), false);//解密
                return Encoding.GetEncoding("UTF-8").GetString(hashvalueDcy);
            }
            //分段解密
            else
            {
                using (MemoryStream CrypStream = new MemoryStream(System.Convert.FromBase64String(Data)))
                using (MemoryStream PlaiStream = new MemoryStream())
                {
                    Byte[] Buffer = new Byte[MaxBlockSize];
                    int BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);

                    while (BlockSize > 0)
                    {
                        Byte[] ToDecrypt = new Byte[BlockSize];
                        Array.Copy(Buffer, 0, ToDecrypt, 0, BlockSize);

                        Byte[] Plaintext = rsa.Decrypt(ToDecrypt, false);
                        PlaiStream.Write(Plaintext, 0, Plaintext.Length);
                        BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
                    }
                    string output = Encoding.GetEncoding("UTF-8").GetString(PlaiStream.ToArray());
                    return output;
                }
            }
        }

前端加密方法

注:jsencrypt默認PKCS#1結構,生成密鑰時需要注意

 <script src="http://passport.cnblogs.com/scripts/jsencrypt.min.js"></script>
  var encryptor = new JSEncrypt()  // 創建加密物件實體
  //之前ssl生成的公鑰,復制的時候要小心不要有空格
  var pubKey = '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1QQRl0HlrVv6kGqhgonD6A9SU6ZJpnEN+Q0blT/ue6Ndt97WRfxtS'+
  'As0QoquTreaDtfC4RRX4o+CU6BTuHLUm+eSvxZS9TzbwoYZq7ObbQAZAY+SYDgAA5PHf1wNN20dGMFFgVS/y0ZWvv1UNa2laEz0I8Vmr5ZlzIn88GkmSiQIDAQAB-----END PUBLIC KEY-----'
  encryptor.setPublicKey(pubKey)//設定公鑰
  var rsaPassWord = encryptor.encrypt('要加密的內容')  // 對內容進行加密

c#pem格式轉換

注:c#的RSACryptoServiceProvider默認只支持xml格式的密鑰決議

 public class RSA_Unit
    {
        static public string Base64EncodeBytes(byte[] byts)
        {
            return System.Convert.ToBase64String(byts);
        }
        static public byte[] Base64DecodeBytes(string str)
        {
            try
            {
                return System.Convert.FromBase64String(str);
            }
            catch
            {
                return null;
            }
        }
        /// <summary>
        /// 把字串按每行多少個字斷行
        /// </summary>
        static public string TextBreak(string text, int line)
        {
            var idx = 0;
            var len = text.Length;
            var str = new StringBuilder();
            while (idx < len)
            {
                if (idx > 0)
                {
                    str.Append('\n');
                }
                if (idx + line >= len)
                {
                    str.Append(text.Substring(idx));
                }
                else
                {
                    str.Append(text.Substring(idx, line));
                }
                idx += line;
            }
            return str.ToString();
        }

    }
    static public class Extensions
    {
        /// <summary>
        /// 從陣列start開始到指定長度復制一份
        /// </summary>
        static public T[] sub<T>(this T[] arr, int start, int count)
        {
            T[] val = new T[count];
            for (var i = 0; i < count; i++)
            {
                val[i] = arr[start + i];
            }
            return val;
        }
        static public void writeAll(this Stream stream, byte[] byts)
        {
            stream.Write(byts, 0, byts.Length);
        }
    }
點擊并拖拽以移動
 public class RSA_PEM
    {
        public static RSACryptoServiceProvider FromPEM(string pem)
        {
            var rsaParams = new CspParameters();
            rsaParams.Flags = CspProviderFlags.UseMachineKeyStore;
            var rsa = new RSACryptoServiceProvider(rsaParams);

            var param = new RSAParameters();

            var base64 = _PEMCode.Replace(pem, "");
            var data =https://www.cnblogs.com/yanpeng19940119/p/ RSA_Unit.Base64DecodeBytes(base64);
            if (data =https://www.cnblogs.com/yanpeng19940119/p/= null)
            {
                throw new Exception("PEM內容無效");
            }
            var idx = 0;

            //讀取長度
            Func<byte, int> readLen = (first) =>
            {
                if (data[idx] == first)
                {
                    idx++;
                    if (data[idx] == 0x81)
                    {
                        idx++;
                        return data[idx++];
                    }
                    else if (data[idx] == 0x82)
                    {
                        idx++;
                        return (((int)data[idx++]) << 8) + data[idx++];
                    }
                    else if (data[idx] < 0x80)
                    {
                        return data[idx++];
                    }
                }
                throw new Exception("PEM未能提取到資料");
            };
            //讀取塊資料
            Func<byte[]> readBlock = () =>
            {
                var len = readLen(0x02);
                if (data[idx] == 0x00)
                {
                    idx++;
                    len--;
                }
                var val = data.sub(idx, len);
                idx += len;
                return val;
            };
            //比較data從idx位置開始是否是byts內容
            Func<byte[], bool> eq = (byts) =>
            {
                for (var i = 0; i < byts.Length; i++, idx++)
                {
                    if (idx >= data.Length)
                    {
                        return false;
                    }
                    if (byts[i] != data[idx])
                    {
                        return false;
                    }
                }
                return true;
            };




            if (pem.Contains("PUBLIC KEY"))
            {
                /****使用公鑰****/
                //讀取資料總長度
                readLen(0x30);
                if (!eq(_SeqOID))
                {
                    throw new Exception("PEM未知格式");
                }
                //讀取1長度
                readLen(0x03);
                idx++;//跳過0x00
                      //讀取2長度
                readLen(0x30);

                //Modulus
                param.Modulus = readBlock();

                //Exponent
                param.Exponent = readBlock();
            }
            else if (pem.Contains("PRIVATE KEY"))
            {
                /****使用私鑰****/
                //讀取資料總長度
                readLen(0x30);

                //讀取版本號
                if (!eq(_Ver))
                {
                    throw new Exception("PEM未知版本");
                }

                //檢測PKCS8
                var idx2 = idx;
                if (eq(_SeqOID))
                {
                    //讀取1長度
                    readLen(0x04);
                    //讀取2長度
                    readLen(0x30);

                    //讀取版本號
                    if (!eq(_Ver))
                    {
                        throw new Exception("PEM版本無效");
                    }
                }
                else
                {
                    idx = idx2;
                }

                //讀取資料
                param.Modulus = readBlock();
                param.Exponent = readBlock();
                param.D = readBlock();
                param.P = readBlock();
                param.Q = readBlock();
                param.DP = readBlock();
                param.DQ = readBlock();
                param.InverseQ = readBlock();
            }
            else
            {
                throw new Exception("pem需要BEGIN END標頭");
            }

            rsa.ImportParameters(param);
            return rsa;
        }
        static private Regex _PEMCode = new Regex(@"--+.+?--+|\s+");
        static private byte[] _SeqOID = new byte[] { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
        static private byte[] _Ver = new byte[] { 0x02, 0x01, 0x00 };


        /// <summary>
        /// 將RSA中的密鑰對轉換成PEM格式,usePKCS8=false時回傳PKCS#1格式,否則回傳PKCS#8格式,如果convertToPublic含私鑰的RSA將只回傳公鑰,僅含公鑰的RSA不受影響
        /// </summary>
        public static string ToPEM(RSACryptoServiceProvider rsa, bool convertToPublic, bool usePKCS8)
        {
            //https://www.jianshu.com/p/25803dd9527d
            //https://www.cnblogs.com/ylz8401/p/8443819.html
            //https://blog.csdn.net/jiayanhui2877/article/details/47187077
            //https://blog.csdn.net/xuanshao_/article/details/51679824
            //https://blog.csdn.net/xuanshao_/article/details/51672547

            var ms = new MemoryStream();
            //寫入一個長度位元組碼
            Action<int> writeLenByte = (len) =>
            {
                if (len < 0x80)
                {
                    ms.WriteByte((byte)len);
                }
                else if (len <= 0xff)
                {
                    ms.WriteByte(0x81);
                    ms.WriteByte((byte)len);
                }
                else
                {
                    ms.WriteByte(0x82);
                    ms.WriteByte((byte)(len >> 8 & 0xff));
                    ms.WriteByte((byte)(len & 0xff));
                }
            };
            //寫入一塊資料
            Action<byte[]> writeBlock = (byts) =>
            {
                var addZero = (byts[0] >> 4) >= 0x8;
                ms.WriteByte(0x02);
                var len = byts.Length + (addZero ? 1 : 0);
                writeLenByte(len);

                if (addZero)
                {
                    ms.WriteByte(0x00);
                }
                ms.Write(byts, 0, byts.Length);
            };
            //根據后續內容長度寫入長度資料
            Func<int, byte[], byte[]> writeLen = (index, byts) =>
            {
                var len = byts.Length - index;

                ms.SetLength(0);
                ms.Write(byts, 0, index);
                writeLenByte(len);
                ms.Write(byts, index, len);

                return ms.ToArray();
            };


            if (rsa.PublicOnly || convertToPublic)
            {
                /****生成公鑰****/
                var param = rsa.ExportParameters(false);


                //寫入總位元組數,不含本段長度,額外需要24位元組的頭,后續計算好填入
                ms.WriteByte(0x30);
                var index1 = (int)ms.Length;

                //固定內容
                // encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
                ms.writeAll(_SeqOID);

                //從0x00開始的后續長度
                ms.WriteByte(0x03);
                var index2 = (int)ms.Length;
                ms.WriteByte(0x00);

                //后續內容長度
                ms.WriteByte(0x30);
                var index3 = (int)ms.Length;

                //寫入Modulus
                writeBlock(param.Modulus);

                //寫入Exponent
                writeBlock(param.Exponent);


                //計算空缺的長度
                var byts = ms.ToArray();

                byts = writeLen(index3, byts);
                byts = writeLen(index2, byts);
                byts = writeLen(index1, byts);


                return "-----BEGIN PUBLIC KEY-----\n" + RSA_Unit.TextBreak(RSA_Unit.Base64EncodeBytes(byts), 64) + "\n-----END PUBLIC KEY-----";
            }
            else
            {
                /****生成私鑰****/
                var param = rsa.ExportParameters(true);

                //寫入總位元組數,后續寫入
                ms.WriteByte(0x30);
                int index1 = (int)ms.Length;

                //寫入版本號
                ms.writeAll(_Ver);

                //PKCS8 多一段資料
                int index2 = -1, index3 = -1;
                if (usePKCS8)
                {
                    //固定內容
                    ms.writeAll(_SeqOID);

                    //后續內容長度
                    ms.WriteByte(0x04);
                    index2 = (int)ms.Length;

                    //后續內容長度
                    ms.WriteByte(0x30);
                    index3 = (int)ms.Length;

                    //寫入版本號
                    ms.writeAll(_Ver);
                }

                //寫入資料
                writeBlock(param.Modulus);
                writeBlock(param.Exponent);
                writeBlock(param.D);
                writeBlock(param.P);
                writeBlock(param.Q);
                writeBlock(param.DP);
                writeBlock(param.DQ);
                writeBlock(param.InverseQ);


                //計算空缺的長度
                var byts = ms.ToArray();

                if (index2 != -1)
                {
                    byts = writeLen(index3, byts);
                    byts = writeLen(index2, byts);
                }
                byts = writeLen(index1, byts);


                var flag = " PRIVATE KEY";
                if (!usePKCS8)
                {
                    flag = " RSA" + flag;
                }
                return "-----BEGIN" + flag + "-----\n" + RSA_Unit.TextBreak(RSA_Unit.Base64EncodeBytes(byts), 64) + "\n-----END" + flag + "-----";
            }
        }
    }

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/270419.html

標籤:C#

上一篇:你不知道C#只帶有 get 訪問器的屬性是只讀屬性?

下一篇:五分鐘完全弄懂特性

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more