Etsy API Ошибка загрузки изображения: тело запроса слишком велико - PullRequest
0 голосов
/ 05 июня 2018

Мой вопрос связан с этой статьей: Ошибка загрузки изображения API Etsy , но с точки зрения C #.

Все остальное работает, например, я могу сделать аутентифицированный вызовEtsy для создания списков, но теперь я начал получать сообщение об ошибке " Слишком большое тело запроса " при попытке прикрепить изображения к списку Etsy.Раньше запрос работал, как у меня, в качестве примера ответа, но теперь он просто терпит неудачу.

Что я обычно делаю, это устанавливаю Rest Client с ключами, токенами от Etsy.Затем я настроил Запрос Отдыха и передал его методу Execute Rest Client, а именно:

...
// 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)
                {
                    // /4662466/preobrazovanie-izobrazheniya-jpeg-v-baitovyi-massiv-isklychenie-com
                    // 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.

Я думаю, что проблема связана с тем, что я не установил некоторую границу в запросе ??Ни одно из «решений», которые я видел, не использует OAuthentication и RestSharp.

статья Брайана Гринстеда https://briangrinstead.com/blog/multipart-form-post-in-c/seemed многообещающая, но я не понимаю, как интегрировать Rest Client, который был настроен с ключами Etsy, для выполнения аутентифицированного вызова.

[EDIT]

Указатели будут очень сильно оценены.

1 Ответ

0 голосов
/ 03 августа 2018

Мы устанавливаем AlwaysMiltipartFormData в true и используем AddFileBytes в RestRequest.Также мы добавили Content-Type multipart/form-data к списку параметров вместо заголовка.Может быть, это работает и для вас.Удачи.

...