简体   繁体   English

Etsy API图片上传错误:请求正文太大

[英]Etsy API Image upload error: The request body is too large

My question is related to this article: Etsy API Image upload error but from a C# point of view. 我的问题与本文有关: Etsy API图像上传错误,但从C#角度来看。

Everything else works, eg I'm able to make an authenticated call to Etsy to create listings but now I've started getting an error " The request body is too large " when trying to attach images to an Etsy listing. 其他所有方法都可以正常工作,例如,我能够对Etsy进行身份验证调用以创建列表,但是现在尝试将图像附加到Etsy列表时,我开始收到错误消息“ The request body too large ”。 The request used to work as I have an example response, but now it simple fails. 该请求曾经可以作为示例响应工作,但现在它简单地失败了。

What I normally do is to set up a Rest Client with the keys, tokens from Etsy. 我通常要做的是使用来自Etsy的密钥和令牌设置Rest Client。 Then I set up a Rest Request and pass it to the Rest Client's Execute method viz: 然后,我设置了一个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);
...

I'm using RestSharp to handle the OAuthentication. 我正在使用RestSharp处理OAuthentication。

The main bit of interest is this: 感兴趣的主要部分是:

...
                        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);

...

Where the response is: 响应是:

"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"

The main routine then that takes a connected rest client: 然后,主例程将连接一个连接的其余客户端:

    /// <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;
    }

It's not a file size problem because I've tried with a 20K image file. 这不是文件大小的问题,因为我尝试使用20K图像文件。

I think the problem is related to me not setting some boundary in the request?? 我认为问题与我没有在请求中设置一些边界有关? None of the "solutions" I've seen make use of OAuthentication and RestSharp. 我见过的“解决方案”都没有利用OAuthentication和RestSharp。

Brian Grinstead's article https://briangrinstead.com/blog/multipart-form-post-in-c/seemed promising but I don't understand how to integrate the Rest Client that's been set up with the Etsy keys to make the authenticated call. 布赖恩·格林斯特德(Brian Grinstead)的文章https://briangrinstead.com/blog/multipart-form-post-in-c/看起来很有希望,但我不明白如何将Etsy密钥设置的Rest Client集成到电话中,以进行经过身份验证的呼叫。

[EDIT] [编辑]

Pointers would be very much apprieciated. 指针将非常受欢迎。

We set the AlwaysMiltipartFormData to true, and used AddFileBytes in the RestRequest . 我们将AlwaysMiltipartFormData设置为true,并在AddFileBytes中使用RestRequest Also, we added the Content-Type multipart/form-data to the parameter list insetead of the header. 另外,我们将Content-Type multipart/form-data到标题的参数列表insetead中。 Maybe that works for you as well. 也许对您也一样。 Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM