Sage One API在创建付款发票时返回500内部服务错误
我在Sage One API中创建“Purchase Invoice”时遇到问题。无论我对传入的数据所做的更改如何,我似乎都会收到500内部服务错误,并且没有包含任何有意义信息的详细响应。无论输入什么数据(只有errorcode字段中的GUID和服务器时间更改),响应总是相同的。回应如下:Sage One API在创建付款发票时返回500内部服务错误
{
"$diagnoses": [
{
"$severity": "error",
"$dataCode": "UnexpectedError",
"$message": "Unexpected error",
"$source": {
"serverTime": "2016-04-29T15:48:11.637+00:00",
"errorCode": "3b83e1b5-164d-42d4-95b3-3479b09c93f1",
"requestPath": "/api/v2/purchase_invoices",
"queryString": "",
"requestMethod": "POST"
}
}
]
}
我很积极,这不是一个授权问题,因为我都得到并创建其他数据类型之前。这包括创建采购发票所需的联系人。
我按照self-service site提供的信息。我也从bare bones SDK开始,作为我正在使用的大部分基础过程的基础。我已经改写了大部分底层结构,最初认为它可能是由SDK引起的,这导致我出现相同的情况 - 我只有500个内部服务错误作为响应。
这使我相信这是与参数本身的问题,如文档在中间列中列出的参数和数据在右列的例子调用之间的一些差异。具体而言,该示例具有额外的字段,如“extra_reference”,以及未在中间列中列出的行项目“product_id”和“product_code”。
下面是一些用于呼叫的相关代码,再次记住的基本架构是他们的,有一些程序上的修改,以适应我目前的架构,不影响实际的呼叫:
protected override List<KeyValuePair<string, string>> GetPostDataValuesForCreate(
SageOnePurchaseInvoice objectToCreate)
{
List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("expense[contact_id]", objectToCreate.ContactId.ToString()));
postData.Add(new KeyValuePair<string, string>("expense[date]", objectToCreate.Date));
postData.Add(new KeyValuePair<string, string>("expense[due_date]", objectToCreate.DueDate));
if (!string.IsNullOrWhiteSpace(objectToCreate.Reference))
{
postData.Add(new KeyValuePair<string, string>("expense[reference]", objectToCreate.Reference));
}
if (objectToCreate.ProjectId != 0)
{
postData.Add(new KeyValuePair<string, string>("expense[project_id]", objectToCreate.ProjectId.ToString()));
}
if (!string.IsNullOrWhiteSpace(objectToCreate.Notes))
{
postData.Add(new KeyValuePair<string, string>("expense[notes]", objectToCreate.Notes));
}
for (int i = 0; i < objectToCreate.LineItems.Length; i++)
{
string index = "expense[line_items_attributes][" + i.ToString() + "][";
postData.Add(new KeyValuePair<string, string>(index + "description]", objectToCreate.LineItems[i].Description));
postData.Add(new KeyValuePair<string, string>(index + "ledger_account_id]", objectToCreate.LineItems[i].LedgerAccount.Id.ToString()));
postData.Add(new KeyValuePair<string, string>(index + "quantity]", objectToCreate.LineItems[i].Quantity.ToString()));
postData.Add(new KeyValuePair<string, string>(index + "unit_price]", objectToCreate.LineItems[i].UnitPrice.ToString()));
}
return postData;
}
这里是创建和执行Web请求的实际方法:
public static string Create(Uri baseUrl,List> bodyParams,string token,string signingSecret) { string result;
string nonce = GenerateNonce();
HttpWebRequest sageOneWebRequest = WebRequest.Create(baseUrl) as HttpWebRequest;
string PostParams = ConvertPostParams(bodyParams);
string signatureString = GetSignatureString(baseUrl, null, bodyParams, nonce, WebRequestMethods.Http.Post);
string signingKey = GetSigningKey(token, signingSecret);
string signature = GenerateHmac(signingKey, signatureString);
sageOneWebRequest.AllowAutoRedirect = true;
sageOneWebRequest.Accept = "*/*";
sageOneWebRequest.UserAgent = "Itemize";
sageOneWebRequest.Headers.Add("X-Signature", signature);
sageOneWebRequest.Headers.Add("X-Nonce", nonce);
sageOneWebRequest.ContentType = "application/x-www-form-urlencoded";
sageOneWebRequest.Timeout = 100000;
sageOneWebRequest.Headers.Add("Authorization", "Bearer " + token);
sageOneWebRequest.Method = WebRequestMethods.Http.Post;
using (StreamWriter requestWriter = new StreamWriter(sageOneWebRequest.GetRequestStream()))
{
try
{
requestWriter.Write(PostParams);
}
catch(Exception ex)
{
throw new Exception("Exception thrown writing Post Params to Body", ex);
}
}
try
{
using (WebResponse response = sageOneWebRequest.GetResponse())
{
Stream dataStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(dataStream))
{
result = reader.ReadToEnd();
}
}
}
catch (WebException webex)
{
//This is where the error is caught
Logger.Error("Web Exception while processing Sage One Web Request: ", webex);
string text;
using (var sr = new StreamReader(webex.Response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
result = null;
throw new Exception("Web Exception thrown processing Sage One Request", webex);
}
catch (Exception ex)
{
Logger.Error("Exception while processing Sage One Web Request: ", ex);
result = null;
throw new Exception("Exception thrown processing Sage One Request", ex);
}
return result;
}
任何有关这个问题的帮助将不胜感激!谢谢!
编辑:关于以下建议,后面的实际URL路径是“api.sageone.com/accounts/v2/purchase_invoices”,而不是接收到的错误中记录的请求路径。
您要发布帖子/purchase_invoices
,但你的参数是expense
。请使用purchase_invoice
名称来包装您的参数。
根据错误响应,请求路径看起来不正确。它显示 “requestPath”: “/ API/V2/purchase_invoices”
但文档显示 /账户/ V2/purchase_invoices
我修改我原来的意见,然而,很明显这里,所谓的实际URL是“https://api.sageone.com/accounts/v2/purchase_invoices”,如文档中表示。我不知道API为什么返回该URL。 –