Uploading media in C#


#1

Hi everyone,

I have been going crazy trying to get media to upload using C#. I’ve tried both handing off the image in binary and base64 but no matter what I have tried twitter returns ‘{“errors”:[{“code”:38,“message”:“media parameter is missing.”}]}’. So I am pretty much at wits end at this point. I’ve spent tons of time Googling the topic to no avail.

BTW I am uploading using https://upload.twitter.com/1.1/media/upload.json . I want to get a return media_id that include it in the tweet (The tweeting part of the app works fine).

This is currently the header I am sending to Twitter to post media:

---------------------------8d25f91607c01d6
Content-Disposition: form-data; name=“media”; filename=“image.jpg”

Content-Type: image/jpeg

[raw binary data]

---------------------------8d25f91607c01d6

Is this close to what Twitter is looking for? Or better yet does anyone have working C# code?

Here is my full code:

// upload media first, then fetch media ID

var resource_url2 = "https://upload.twitter.com/1.1/media/upload.json";

var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");

var baseFormat2 = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
                    "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}";
var baseString2 = string.Format(baseFormat2,
    oauth_consumer_key,
    oauth_nonce,
    oauth_signature_method,
    oauth_timestamp,
    oauth_token,
    oauth_version);

baseString2 = string.Concat("POST&", Uri.EscapeDataString(resource_url2),
             "&", Uri.EscapeDataString(baseString2));

var compositeKey2 = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
                        "&", Uri.EscapeDataString(oauth_token_secret));

string oauth_signature2;
using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey2)))
{
    oauth_signature2 = Convert.ToBase64String(
        hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString2)));
}

var headerFormat2 = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
                   "oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
                   "oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
                   "oauth_version=\"{6}\"";

var authHeader2 = string.Format(headerFormat2,
                        Uri.EscapeDataString(oauth_nonce),
                        Uri.EscapeDataString(oauth_signature_method),
                        Uri.EscapeDataString(oauth_timestamp),
                        Uri.EscapeDataString(oauth_consumer_key),
                        Uri.EscapeDataString(oauth_token),
                        Uri.EscapeDataString(oauth_signature2),
                        Uri.EscapeDataString(oauth_version)
                );
var postBody2 = "";
ServicePointManager.Expect100Continue = false;

HttpWebRequest request2 = (HttpWebRequest)WebRequest.Create(resource_url2);
request2.Headers.Add("Authorization", authHeader2);

request2.Method = "POST";
request2.ContentType = "multipart/form-data; boundary=" + boundary;

// build request string

StringBuilder requestString = new StringBuilder();

requestString.AppendLine(boundary + "\r\nContent-Disposition: form-data; name=\"media\"; filename=\"image.jpg\"\r\n");
requestString.AppendLine("Content-Type: image/jpeg\r\n\r\n");
requestString.AppendLine(Encoding.Default.GetString(imageData));    
requestString.AppendLine("\r\n" + boundary + "\r\n");

byte[] bytes = Encoding.UTF8.GetBytes(requestString.ToString());

using (Stream stream = request2.GetRequestStream())
{
    byte[] content = bytes;
    stream.Write(content, 0, content.Length);
}

try
{
    HttpWebResponse response2 = (HttpWebResponse)request2.GetResponse();

                                // Successful upload

}
catch (WebException ex)
{
    using (WebResponse response = ex.Response)
    {
        var httpResponse = (HttpWebResponse)response;

        try
        {

            using (Stream data = response.GetResponseStream())
            {
                StreamReader sr = new StreamReader(data);

                // Twitter didn't like request
            }
        }
        catch (Exception ex2)
        {
            // Whole app blew up
        }
    }
}

#2

I figured it out! A little understanding of multipart boundaries helped. I basically added two dashes ‘–’ to the beginning of the opening boundary and put two dashes ‘–’ at the beginning and end of the closing boundary. I then removed the ‘Content-Type: image/jpeg’ and it is now uploading!


#3
        var URL = "https://upload.twitter.com/1.1/media/upload.json";

        var baseFormat2 = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
                            "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}";
        var baseString2 = string.Format(baseFormat2,
            oauth_consumer_key,
            oauth_nonce,
            oauth_signature_method,
            oauth_timestamp,
            oauth_token,
            oauth_version);

        baseString2 = string.Concat("POST&", Uri.EscapeDataString(URL),
                     "&", Uri.EscapeDataString(baseString2));

        var compositeKey2 = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
                                "&", Uri.EscapeDataString(oauth_token_secret));

        string oauth_signature2;
        using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey2)))
        {
            oauth_signature2 = Convert.ToBase64String(
                hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString2)));
        }

        var headerFormat2 = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
                           "oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
                           "oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
                           "oauth_version=\"{6}\"";

        var OAuthSignature = string.Format(headerFormat2,
                                Uri.EscapeDataString(oauth_nonce),
                                Uri.EscapeDataString(oauth_signature_method),
                                Uri.EscapeDataString(oauth_timestamp),
                                Uri.EscapeDataString(oauth_consumer_key),
                                Uri.EscapeDataString(oauth_token),
                                Uri.EscapeDataString(oauth_signature2),
                                Uri.EscapeDataString(oauth_version)
                        );
        byte[] imageData = File.ReadAllBytes(PictureFile);
        Encoding EncodingAlgorithm = Encoding.GetEncoding("iso-8859-1");
        string Boundary = DateTime.Now.Ticks.ToString("x");
        string StartBoundary = string.Format("--{0}\r\n", Boundary);
        string EndBoundary = string.Format("\r\n--{0}--\r\n", Boundary);
        string sContentType = "multipart/form-data;boundary=" + Boundary;
        string contentDisposition = "Content-Disposition: form-data; ";
        string contenName = "name=\"media\";\r\n ";
        string contentType = "\r\nContent-Type: application/octet-stream\r\n\r\n";
        string Data = EncodingAlgorithm.GetString(imageData, 0, imageData.Length);
        var contents = new System.Text.StringBuilder();
        contents.Append(String.Format("{0}{1}{2}{3}{4}", StartBoundary, contentDisposition, contenName, contentType, Data));
        contents.Append(EndBoundary);
        byte[] Content = EncodingAlgorithm.GetBytes(contents.ToString());

        var request = (HttpWebRequest)WebRequest.Create(URL);
        request.Method = "POST";
        request.AllowWriteStreamBuffering = true;
        request.Headers.Add("Authorization", OAuthSignature);
        request.ContentType = sContentType;
        request.ContentLength = Content.Length;

        Stream dataStream = request.GetRequestStream();
        dataStream.Write(Content, 0, Content.Length);
        dataStream.Close();
        try
        {
            string MediaID = string.Empty;
            using (var Response = (HttpWebResponse)request.GetResponse())
            {
                if (Response.StatusCode == HttpStatusCode.OK)
                {
                    Stream receiveStream = Response.GetResponseStream();
                    StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
                    string jsonResult = readStream.ReadToEnd();
                    JObject jobj = JObject.Parse(jsonResult);
                    MediaID = Convert.ToString(jobj["media_id_string"]);
                }
            }
        }
        catch (WebException ex)
        {
            using (WebResponse response = ex.Response)
            {
                var httpResponse = (HttpWebResponse)response;

                try
                {

                    using (Stream data = response.GetResponseStream())
                    {
                        StreamReader sr = new StreamReader(data);

                        // Twitter didn't like request
                    }
                }
                catch (Exception ex2)
                {
                    // Whole app blew up
                }
            }
        }

#4

MANY THANKS
:slight_smile:


#5