├── README.md └── api-gateway-demo-sign-net ├── App.config ├── Constant ├── Constants.cs ├── ContentType.cs ├── HttpHeader.cs ├── HttpMethod.cs ├── HttpSchema.cs └── SystemHeader.cs ├── Demo.cs ├── Enums └── Method.cs ├── Properties └── AssemblyInfo.cs ├── Util ├── DateUtil.cs ├── DictionaryUtil.cs ├── HttpUtil.cs ├── MessageDigestUtil.cs └── SignUtil.cs └── api-gateway-demo-sign-net.csproj /README.md: -------------------------------------------------------------------------------- 1 | aliyun api gateway request signature demo by net -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Constant/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace aliyun_api_gateway_sdk.Constant 8 | { 9 | public class Constants 10 | { 11 | //签名算法HmacSha256 12 | public const String HMAC_SHA256 = "HmacSHA256"; 13 | //编码UTF-8 14 | public const String ENCODING = "UTF-8"; 15 | //UserAgent 16 | public const String USER_AGENT = "demo/aliyun/net"; 17 | //换行符 18 | public const String LF = "\n"; 19 | //分隔符1 20 | public const String SPE1 = ","; 21 | //分隔符2 22 | public const String SPE2 = ":"; 23 | 24 | //默认请求超时时间,单位毫秒 25 | public const int DEFAULT_TIMEOUT = 1000; 26 | 27 | //参与签名的系统Header前缀,只有指定前缀的Header才会参与到签名中 28 | public const String CA_HEADER_TO_SIGN_PREFIX_SYSTEM = "X-Ca-"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Constant/ContentType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace aliyun_api_gateway_sdk.Constant 8 | { 9 | public class ContentType 10 | { 11 | //表单类型Content-Type 12 | public const String CONTENT_TYPE_FORM = "application/x-www-form-urlencoded; charset=utf-8"; 13 | // 流类型Content-Type 14 | public const String CONTENT_TYPE_STREAM = "application/octet-stream; charset=utf-8"; 15 | //JSON类型Content-Type 16 | public const String CONTENT_TYPE_JSON = "application/json; charset=utf-8"; 17 | //XML类型Content-Type 18 | public const String CONTENT_TYPE_XML = "application/xml; charset=utf-8"; 19 | //文本类型Content-Type 20 | public const String CONTENT_TYPE_TEXT = "application/text; charset=utf-8"; 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Constant/HttpHeader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace aliyun_api_gateway_sdk.Constant 8 | { 9 | public class HttpHeader 10 | { 11 | //请求Header Accept 12 | public const String HTTP_HEADER_ACCEPT = "Accept"; 13 | //请求Body内容MD5 Header 14 | public const String HTTP_HEADER_CONTENT_MD5 = "Content-MD5"; 15 | //请求Header Content-Type 16 | public const String HTTP_HEADER_CONTENT_TYPE = "Content-Type"; 17 | //请求Header UserAgent 18 | public const String HTTP_HEADER_USER_AGENT = "User-Agent"; 19 | //请求Header Date 20 | public const String HTTP_HEADER_DATE = "Date"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Constant/HttpMethod.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace aliyun_api_gateway_sdk.Constant 8 | { 9 | public class HttpMethod 10 | { 11 | //GET 12 | public const String GET = "GET"; 13 | //POST 14 | public const String POST = "POST"; 15 | //PUT 16 | public const String PUT = "PUT"; 17 | //DELETE 18 | public const String DELETE = "DELETE"; 19 | //DELETE 20 | public const String HEAD = "HEAD"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Constant/HttpSchema.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace aliyun_api_gateway_sdk.Constant 8 | { 9 | public class HttpSchema 10 | { 11 | //HTTP 12 | public const String HTTP = "http://"; 13 | //HTTPS 14 | public const String HTTPS = "https://"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Constant/SystemHeader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace aliyun_api_gateway_sdk.Constant 8 | { 9 | public class SystemHeader 10 | { 11 | //签名Header 12 | public const String X_CA_SIGNATURE = "X-Ca-Signature"; 13 | //所有参与签名的Header 14 | public const String X_CA_SIGNATURE_HEADERS = "X-Ca-Signature-Headers"; 15 | //请求时间戳 16 | public const String X_CA_TIMESTAMP = "X-Ca-Timestamp"; 17 | //请求放重放Nonce,15分钟内保持唯一,建议使用UUID 18 | public const String X_CA_NONCE = "X-Ca-Nonce"; 19 | //APP KEY 20 | public const String X_CA_KEY = "X-Ca-Key"; 21 | //请求API所属Stage 22 | public const String X_CA_STAGE = "X-Ca-Stage"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Demo.cs: -------------------------------------------------------------------------------- 1 | using aliyun_api_gateway_sdk.Constant; 2 | using aliyun_api_gateway_sdk.Util; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Net; 8 | using System.Security.Cryptography; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace aliyun_api_gateway_sdk 13 | { 14 | class Demo 15 | { 16 | private const String appKey = "appKey"; 17 | private const String appSecret = "appSecret"; 18 | private const String host = "http://test.alicloudapi.com"; 19 | 20 | static void Main(string[] args) 21 | { 22 | doGet(); 23 | 24 | doPostForm(); 25 | doPostStream(); 26 | doPostString(); 27 | 28 | doPutStream(); 29 | doPutString(); 30 | 31 | doDelete(); 32 | 33 | doHead(); 34 | Console.Read(); 35 | 36 | } 37 | 38 | private static void doGet() { 39 | String path = "/get"; 40 | Dictionary headers = new Dictionary(); 41 | Dictionary querys = new Dictionary(); 42 | List signHeader = new List(); 43 | 44 | //设定Content-Type,根据服务器端接受的值来设置 45 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_TEXT); 46 | //设定Accept,根据服务器端接受的值来设置 47 | headers.Add(HttpHeader.HTTP_HEADER_ACCEPT, ContentType.CONTENT_TYPE_TEXT); 48 | //如果是调用测试环境请设置 49 | //headers.Add(SystemHeader.X_CA_STAGE, "TEST"); 50 | 51 | //注意:业务header部分,如果没有则无此行(如果有中文,请做Utf8ToIso88591处理) 52 | headers.Add("b-header2", MessageDigestUtil.Utf8ToIso88591("headervalue1")); 53 | headers.Add("a-header1", MessageDigestUtil.Utf8ToIso88591("headervalue2处理")); 54 | 55 | //注意:业务query部分,如果没有则无此行;请不要、不要、不要做UrlEncode处理 56 | querys.Add("b-query2", "queryvalue2"); 57 | querys.Add("a-query1", "queryvalue1"); 58 | 59 | 60 | //指定参与签名的header 61 | signHeader.Add(SystemHeader.X_CA_TIMESTAMP); 62 | signHeader.Add("a-header1"); 63 | signHeader.Add("b-header2"); 64 | 65 | using (HttpWebResponse response = HttpUtil.HttpGet(host, path, appKey, appSecret, 30000, headers, querys, signHeader)) 66 | { 67 | Console.WriteLine(response.StatusCode); 68 | Console.WriteLine(response.Method); 69 | Console.WriteLine(response.Headers); 70 | Stream st = response.GetResponseStream(); 71 | StreamReader reader = new StreamReader(st, Encoding.GetEncoding("utf-8")); 72 | Console.WriteLine(reader.ReadToEnd()); 73 | Console.WriteLine(Constants.LF); 74 | 75 | } 76 | } 77 | 78 | private static void doPostForm() { 79 | String path = "/postform"; 80 | 81 | Dictionary headers = new Dictionary(); 82 | Dictionary querys = new Dictionary(); 83 | Dictionary bodys = new Dictionary(); 84 | List signHeader = new List(); 85 | 86 | //设定Content-Type,根据服务器端接受的值来设置 87 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_FORM); 88 | //设定Accept,根据服务器端接受的值来设置 89 | headers.Add(HttpHeader.HTTP_HEADER_ACCEPT, ContentType.CONTENT_TYPE_JSON); 90 | //如果是调用测试环境请设置 91 | //headers.Add(SystemHeader.X_CA_STAGE, "TEST"); 92 | 93 | //注意:业务header部分,如果没有则无此行(如果有中文,请做Utf8ToIso88591处理) 94 | headers.Add("b-header2", MessageDigestUtil.Utf8ToIso88591("headervalue1")); 95 | headers.Add("a-header1", MessageDigestUtil.Utf8ToIso88591("headervalue2处理")); 96 | 97 | //注意:业务query部分,如果没有则无此行;请不要、不要、不要做UrlEncode处理 98 | querys.Add("b-query2", "queryvalue2"); 99 | querys.Add("a-query1", "queryvalue1"); 100 | 101 | //注意:业务body部分,如果没有则无此行;请不要、不要、不要做UrlEncode处理 102 | bodys.Add("b-body2", "bodyvalue1"); 103 | bodys.Add("a-body1", "bodyvalue2"); 104 | 105 | //指定参与签名的header 106 | signHeader.Add(SystemHeader.X_CA_TIMESTAMP); 107 | signHeader.Add("a-header1"); 108 | signHeader.Add("b-header2"); 109 | 110 | using (HttpWebResponse response = HttpUtil.HttpPost(host, path, appKey, appSecret, 30000, headers, querys, bodys, signHeader)) 111 | { 112 | Console.WriteLine(response.StatusCode); 113 | Console.WriteLine(response.Method); 114 | Console.WriteLine(response.Headers); 115 | Stream st = response.GetResponseStream(); 116 | StreamReader reader = new StreamReader(st, Encoding.GetEncoding("utf-8")); 117 | Console.WriteLine(reader.ReadToEnd()); 118 | Console.WriteLine(Constants.LF); 119 | 120 | } 121 | } 122 | 123 | private static void doPostStream() 124 | { 125 | String path = "/poststream"; 126 | 127 | Dictionary headers = new Dictionary(); 128 | Dictionary querys = new Dictionary(); 129 | Dictionary bodys = new Dictionary(); 130 | List signHeader = new List(); 131 | byte[] bobyContent = new byte[10]; 132 | 133 | //设定Content-Type,根据服务器端接受的值来设置 134 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_STREAM); 135 | //设定Accept,根据服务器端接受的值来设置 136 | headers.Add(HttpHeader.HTTP_HEADER_ACCEPT, ContentType.CONTENT_TYPE_JSON); 137 | 138 | //注意:如果有非Form形式数据(body中只有value,没有key);如果body中是key/value形式数据,不要指定此行 139 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_MD5, MessageDigestUtil.Base64AndMD5(bobyContent)); 140 | //如果是调用测试环境请设置 141 | //headers.Add(SystemHeader.X_CA_STAGE, "TEST"); 142 | 143 | //注意:业务header部分,如果没有则无此行(如果有中文,请做Utf8ToIso88591处理) 144 | headers.Add("b-header2", MessageDigestUtil.Utf8ToIso88591("headervalue1")); 145 | headers.Add("a-header1", MessageDigestUtil.Utf8ToIso88591("headervalue2处理")); 146 | 147 | //注意:业务query部分,如果没有则无此行;请不要、不要、不要做UrlEncode处理 148 | querys.Add("b-query2", "queryvalue2"); 149 | querys.Add("a-query1", "queryvalue1"); 150 | 151 | //注意:业务body部分 152 | bodys.Add("", BitConverter.ToString(bobyContent)); 153 | 154 | //指定参与签名的header 155 | signHeader.Add(SystemHeader.X_CA_TIMESTAMP); 156 | signHeader.Add("a-header1"); 157 | signHeader.Add("b-header2"); 158 | 159 | using (HttpWebResponse response = HttpUtil.HttpPost(host, path, appKey, appSecret, 30000, headers, querys, bodys, signHeader)) 160 | { 161 | Console.WriteLine(response.StatusCode); 162 | Console.WriteLine(response.Method); 163 | Console.WriteLine(response.Headers); 164 | Stream st = response.GetResponseStream(); 165 | StreamReader reader = new StreamReader(st, Encoding.GetEncoding("utf-8")); 166 | Console.WriteLine(reader.ReadToEnd()); 167 | Console.WriteLine(Constants.LF); 168 | 169 | } 170 | } 171 | 172 | private static void doPostString() 173 | { 174 | String bobyContent = "{\"inputs\": [{\"image\": {\"dataType\": 50,\"dataValue\": \"base64_image_string(此行)\"},\"configure\": {\"dataType\": 50,\"dataValue\": \"{\"side\":\"face(#此行此行)\"}\"}}]}"; 175 | 176 | String path = "/poststring"; 177 | Dictionary headers = new Dictionary(); 178 | Dictionary querys = new Dictionary(); 179 | Dictionary bodys = new Dictionary(); 180 | List signHeader = new List(); 181 | 182 | //设定Content-Type,根据服务器端接受的值来设置 183 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_JSON); 184 | //设定Accept,根据服务器端接受的值来设置 185 | headers.Add(HttpHeader.HTTP_HEADER_ACCEPT, ContentType.CONTENT_TYPE_JSON); 186 | 187 | //注意:如果有非Form形式数据(body中只有value,没有key);如果body中是key/value形式数据,不要指定此行 188 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_MD5, MessageDigestUtil.Base64AndMD5(Encoding.UTF8.GetBytes(bobyContent))); 189 | //如果是调用测试环境请设置 190 | //headers.Add(SystemHeader.X_CA_STAGE, "TEST"); 191 | 192 | //注意:业务header部分,如果没有则无此行(如果有中文,请做Utf8ToIso88591处理) 193 | headers.Add("b-header2", MessageDigestUtil.Utf8ToIso88591("headervalue1")); 194 | headers.Add("a-header1", MessageDigestUtil.Utf8ToIso88591("headervalue2处理")); 195 | 196 | //注意:业务query部分,如果没有则无此行;请不要、不要、不要做UrlEncode处理 197 | querys.Add("b-query2", "queryvalue2"); 198 | querys.Add("a-query1", "queryvalue1"); 199 | 200 | //注意:业务body部分 201 | bodys.Add("", bobyContent); 202 | 203 | //指定参与签名的header 204 | signHeader.Add(SystemHeader.X_CA_TIMESTAMP); 205 | signHeader.Add("a-header1"); 206 | signHeader.Add("b-header2"); 207 | 208 | using (HttpWebResponse response = HttpUtil.HttpPost(host, path, appKey, appSecret, 30000, headers, querys, bodys, signHeader)) 209 | { 210 | Console.WriteLine(response.StatusCode); 211 | Console.WriteLine(response.Method); 212 | Console.WriteLine(response.Headers); 213 | Stream st = response.GetResponseStream(); 214 | StreamReader reader = new StreamReader(st, Encoding.GetEncoding("utf-8")); 215 | Console.WriteLine(reader.ReadToEnd()); 216 | Console.WriteLine(Constants.LF); 217 | 218 | } 219 | } 220 | 221 | private static void doPutStream() 222 | { 223 | String path = "/putstream"; 224 | 225 | Dictionary headers = new Dictionary(); 226 | Dictionary querys = new Dictionary(); 227 | Dictionary bodys = new Dictionary(); 228 | List signHeader = new List(); 229 | byte[] bobyContent = new byte[10]; 230 | 231 | //设定Content-Type,根据服务器端接受的值来设置 232 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_STREAM); 233 | //设定Accept,根据服务器端接受的值来设置 234 | headers.Add(HttpHeader.HTTP_HEADER_ACCEPT, ContentType.CONTENT_TYPE_JSON); 235 | 236 | //注意:如果有非Form形式数据(body中只有value,没有key);如果body中是key/value形式数据,不要指定此行 237 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_MD5, MessageDigestUtil.Base64AndMD5(bobyContent)); 238 | //如果是调用测试环境请设置 239 | //headers.Add(SystemHeader.X_CA_STAGE, "TEST"); 240 | 241 | //注意:业务header部分,如果没有则无此行(如果有中文,请做Utf8ToIso88591处理) 242 | headers.Add("b-header2", MessageDigestUtil.Utf8ToIso88591("headervalue1")); 243 | headers.Add("a-header1", MessageDigestUtil.Utf8ToIso88591("headervalue2处理")); 244 | 245 | //注意:业务query部分,如果没有则无此行;请不要、不要、不要做UrlEncode处理 246 | querys.Add("b-query2", "queryvalue2"); 247 | querys.Add("a-query1", "queryvalue1"); 248 | 249 | //注意:业务body部分 250 | bodys.Add("", BitConverter.ToString(bobyContent)); 251 | 252 | //指定参与签名的header 253 | signHeader.Add(SystemHeader.X_CA_TIMESTAMP); 254 | signHeader.Add("a-header1"); 255 | signHeader.Add("b-header2"); 256 | 257 | using (HttpWebResponse response = HttpUtil.HttpPut(host, path, appKey, appSecret, 30000, headers, querys, bodys, signHeader)) 258 | { 259 | Console.WriteLine(response.StatusCode); 260 | Console.WriteLine(response.Method); 261 | Console.WriteLine(response.Headers); 262 | Stream st = response.GetResponseStream(); 263 | StreamReader reader = new StreamReader(st, Encoding.GetEncoding("utf-8")); 264 | Console.WriteLine(reader.ReadToEnd()); 265 | Console.WriteLine(Constants.LF); 266 | 267 | } 268 | } 269 | 270 | private static void doPutString() 271 | { 272 | String bobyContent = "{\"inputs\": [{\"image\": {\"dataType\": 50,\"dataValue\": \"base64_image_string(此行)\"},\"configure\": {\"dataType\": 50,\"dataValue\": \"{\"side\":\"face(#此行此行)\"}\"}}]}"; 273 | 274 | String path = "/putstring"; 275 | Dictionary headers = new Dictionary(); 276 | Dictionary querys = new Dictionary(); 277 | Dictionary bodys = new Dictionary(); 278 | List signHeader = new List(); 279 | 280 | //设定Content-Type,根据服务器端接受的值来设置 281 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_JSON); 282 | //设定Accept,根据服务器端接受的值来设置 283 | headers.Add(HttpHeader.HTTP_HEADER_ACCEPT, ContentType.CONTENT_TYPE_JSON); 284 | 285 | //注意:如果有非Form形式数据(body中只有value,没有key);如果body中是key/value形式数据,不要指定此行 286 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_MD5, MessageDigestUtil.Base64AndMD5(Encoding.UTF8.GetBytes(bobyContent))); 287 | //如果是调用测试环境请设置 288 | //headers.Add(SystemHeader.X_CA_STAGE, "TEST"); 289 | 290 | //注意:业务header部分,如果没有则无此行(如果有中文,请做Utf8ToIso88591处理) 291 | headers.Add("b-header2", MessageDigestUtil.Utf8ToIso88591("headervalue1")); 292 | headers.Add("a-header1", MessageDigestUtil.Utf8ToIso88591("headervalue2处理")); 293 | 294 | //注意:业务query部分,如果没有则无此行;请不要、不要、不要做UrlEncode处理 295 | querys.Add("b-query2", "queryvalue2"); 296 | querys.Add("a-query1", "queryvalue1"); 297 | 298 | //注意:业务body部分 299 | bodys.Add("", bobyContent); 300 | 301 | //指定参与签名的header 302 | signHeader.Add(SystemHeader.X_CA_TIMESTAMP); 303 | signHeader.Add("a-header1"); 304 | signHeader.Add("b-header2"); 305 | 306 | using (HttpWebResponse response = HttpUtil.HttpPut(host, path, appKey, appSecret, 30000, headers, querys, bodys, signHeader)) 307 | { 308 | Console.WriteLine(response.StatusCode); 309 | Console.WriteLine(response.Method); 310 | Console.WriteLine(response.Headers); 311 | Stream st = response.GetResponseStream(); 312 | StreamReader reader = new StreamReader(st, Encoding.GetEncoding("utf-8")); 313 | Console.WriteLine(reader.ReadToEnd()); 314 | Console.WriteLine(Constants.LF); 315 | 316 | } 317 | } 318 | 319 | private static void doDelete() 320 | { 321 | String path = "/delete"; 322 | Dictionary headers = new Dictionary(); 323 | Dictionary querys = new Dictionary(); 324 | List signHeader = new List(); 325 | 326 | //设定Content-Type,根据服务器端接受的值来设置 327 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_JSON); 328 | //设定Accept,根据服务器端接受的值来设置 329 | headers.Add(HttpHeader.HTTP_HEADER_ACCEPT, ContentType.CONTENT_TYPE_JSON); 330 | //如果是调用测试环境请设置 331 | //headers.Add(SystemHeader.X_CA_STAGE, "TEST"); 332 | 333 | //注意:业务header部分,如果没有则无此行(如果有中文,请做Utf8ToIso88591处理) 334 | headers.Add("b-header2", MessageDigestUtil.Utf8ToIso88591("headervalue1")); 335 | headers.Add("a-header1", MessageDigestUtil.Utf8ToIso88591("headervalue2处理")); 336 | 337 | //注意:业务query部分,如果没有则无此行;请不要、不要、不要做UrlEncode处理 338 | querys.Add("b-query2", "queryvalue2"); 339 | querys.Add("a-query1", "queryvalue1"); 340 | 341 | //指定参与签名的header 342 | signHeader.Add(SystemHeader.X_CA_TIMESTAMP); 343 | signHeader.Add("a-header1"); 344 | signHeader.Add("b-header2"); 345 | 346 | using (HttpWebResponse response = HttpUtil.HttpDelete(host, path, appKey, appSecret, 30000, headers, querys, signHeader)) 347 | { 348 | Console.WriteLine(response.StatusCode); 349 | Console.WriteLine(response.Method); 350 | Console.WriteLine(response.Headers); 351 | Stream st = response.GetResponseStream(); 352 | StreamReader reader = new StreamReader(st, Encoding.GetEncoding("utf-8")); 353 | Console.WriteLine(reader.ReadToEnd()); 354 | Console.WriteLine(Constants.LF); 355 | 356 | } 357 | } 358 | 359 | private static void doHead() 360 | { 361 | String path = "/head"; 362 | 363 | Dictionary headers = new Dictionary(); 364 | Dictionary querys = new Dictionary(); 365 | List signHeader = new List(); 366 | 367 | //设定Content-Type,根据服务器端接受的值来设置 368 | headers.Add(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_JSON); 369 | //设定Accept,根据服务器端接受的值来设置 370 | headers.Add(HttpHeader.HTTP_HEADER_ACCEPT, ContentType.CONTENT_TYPE_JSON); 371 | //如果是调用测试环境请设置 372 | //headers.Add(SystemHeader.X_CA_STAGE, "TEST"); 373 | 374 | //注意:业务header部分,如果没有则无此行(如果有中文,请做Utf8ToIso88591处理) 375 | headers.Add("b-header2", MessageDigestUtil.Utf8ToIso88591("headervalue1")); 376 | headers.Add("a-header1", MessageDigestUtil.Utf8ToIso88591("headervalue2处理")); 377 | 378 | //注意:业务query部分,如果没有则无此行;请不要、不要、不要做UrlEncode处理 379 | querys.Add("b-query2", "queryvalue2"); 380 | querys.Add("a-query1", "queryvalue1"); 381 | 382 | //指定参与签名的header 383 | signHeader.Add(SystemHeader.X_CA_TIMESTAMP); 384 | signHeader.Add("a-header1"); 385 | signHeader.Add("b-header2"); 386 | 387 | using (HttpWebResponse response = HttpUtil.HttpHead(host, path, appKey, appSecret, 30000, headers, querys, signHeader)) 388 | { 389 | Console.WriteLine(response.StatusCode); 390 | Console.WriteLine(response.Method); 391 | Console.WriteLine(response.Headers); 392 | Stream st = response.GetResponseStream(); 393 | StreamReader reader = new StreamReader(st, Encoding.GetEncoding("utf-8")); 394 | Console.WriteLine(reader.ReadToEnd()); 395 | Console.WriteLine(Constants.LF); 396 | 397 | } 398 | } 399 | 400 | } 401 | } 402 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Enums/Method.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace aliyun_api_gateway_sdk.Enums 8 | { 9 | public enum Method 10 | { 11 | GET, POST_FORM, POST_STRING, POST_BYTES, PUT_STRING, PUT_BYTES, DELETE 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过以下 6 | // 特性集控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("api-gateway-demo-sign-net")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("api-gateway-demo-sign-net")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 使此程序集中的类型 18 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, 19 | // 则将该类型上的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("75a3b33d-01ca-4b4a-bea5-baf5e5beb8d7")] 24 | 25 | // 程序集的版本信息由下面四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Util/DateUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace aliyun_api_gateway_sdk.Util 9 | { 10 | public class DateUtil 11 | { 12 | private const string ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; 13 | 14 | public static string FormatIso8601Date(DateTime date) 15 | { 16 | return date.ToUniversalTime().ToString(ISO8601_DATE_FORMAT, CultureInfo.CreateSpecificCulture("en-US")); 17 | } 18 | 19 | public static String ConvertDateTimeInt(DateTime time) 20 | { 21 | double intResult = 0; 22 | DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); 23 | intResult = (time - startTime).TotalMilliseconds; 24 | return Convert.ToInt64(intResult).ToString(); ; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Util/DictionaryUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace aliyun_api_gateway_sdk.Util 8 | { 9 | public class DictionaryUtil 10 | { 11 | public static void Add(Dictionary dic, string key, T value) 12 | { 13 | if (null == value) 14 | { 15 | return; 16 | } 17 | if (dic == null) 18 | { 19 | dic = new Dictionary(); 20 | } 21 | else if (dic.ContainsKey(key)) 22 | { 23 | dic.Remove(key); 24 | } 25 | dic.Add(key, value.ToString()); 26 | } 27 | 28 | public static string Get(Dictionary dic, string key) 29 | { 30 | if (dic.ContainsKey(key)) 31 | { 32 | return dic[key]; 33 | } 34 | return null; 35 | } 36 | 37 | public static string Pop(Dictionary dic, string key) 38 | { 39 | string value = null; 40 | if (dic.ContainsKey(key)) 41 | { 42 | value = dic[key]; 43 | dic.Remove(key); 44 | } 45 | return value; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Util/HttpUtil.cs: -------------------------------------------------------------------------------- 1 | using aliyun_api_gateway_sdk.Constant; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Net.Security; 8 | using System.Web; 9 | using System.Security.Cryptography.X509Certificates; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace aliyun_api_gateway_sdk.Util 14 | { 15 | public class HttpUtil 16 | { 17 | public static HttpWebResponse HttpPost(String host, String path, String appKey, String appSecret, int timeout, Dictionary headers, Dictionary querys, Dictionary bodys, List signHeaderPrefixList) 18 | { 19 | return DoHttp(host, path, HttpMethod.POST, appKey, appSecret, timeout, headers, querys, bodys, signHeaderPrefixList); 20 | } 21 | 22 | public static HttpWebResponse HttpPut(String host, String path, String appKey, String appSecret, int timeout, Dictionary headers, Dictionary querys, Dictionary bodys, List signHeaderPrefixList) 23 | { 24 | return DoHttp(host, path, HttpMethod.PUT, appKey, appSecret, timeout, headers, querys, bodys, signHeaderPrefixList); 25 | } 26 | 27 | public static HttpWebResponse HttpGet(String host, String path, String appKey, String appSecret, int timeout, Dictionary headers, Dictionary querys, List signHeaderPrefixList) 28 | { 29 | return DoHttp(host, path, HttpMethod.GET, appKey, appSecret, timeout, headers, querys, null, signHeaderPrefixList); 30 | } 31 | 32 | public static HttpWebResponse HttpHead(String host, String path, String appKey, String appSecret, int timeout, Dictionary headers, Dictionary querys, List signHeaderPrefixList) 33 | { 34 | return DoHttp(host, path, HttpMethod.HEAD, appKey, appSecret, timeout, headers, querys, null, signHeaderPrefixList); 35 | } 36 | 37 | public static HttpWebResponse HttpDelete(String host, String path, String appKey, String appSecret, int timeout, Dictionary headers, Dictionary querys, List signHeaderPrefixList) 38 | { 39 | return DoHttp(host, path, HttpMethod.DELETE, appKey, appSecret, timeout, headers, querys, null, signHeaderPrefixList); 40 | } 41 | 42 | 43 | 44 | 45 | 46 | private static HttpWebResponse DoHttp(String host, String path, String method, String appKey, String appSecret, int timeout, Dictionary headers, Dictionary querys, Dictionary bodys, List signHeaderPrefixList) 47 | { 48 | headers = InitialBasicHeader(path, appKey, appSecret, method, headers, querys, bodys, signHeaderPrefixList); 49 | HttpWebRequest httpRequest = InitHttpRequest(host, path, method, timeout, headers, querys); 50 | 51 | if (null != bodys && 0 < bodys.Count) 52 | { 53 | StringBuilder sb = new StringBuilder(); 54 | foreach (var param in bodys) 55 | { 56 | if (0 < sb.Length) 57 | { 58 | sb.Append("&"); 59 | } 60 | if (null != param.Value && 0 == param.Key.Length) 61 | { 62 | sb.Append(param.Value); 63 | } 64 | if (0 < param.Key.Length) 65 | { 66 | sb.Append(param.Key).Append("="); 67 | if (null != param.Value) 68 | { 69 | sb.Append(HttpUtility.UrlEncode(param.Value, Encoding.UTF8)); 70 | } 71 | } 72 | } 73 | byte[] data = Encoding.UTF8.GetBytes(sb.ToString()); 74 | using (Stream stream = httpRequest.GetRequestStream()) 75 | { 76 | stream.Write(data, 0, data.Length); 77 | } 78 | } 79 | 80 | HttpWebResponse httpResponse = GetResponse(httpRequest); 81 | return httpResponse; 82 | } 83 | 84 | private static HttpWebResponse GetResponse(HttpWebRequest httpRequest) 85 | { 86 | HttpWebResponse httpResponse = null; 87 | try 88 | { 89 | WebResponse response = httpRequest.GetResponse(); 90 | httpResponse = (HttpWebResponse)response; 91 | 92 | } 93 | catch (WebException ex) 94 | { 95 | httpResponse = (HttpWebResponse)ex.Response; 96 | } 97 | return httpResponse; 98 | } 99 | 100 | private static HttpWebRequest InitHttpRequest(String host, String path, String method, int timeout, Dictionary headers, Dictionary querys) 101 | { 102 | HttpWebRequest httpRequest = null; 103 | String url = host; 104 | if (null != path) 105 | { 106 | url = url + path; 107 | } 108 | 109 | if (null != querys && 0 < querys.Count) 110 | { 111 | StringBuilder sb = new StringBuilder(); 112 | foreach (var param in querys) 113 | { 114 | if (0 < sb.Length) 115 | { 116 | sb.Append("&"); 117 | } 118 | if (null != param.Value && null == param.Key) 119 | { 120 | sb.Append(param.Value); 121 | } 122 | if (null != param.Key) 123 | { 124 | sb.Append(param.Key).Append("="); 125 | if (null != param.Value) 126 | { 127 | sb.Append(HttpUtility.UrlEncode(param.Value, Encoding.UTF8)); 128 | } 129 | } 130 | } 131 | if (0 < sb.Length) 132 | { 133 | url = url + "?" + sb.ToString(); 134 | } 135 | } 136 | 137 | if (host.Contains("https://")) 138 | { 139 | ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); 140 | httpRequest = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url)); 141 | } 142 | else 143 | { 144 | httpRequest = (HttpWebRequest)WebRequest.Create(url); 145 | } 146 | httpRequest.ServicePoint.Expect100Continue = false; 147 | httpRequest.Method = method; 148 | httpRequest.KeepAlive = true; 149 | httpRequest.Timeout = timeout; 150 | 151 | if (headers.ContainsKey("Accept")) 152 | { 153 | httpRequest.Accept = DictionaryUtil.Pop(headers, "Accept"); 154 | } 155 | if (headers.ContainsKey("Date")) 156 | { 157 | httpRequest.Date = Convert.ToDateTime(DictionaryUtil.Pop(headers, "Date")); 158 | } 159 | if (headers.ContainsKey(HttpHeader.HTTP_HEADER_CONTENT_TYPE)) 160 | { 161 | httpRequest.ContentType = DictionaryUtil.Pop(headers, HttpHeader.HTTP_HEADER_CONTENT_TYPE); 162 | } 163 | 164 | foreach (var header in headers) 165 | { 166 | httpRequest.Headers.Add(header.Key, header.Value); 167 | } 168 | return httpRequest; 169 | } 170 | 171 | 172 | private static Dictionary InitialBasicHeader(String path, String appKey, String appSecret, String method, Dictionary headers, Dictionary querys, Dictionary bodys, List signHeaderPrefixList) 173 | { 174 | if (headers == null) 175 | { 176 | headers = new Dictionary(); 177 | } 178 | 179 | StringBuilder sb = new StringBuilder(); 180 | //时间戳 181 | headers.Add(SystemHeader.X_CA_TIMESTAMP, DateUtil.ConvertDateTimeInt(DateTime.Now).ToString()); 182 | //防重放,协议层不能进行重试,否则会报NONCE被使用;如果需要协议层重试,请注释此行 183 | headers.Add(SystemHeader.X_CA_NONCE, Guid.NewGuid().ToString()); 184 | headers.Add(SystemHeader.X_CA_KEY, appKey); 185 | headers.Add(SystemHeader.X_CA_SIGNATURE, SignUtil.Sign(path, method, appSecret, headers, querys, bodys, signHeaderPrefixList)); 186 | 187 | return headers; 188 | } 189 | 190 | 191 | public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) 192 | { 193 | return true; 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Util/MessageDigestUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace aliyun_api_gateway_sdk.Util 9 | { 10 | public class MessageDigestUtil 11 | { 12 | public static string Base64AndMD5(string input) { 13 | if (input == null || input.Length == 0) 14 | { 15 | throw new Exception("input can not be null"); 16 | } 17 | byte[] bytes = Encoding.UTF8.GetBytes(input); 18 | return Base64AndMD5(bytes); 19 | } 20 | 21 | public static String Base64AndMD5(byte[] bytes) { 22 | MD5 md5 = new MD5CryptoServiceProvider(); 23 | byte[] data = md5.ComputeHash(bytes); 24 | 25 | return Convert.ToBase64String(data); 26 | } 27 | 28 | /** 29 | * UTF-8编码转换为ISO-9959-1 30 | * 31 | * @param str 32 | * @return 33 | */ 34 | public static String Utf8ToIso88591(String input) 35 | { 36 | if (input == null) 37 | { 38 | return input; 39 | } 40 | 41 | try 42 | { 43 | return Encoding.Default.GetString(Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1"), Encoding.UTF8.GetBytes(input))); 44 | } 45 | catch (Exception e) 46 | { 47 | return input; 48 | } 49 | } 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/Util/SignUtil.cs: -------------------------------------------------------------------------------- 1 | using aliyun_api_gateway_sdk.Constant; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Security.Cryptography; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace aliyun_api_gateway_sdk.Util 10 | { 11 | public class SignUtil 12 | { 13 | public static string Sign(String path, String method, String secret, Dictionary headers, Dictionary querys, Dictionary bodys, List signHeaderPrefixList) 14 | { 15 | using (var algorithm = KeyedHashAlgorithm.Create("HMACSHA256")) 16 | { 17 | algorithm.Key = Encoding.UTF8.GetBytes(secret.ToCharArray()); 18 | String signStr = BuildStringToSign(path, method, headers, querys, bodys, signHeaderPrefixList); 19 | return Convert.ToBase64String(algorithm.ComputeHash(Encoding.UTF8.GetBytes(signStr.ToCharArray()))); 20 | } 21 | } 22 | 23 | private static String BuildStringToSign(String path, String method, Dictionary headers, Dictionary querys, Dictionary bodys, List signHeaderPrefixList) 24 | { 25 | StringBuilder sb = new StringBuilder(); 26 | 27 | sb.Append(method.ToUpper()).Append(Constants.LF); 28 | if (headers.ContainsKey(HttpHeader.HTTP_HEADER_ACCEPT) && headers[HttpHeader.HTTP_HEADER_ACCEPT] != null) 29 | { 30 | sb.Append(headers[HttpHeader.HTTP_HEADER_ACCEPT]); 31 | } 32 | sb.Append(Constants.LF); 33 | if (headers.ContainsKey(HttpHeader.HTTP_HEADER_CONTENT_MD5) && headers[HttpHeader.HTTP_HEADER_CONTENT_MD5] != null) 34 | { 35 | sb.Append(headers[HttpHeader.HTTP_HEADER_CONTENT_MD5]); 36 | } 37 | sb.Append(Constants.LF); 38 | if (headers.ContainsKey(HttpHeader.HTTP_HEADER_CONTENT_TYPE) && headers[HttpHeader.HTTP_HEADER_CONTENT_TYPE] != null) 39 | { 40 | sb.Append(headers[HttpHeader.HTTP_HEADER_CONTENT_TYPE]); 41 | } 42 | sb.Append(Constants.LF); 43 | if (headers.ContainsKey(HttpHeader.HTTP_HEADER_DATE) && headers[HttpHeader.HTTP_HEADER_DATE] != null) 44 | { 45 | sb.Append(headers[HttpHeader.HTTP_HEADER_DATE]); 46 | } 47 | sb.Append(Constants.LF); 48 | sb.Append(BuildHeaders(headers, signHeaderPrefixList)); 49 | sb.Append(BuildResource(path, querys, bodys)); 50 | 51 | return sb.ToString(); 52 | } 53 | 54 | /** 55 | * 构建待签名Path+Query+FormParams 56 | * 57 | * @param url Path+Query 58 | * @param formParamMap POST表单参数 59 | * @return 待签名Path+Query+FormParams 60 | */ 61 | private static String BuildResource(String path, Dictionary querys, Dictionary bodys) 62 | { 63 | StringBuilder sb = new StringBuilder(); 64 | if (null != path) 65 | { 66 | sb.Append(path); 67 | } 68 | StringBuilder sbParam = new StringBuilder(); 69 | IDictionary sortParams = new SortedDictionary(StringComparer.Ordinal); 70 | 71 | //query参与签名 72 | if (querys != null && querys.Count > 0) 73 | { 74 | foreach (var param in querys) 75 | { 76 | if (0 < param.Key.Length) 77 | { 78 | sortParams.Add(param.Key, param.Value); 79 | } 80 | } 81 | } 82 | 83 | //body参与签名 84 | if (bodys != null && bodys.Count > 0) 85 | { 86 | foreach (var param in bodys) 87 | { 88 | if (0 < param.Key.Length) 89 | { 90 | sortParams.Add(param.Key, param.Value); 91 | } 92 | } 93 | } 94 | //参数Key 95 | foreach (var param in sortParams) 96 | { 97 | if (0 < param.Key.Length) 98 | { 99 | if (0 < sbParam.Length) 100 | { 101 | sbParam.Append("&"); 102 | } 103 | sbParam.Append(param.Key); 104 | if (!String.IsNullOrEmpty(param.Value)) 105 | { 106 | sbParam.Append("=").Append(param.Value); 107 | } 108 | } 109 | } 110 | if (0 < sbParam.Length) 111 | { 112 | sb.Append("?").Append(sbParam); 113 | } 114 | 115 | return sb.ToString(); 116 | } 117 | 118 | 119 | /** 120 | * 构建待签名Http头 121 | * 122 | * @param headers 请求中所有的Http头 123 | * @param signHeaderPrefixList 自定义参与签名Header前缀 124 | * @return 待签名Http头 125 | */ 126 | private static String BuildHeaders(Dictionary headers, List signHeaderPrefixList) 127 | { 128 | StringBuilder sb = new StringBuilder(); 129 | 130 | if (null != signHeaderPrefixList) 131 | { 132 | //剔除X-Ca-Signature/X-Ca-Signature-Headers/Accept/Content-MD5/Content-Type/Date 133 | signHeaderPrefixList.Remove("X-Ca-Signature"); 134 | signHeaderPrefixList.Remove("X-Ca-Signature-Headers"); 135 | signHeaderPrefixList.Remove("Accept"); 136 | signHeaderPrefixList.Remove("Content-MD5"); 137 | signHeaderPrefixList.Remove("Content-Type"); 138 | signHeaderPrefixList.Remove("Date"); 139 | signHeaderPrefixList.Sort(StringComparer.Ordinal); 140 | } 141 | 142 | //Dictionary headersToSign = new Dictionary(); 143 | if (null != headers) 144 | { 145 | IDictionary sortedParams = new SortedDictionary(headers, StringComparer.Ordinal); 146 | StringBuilder signHeadersStringBuilder = new StringBuilder(); 147 | 148 | foreach (var param in sortedParams) 149 | { 150 | if (IsHeaderToSign(param.Key, signHeaderPrefixList)) 151 | { 152 | sb.Append(param.Key).Append(Constants.SPE2); 153 | if (null != param.Value) 154 | { 155 | sb.Append(param.Value); 156 | } 157 | sb.Append(Constants.LF); 158 | if (0 < signHeadersStringBuilder.Length) 159 | { 160 | signHeadersStringBuilder.Append(Constants.SPE1); 161 | } 162 | signHeadersStringBuilder.Append(param.Key); 163 | } 164 | } 165 | 166 | headers.Add(SystemHeader.X_CA_SIGNATURE_HEADERS, signHeadersStringBuilder.ToString()); 167 | } 168 | 169 | return sb.ToString(); 170 | } 171 | 172 | 173 | /** 174 | * Http头是否参与签名 175 | * return 176 | */ 177 | private static bool IsHeaderToSign(String headerName, List signHeaderPrefixList) 178 | { 179 | if (String.IsNullOrEmpty(headerName)) 180 | { 181 | return false; 182 | } 183 | 184 | if (headerName.StartsWith(Constants.CA_HEADER_TO_SIGN_PREFIX_SYSTEM)) 185 | { 186 | return true; 187 | } 188 | 189 | if (signHeaderPrefixList != null) 190 | { 191 | foreach (var signHeaderPrefix in signHeaderPrefixList) 192 | { 193 | if (headerName.StartsWith(signHeaderPrefix)) 194 | { 195 | return true; 196 | } 197 | } 198 | } 199 | 200 | return false; 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /api-gateway-demo-sign-net/api-gateway-demo-sign-net.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {EAA50ED8-62E2-43DD-9C15-21DFA580BF2E} 8 | Exe 9 | Properties 10 | aliyun_api_gateway_sdk 11 | aliyun-api-gateway-sdk 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 72 | --------------------------------------------------------------------------------