HttpWebRequest HttpVersion

时间:2016-01-12 16:24:14

标签: c# api httpwebrequest

我有一个Python代码段来连接有效的API。

我想要做的是使用C#复制相同的代码片段但没有运气..

我得到了异常The remote server returned an error: (401) Unauthorized. - 所以下一步找出代码之间的差异就是使用fiddler,我看到的第一个不同的东西是:

  • CONNECT api.stg.xxx.org:443 HTTP/1.1使用C#时,
  • 使用Python时
  • CONNECT api.stg.XXX.org:443 HTTP/1.0

所以我尝试设置协议:req.ProtocolVersion = HttpVersion.Version10;

其中req是HttpWebRequest

但是当我用fiddler看时 - HTTP标头仍然是: CONNECT api.stg.printopt.org:443 HTTP/1.1

我错过了什么吗? (401) Unauthorized.可以相关吗?

使用Python代码

#!/usr/bin/python

__author__ = 'xxx'

import requests, json, hmac, hashlib, datetime, base64, string, random

def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

def create_headers(method, path, timestamp):
    string_to_sign = method + ' ' + path + ' ' + timestamp
    #print(string_to_sign)
    signature = hmac.new(secret, string_to_sign, hashlib.sha1).hexdigest()
    xxx_auth = token + ':' + signature


    return {'content-type': 'application/json',
        'x-xxx-authorization': xxx_auth,
        'x-xxx-date': timestamp}

def xxx_request(method, path, data):
    timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print(timestamp)
    url = endpoint + path
    headers = create_headers(method, path, timestamp)
    result = requests.post(url, data, headers=headers)
    return result.content

def validate_order(order):
    print ("Validating Order")
    return xxx_request("POST", '/api/order/validate', order)

def submit_order(order):
    print ("Submitting Order")
    return xxx_request("POST", '/api/order', order)


#access credentials
token = '12345'
secret = '54321'
endpoint = "https://api.stg.url.org/workflow"

#Here are the variables required for a single item order
#this is not a full set of fields available
destination = 'dest'
orderId = id_generator()
itemId = id_generator()
postbackAddress = "http://postback.xxx.com"
sku = "Business Cards"
quantity = 1
fetchPath = "https://Server/Path/business_cards.pdf"
componentCode = "Content"
shipTo = {
    "name":           "John Doe",
    "address1":       "5th Avenue",
    "town":           "New York",
    "postcode":       "12345",
    "state":          "New York",
    "isoCountry":     "US",
    "email":          "johnd@acme.com",
    "phone":          "01234567890"
}
carrier = {
    "code":       "customer",
    "service":    "pickup"
}

#nothing to change below here

#create an item - this goes into the order below
item = {
    "sourceItemId":         itemId,
    "sku":                  sku,
    "quantity":             quantity,
    "components": [{
        "code":               componentCode,
        "path":               fetchPath,
        "fetch":              "true"
    }]
}

#create a shipment - this goes into the order below
shipment = {
    "shipTo":  shipTo,
    "carrier": carrier
}

#put together the complete order
order = {
  "destination": {
    "name":       destination
  },
  "orderData": {
    "sourceOrderId":        orderId,
    "postbackAddress":      postbackAddress,
    "items": [ item ],
    "shipments": [ shipment ]
  }
}

#validate the order
print (validate_order(json.dumps(order)))


#finally, submit the order
#print (submit_order(json.dumps(order)))

C# - 制作The remote server returned an error: (401) Unauthorized.

using Newtonsoft.Json;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Cache;
using System.Security.Cryptography;
using System.Text;

namespace urlIntegration_Demo
{
    public class Program
    {
        // access credentials
        static string token = "12345";
        static string secret = "54321";
        static string endpoint = "https://api.stg.url.org/workflow";

        static void Main(string[] args)
        {
            url_request("POST", "/api/order/validate", "");
        }

        private static string id_generator()
        {
            int size = 6;
            var random = new Random((int)DateTime.Now.Ticks);
            string input = "abcdefghijklmnopqrstuvwxyz0123456789";

            var chars = Enumerable.Range(0, size)
                                   .Select(x => input[random.Next(0, input.Length)]);
            return new string(chars.ToArray());
        } 

        // http://stackoverflow.com/questions/11790599/python-hmac-and-c-sharp-hmac
        public static string ToHexString(byte[] array)
        {
            StringBuilder hex = new StringBuilder(array.Length * 2);
            foreach (byte b in array)
            {
                hex.AppendFormat("{0:x2}", b);
            }
            return hex.ToString();
        }

        public static String HashMe(string string_to_sign)
        {
            ASCIIEncoding encoder = new ASCIIEncoding();
            Byte[] code = encoder.GetBytes(secret);
            HMACSHA1 hmSha1 = new HMACSHA1(code);
            Byte[] hashMe = encoder.GetBytes(string_to_sign);
            Byte[] hmBytes = hmSha1.ComputeHash(hashMe);
            return ToHexString(hmBytes);
        }

        #region exampleJson
        static string exampleJson = " {\"orderData\": {\"shipments\": [{\"shipTo\": {\"town\": \"New York\", \"isoCountry\": \"US\", \"state\": \"New York\", \"name\": \"John Doe\", \"phone\": \"01234567890\", \"address1\": \"5th Avenue\", \"email\": \"johnd@acme.com\", \"postcode\": \"12345\"}, \"carrier\": {\"code\": \"customer\", \"service\": \"pickup\"}}], \"items\": [{\"sku\": \"Business Cards\", \"sourceItemId\": \"KIDJ7J\", \"components\": [{\"path\": \"https://Server/Path/business_cards.pdf\",\"code\": \"Content\", \"fetch\": \"true\"}], \"quantity\": 1}], \"postbackAddress\": \"http://postback.url.com\", \"sourceOrderId\": \"P27XWG\"}, \"destination\": {\"name\": \"dest\"}}";
        #endregion

        //prepare the request
        private static string url_request(string method, string path, string data)
        {
            // creating the headers
            var timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddThh:mm:ss.sssZ");
            var string_to_sign = method + ' ' + path + ' ' + timestamp;
            string signature = HashMe(string_to_sign);
            string url_auth = token + ':' + signature;

            // building the headers
            string x_url_authorization = "'x-url-authorization':" + url_auth;
            string x_url_date = "'x-url-date':" + timestamp;
            string url = endpoint + path;
            string result = GetResponse(x_url_authorization, x_url_date, url);

            return result;
        }

        // get the API response
        private static string GetResponse(string x_url_authorization, string x_url_date, string url)
        {
            var t = string.Empty;
            var Obj_response = string.Empty;

            byte[] requestData = Encoding.UTF8.GetBytes(exampleJson);

            HttpWebRequest req = WebRequest.Create(new Uri(url)) as HttpWebRequest;
            req.ProtocolVersion = HttpVersion.Version10;

            req.Method = "POST";
            req.ContentType = "application/json";
            req.Accept = "application/json";
            req.Headers.Add("x-url-authorization",x_url_authorization); 
            req.Headers.Add("x-url-date",x_url_date);
            req.ContentLength = requestData.Length;

            using (Stream post = req.GetRequestStream())
            {
                post.Write(requestData, 0, requestData.Length);

                using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse)
                {
                    if (resp.StatusCode == HttpStatusCode.OK)
                    {
                        var ms = new StreamReader(resp.GetResponseStream(), UTF8Encoding.UTF8);
                        t = ms.ReadToEnd();
                        Obj_response = JsonConvert.DeserializeObject<string>(t);
                    }

                    return Obj_response;
                }

            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

问题出在标题中,我也用标题的名称填充了自定义标题,因此它被写了两次。