我的问题与本文有关:Etsy API Image upload error但是从C#的角度来看。
其他一切都有效,例如我能够对Etsy进行身份验证调用以创建列表但现在我开始收到错误" 请求正文太大"当试图将图像附加到Etsy列表时。这个请求过去起作用,因为我有一个示例响应,但现在很简单就失败了。
我通常做的是使用Etsy的密钥和令牌设置Rest Client。然后我设置一个Rest请求并将其传递给Rest Client的Execute方法即:
...
// Set up the rest client...
RestClient restClient = new RestClient();
restClient.BaseUrl = new System.Uri("https://openapi.etsy.com/v2/");
restClient.Authenticator = RestSharp.Authenticators.OAuth1Authenticator.ForProtectedResource(ConsumerKey, ConsumerSecret, PermanentAccessTokenKey, PermanentAccessTokenSecret);
// Set up the request...
RestRequest request = new RestRequest();
request.Resource = "An Etsy end point";
request.Method = Method.POST;
...
IRestResponse response = restClient.Execute(request);
...
我使用RestSharp来处理OAuthentication。
感兴趣的主要是:
...
request.AddHeader("Content-Type", "multipart/form-data");
request.AlwaysMultipartFormData = true;
request.AddParameter("image", localImageFilenames[i]);
request.AddParameter("type", "image/" + imageType);
request.AddParameter("rank", imageRank++);
request.AddFile("image", imageByteArray, localImageFilenames[i], "image/" + imageType);
request.Resource = "/listings/{0}/images".Replace("{0}", etsyListingId.ToString()); // eg "/listings/559242925/images";
request.Method = Method.POST;
response = restClient.Execute(request);
...
回复是:
"StatusCode: BadRequest, Content-Type: text/plain;charset=UTF-8, Content-Length: 29)"
Content: "The request body is too large"
ContentEncoding: ""
ContentLength: 29
ContentType: "text/plain;charset=UTF-8"
Cookies: Count = 3
ErrorException: null
ErrorMessage: null
Headers: Count = 9
IsSuccessful: false
ProtocolVersion: {1.1}
RawBytes: {byte[29]}
Request: {RestSharp.RestRequest}
ResponseStatus: Completed
ResponseUri: {https://openapi.etsy.com/v2/listings/605119036/images}
Server: "Apache"
StatusCode: BadRequest
StatusDescription: "Bad Request"
content: "The request body is too large"
接下来是连接休息客户端的主程序:
/// <summary>
/// Upload and attach the list of images to the specified Etsy listing id.
/// </summary>
/// <param name="restClient">Connected Etsy client</param>
/// <param name="localImageFilenames">List of local images to attach to the listing (ordered in rank order).</param>
/// <param name="etsyListingId">The Etsy listing's listing id to which images will be attached.</param>
public void AttachImagesToProduct(RestClient restClient, List<string> imageFilenames, int etsyListingId, string localTemporaryDirectory)
{
int imageRank = 1;
string localImageFilename = null;
List<string> localImageFilenames = new List<string>();
// Before we reattach images, Etsy only caters for local image filesname eg ones that reside on the user's PC (and not http://...).
// So, if the images beign with http... then we need to download them locally, upload them and then delete...
for (int i = 0; i < imageFilenames.Count; i++)
{
if (imageFilenames[i].ToLower().Trim().StartsWith("http"))
{
// Download...
localImageFilename = Orcus.CommonLibrary.Images.DownloadRemoteImageFile(imageFilenames[i], localTemporaryDirectory);
}
else
{
localImageFilename = imageFilenames[i];
}
if (!string.IsNullOrEmpty(localImageFilename))
{
localImageFilenames.Add(localImageFilename);
}
}
for (int i = 0; i < localImageFilenames.Count; i++)
{
try
{
if (File.Exists(localImageFilenames[i]) && etsyListingId > 0)
{
// https://stackoverflow.com/questions/7413184/converting-a-jpeg-image-to-a-byte-array-com-exception
// https://blog.tyrsius.com/restsharp-file-upload/
// https://nediml.wordpress.com/2012/05/10/uploading-files-to-remote-server-with-multiple-parameters/
// And also sample code from https://github.com/ChrisGraham84/EtsyAPIConsumer
using (MemoryStream ms = new MemoryStream())
{
Image img = Image.FromFile(localImageFilenames[i]);
string imageType = DetermineImageType(img);
System.Drawing.Imaging.ImageFormat imageFormat = DetermineImageFormat(img);
byte[] imageByteArray;
RestRequest request = new RestRequest();
IRestResponse response;
img.Save(ms, imageFormat);
imageByteArray = ms.ToArray();
request.AddHeader("Content-Type", "multipart/form-data");
request.AlwaysMultipartFormData = true;
request.AddParameter("image", localImageFilenames[i]);
request.AddParameter("type", "image/" + imageType);
request.AddParameter("rank", imageRank++);
request.AddFile("image", imageByteArray, localImageFilenames[i], "image/" + imageType);
request.AddJsonBody(null);
request.Resource = "/listings/{0}/images".Replace("{0}", etsyListingId.ToString()); // eg "/listings/559242925/images";
request.Method = Method.POST;
response = restClient.Execute(request);
}
}
}
catch (Exception ex)
{
// Image n failed to up attached so skip it...
}
} // for...
}
/// <summary>
/// Determine the image type.
/// </summary>
/// <param name="localImage">The local image to be eventually uploaded to Etsy.</param>
/// <returns>The image's type. Default is Jpeg.</returns>
private string DetermineImageType(Image localImage)
{
string imageType = "jpeg";
if (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(localImage.RawFormat))
{
imageType = "jpeg";
}
else if (System.Drawing.Imaging.ImageFormat.Gif.Equals(localImage.RawFormat))
{
imageType = "gif";
}
else if (System.Drawing.Imaging.ImageFormat.Bmp.Equals(localImage.RawFormat))
{
imageType = "bmp";
}
else if (System.Drawing.Imaging.ImageFormat.Png.Equals(localImage.RawFormat))
{
imageType = "png";
}
else if (System.Drawing.Imaging.ImageFormat.Tiff.Equals(localImage.RawFormat))
{
imageType = "tiff";
}
return imageType;
}
/// <summary>
/// Determines the image's image format.
/// </summary>
/// <param name="localImage">The local image to be eventually uploaded to Etsy</param>
/// <returns>The image's format. Default is Jpeg.</returns>
private System.Drawing.Imaging.ImageFormat DetermineImageFormat(Image localImage)
{
System.Drawing.Imaging.ImageFormat imgFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
if (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(localImage.RawFormat))
{
imgFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
}
else if (System.Drawing.Imaging.ImageFormat.Gif.Equals(localImage.RawFormat))
{
imgFormat = System.Drawing.Imaging.ImageFormat.Gif;
}
else if (System.Drawing.Imaging.ImageFormat.Bmp.Equals(localImage.RawFormat))
{
imgFormat = System.Drawing.Imaging.ImageFormat.Bmp;
}
else if (System.Drawing.Imaging.ImageFormat.Png.Equals(localImage.RawFormat))
{
imgFormat = System.Drawing.Imaging.ImageFormat.Png;
}
else if (System.Drawing.Imaging.ImageFormat.Tiff.Equals(localImage.RawFormat))
{
imgFormat = System.Drawing.Imaging.ImageFormat.Tiff;
}
return imgFormat;
}
这不是文件大小问题,因为我尝试过使用20K图像文件。
我认为问题与我在请求中没有设置边界有关?没有一个&#34;解决方案&#34;我见过使用OAuthentication和RestSharp。
Brian Grinstead的文章https://briangrinstead.com/blog/multipart-form-post-in-c/seemed很有希望,但我不明白如何将使用Etsy密钥设置的Rest Client集成以进行身份验证。
[编辑]
指针会非常受欢迎。
答案 0 :(得分:0)
我们将AlwaysMiltipartFormData
设置为true,并在AddFileBytes
中使用了RestRequest
。另外,我们将Content-Type multipart/form-data
添加到标题的参数列表insetead中。
也许对您也一样。祝你好运。