我试图使用c#RestSharp向Wooccommerce添加新产品,但来自服务器的答案是:
{"errors":[{"code":"woommerce_api_authentication_error","message":"oauth_consumer_key parameter mangler"}]}
对于添加产品,我使用下一个代码:
public string AddProduct()
{
Method method = Method.POST;
string result = "";
string endpoint = "products";
var client = new RestClient(ApiUrl);
var parameters = new Dictionary<string, string>();
var request = createRequestWithParams(parameters, endpoint, method);
request.RequestFormat = DataFormat.Json;
request.AddJsonBody(new DTO.WCProduct { title = "eeee2", type = "simple", regular_price = "777", description = "Descr" });
AddOAuthparams(ref parameters, method.ToString(), endpoint);
result = client.Execute(request).Content;
return result;
}
其中方法createRequestWithParams为:
private RestRequest createRequestWithParams(Dictionary<string, string> parameters, string res, Method methos)
{
var req = new RestRequest(res, methos);
foreach (var item in parameters)
{
req.AddParameter(item.Key, item.Value);
}
return req;
}`
其中方法AddOAuthparams为:
void AddOAuthparams(ref Dictionary<string, string> parameters, string method, string endpoint)
{
parameters["oauth_consumer_key"] = this.ConsumerKey;
parameters["oauth_timestamp"] =
DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds.ToString();
parameters["oauth_timestamp"] = parameters["oauth_timestamp"].Substring(0, parameters["oauth_timestamp"].IndexOf(",")); //todo fix for . or ,
parameters["oauth_nonce"] = Hash(parameters["oauth_timestamp"]);
parameters["oauth_signature_method"] = "HMAC-SHA256";
parameters["oauth_signature"] = GenerateSignature(parameters, method, endpoint);
}
public string GenerateSignature(Dictionary<string, string> parameters, string method, string endpoint)
{
var baserequesturi = Regex.Replace(HttpUtility.UrlEncode(this.ApiUrl + endpoint), "(%[0-9a-f][0-9a-f])", c => c.Value.ToUpper());
var normalized = NormalizeParameters(parameters);
var signingstring = string.Format("{0}&{1}&{2}", method, baserequesturi,
string.Join("%26", normalized.OrderBy(x => x.Key).ToList().ConvertAll(x => x.Key + "%3D" + x.Value)));
var signature =
Convert.ToBase64String(HashHMAC(Encoding.UTF8.GetBytes(this.ConsumerSecret),
Encoding.UTF8.GetBytes(signingstring)));
Console.WriteLine(signature);
return signature;
}
private Dictionary<string, string> NormalizeParameters(Dictionary<string, string> parameters)
{
var result = new Dictionary<string, string>();
foreach (var pair in parameters)
{
var key = HttpUtility.UrlEncode(HttpUtility.UrlDecode(pair.Key));
key = Regex.Replace(key, "(%[0-9a-f][0-9a-f])", c => c.Value.ToUpper()).Replace("%", "%25");
var value = HttpUtility.UrlEncode(HttpUtility.UrlDecode(pair.Value));
value = Regex.Replace(value, "(%[0-9a-f][0-9a-f])", c => c.Value.ToUpper()).Replace("%", "%25");
result.Add(key, value);
}
return result;
}
**但如果我尝试获取有关产品的信息或删除一些产品,该功能运行良好,**
我在Github上找到了这段代码https://github.com/kloon/WooCommerce-REST-API-Client-Library
我认为,我的签名功能工作不好,但我不明白应该修复什么。
也许这是个老问题。但对于来自谷歌的人来说,搜索任何提示都是值得的。
edit:从错误消息中,我认为您忘记将oauth_consumer_key作为消息包含在内。通过检查RestRequest查询参数,确保您的请求包括oauth_consumer_key。
顺便说一句,使用kloon的实现,您可以使用我的存储库中的Wooccommerce C#库
试试下面的解决方案,它非常容易集成,只需要很少的代码行。它对我有效
static void Main(string[] args)
{
string requestURL = @"http://www.example.co.uk/test/wp-json/wc/v1/products";
UriBuilder tokenRequestBuilder = new UriBuilder(requestURL);
var query = HttpUtility.ParseQueryString(tokenRequestBuilder.Query);
query["oauth_consumer_key"] = "consumer_key";
query["oauth_nonce"] = Guid.NewGuid().ToString("N");
query["oauth_signature_method"] = "HMAC-SHA1";
query["oauth_timestamp"] = (Math.Truncate((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds)).ToString();
string signature = string.Format("{0}&{1}&{2}", "POST", Uri.EscapeDataString(requestURL), Uri.EscapeDataString(query.ToString()));
string oauth_Signature = "";
using (HMACSHA1 hmac = new HMACSHA1(Encoding.ASCII.GetBytes("consumer_Secret&")))
{
byte[] hashPayLoad = hmac.ComputeHash(Encoding.ASCII.GetBytes(signature));
oauth_Signature = Convert.ToBase64String(hashPayLoad);
}
query["oauth_signature"] = oauth_Signature;
tokenRequestBuilder.Query = query.ToString();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(tokenRequestBuilder.ToString());
request.ContentType = "application/json; charset=utf-8";
// request.Method = "GET";
request.Method = "POST";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json = File.ReadAllText(@"D:JsonFile.txt");//File Path for Json String
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
}