How to upload a binary image using mutipart/relative http post request?

PreranaPrerana INMember ✭✭

Hello All,

I have my application running on Windows and Mac(using Xamarin). Google recently deprecated Oauth 1.0 and couple of other APIs like Picasa Web Album Data API 1.0. I am trying to upload an image with metadata using Picasa Web Album Data API 2.0 which results in 400 Bad Request error with no details what my request is missing or where it is malformed. Following is my code :

      byte[] image = System.IO.File.ReadAllBytes("fullimagepath");
        int imglenth= image.Length;
        string text = Encoding.ASCII.GetString(image);

        string rawImgXml="<entry xmlns=\'http://www.w3.org/2005/Atom\'>"+"\n"+
            "<title>plz-to-love-realcat.png</title>"+"\n"+
            "<summary>Real cat wants attention too</summary>"+"\n"+
            "<category scheme=\"http://schemas.google.com/g/2005#kind\"\n"+
            "term=\"http://schemas.google.com/photos/2007#photo\"/>"+"\n"+
            "</entry>";

        string data = "";
         data ="\nMedia multipart posting\n"+
            "--END_OF_PART\n"+
                  "Content-Type: application/atom+xml\n\n"+
                    rawImgXml + "\n"
            +"--END_OF_PART\n"
            +"Content-Type: image/png\n"+
                       text+"\n"+
            "--END_OF_PART--";
        int length=data.Length;

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://picasaweb.google.com/data/feed/api/user/"+tc.userId+"/albumid/"+"6150508893827643953"+"?access_token="+tc.auth_Token);
        byte[] bytes;
        bytes = System.Text.Encoding.ASCII.GetBytes(data);
        request.ContentType = "multipart/related; boundary=END_OF_PART";
        request.ContentLength = length;
        request.Headers.Add("GData-Version","2");
        request.Headers.Add("MIME-Version","1.0");
        request.Method = "POST";
        Stream requestStream = request.GetRequestStream();
        int start = 0;
        int chunkSize = 1024 * 4; // changed form 100 to 4
        double percentage = 0;

        while (start <= bytes.Length)
        {
            if (start + chunkSize > bytes.Length)
                requestStream.Write(bytes, start, bytes.Length - start);
            else
                requestStream.Write(bytes, start, chunkSize);
            start += chunkSize;
        }

        HttpWebResponse response;
        response = (HttpWebResponse)request.GetResponse();

        Stream responseStream = response.GetResponseStream();
        string responseStr = new StreamReader(responseStream).ReadToEnd();



Image data is being converted to ASCII and then appended to data string. After trying many permutation and combinations from past 3 days its failing with the same error. Totally at my wits end to figure out where the request is going wrong?

Uploading the image without metadata works perfectly but I want to upload videos too in my application which cannot be done without metadata.
Have asked the same question on StackOverFlow, Google Picasa Web Album API forum but no luck!

If any one who has experience in http multipart request can just point out what is missing in my request, will really help me to move forward. I am totally stuck at the moment :(

Any pointers or help will be highly appreciated. Thanks a ton in advance.

-Prerana

Answers

  • OhiaNongOhiaNong USMember
    edited August 2017

    You can try this code:
    static void PostImage2(string access_token)
    {
    string filePath = @C:\Users\ngochoaitn\Desktop\1.jpg;
    string extension=(Path.GetExtension (filePath)).TrimStart ('.');

    byte[] image = System.IO.File.ReadAllBytes(filePath);
    int imglenth= image.Length;
    String boundary = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    Console.WriteLine("BOUNDARY:" + boundary);
    
    StringBuilder writeData = new StringBuilder();
    writeData.Append("--").Append(boundary).Append("\r\n");
    writeData.Append("Content-Type: application/atom+xml;\r\n\r\n");
    writeData.Append("<entry xmlns='http://www.w3.org/2005/Atom'>\r\n");
    //writeData.Append("<title>" + Path.GetFileName(filePath) + "</title>\r\n");
    writeData.Append("<title>abc</title>\r\n");
    writeData.Append("<summary></summary>\r\n");
    writeData.Append("<category scheme=\"http://schemas.google.com/g/2005#kind\"\r\n");
    writeData.Append("term=\"http://schemas.google.com/photos/2007#photo\"/>\r\n");
    writeData.Append("</entry>\r\n");
    writeData.Append("--").Append(boundary).Append("\r\n");
    writeData.Append("Content-type: image/" + extension + "\r\n\r\n");
    
    StringBuilder endOfPart = new StringBuilder();
    endOfPart.Append("\r\n--").Append(boundary).Append("--");
    long totalLenght = writeData.Length + image.Length + endOfPart.Length;
    Uri serverUrl = new Uri("https://picasaweb.google.com/data/feed/api/user/default/"+"?access_token=" + access_token);
    
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serverUrl);
    request.Method = "POST";
    
    byte[] bytes,bytes1;
    bytes = System.Text.Encoding.ASCII.GetBytes(writeData.ToString());
    bytes1 = System.Text.Encoding.ASCII.GetBytes(endOfPart.ToString());
    request.ContentType = "multipart/related; boundary=\"" + boundary + "\"";
    request.ContentLength = totalLenght;
    
    request.Headers.Add("GData-Version", "2");
    request.Headers.Add("MIME-Version", "1.0");
    
    Stream requestStream = request.GetRequestStream();
    requestStream.Write(bytes, 0, bytes.Length);
    requestStream.Write(image, 0, image.Length);
    requestStream.Write(bytes1, 0, bytes1.Length);
    
    HttpWebResponse response;
    response = (HttpWebResponse)request.GetResponse();
    
    if (requestStream != null)
        requestStream.Close();
    if (response != null)
        response.Close();
    

    }

Sign In or Register to comment.