简体   繁体   中英

C# Twitter - Upload Image - No 3rd party Libraries

I have a library that I wrote a while ago that allows me to post a new status to Twitter. So handling of the OAuth headers etc is all working.

However, I now have a requirement to upload an image using the Twitter REST API:

https://upload.twitter.com/1.1/media/upload.json

When posting a status I normally put the following in the request stream 'status=<my tweet here>'

Ideally I want to post the raw image data rather than a Base64 string, however, I am having issues with each of them working.

According to Twitter, the OAuth should only be build up from the keys starting 'oauth_' - I am only putting the following in:

parameters.Add("oauth_consumer_key", consumerKey);
parameters.Add("oauth_signature_method", "HMAC-SHA1");
parameters.Add("oauth_timestamp", Base.Methods.UNIXTimestamp);
parameters.Add("oauth_nonce", Guid.NewGuid().ToString().Replace("-", ""));
parameters.Add("oauth_version", "1.0");
parameters.Add("oauth_token", token);

Twitter says that when in doubt to use a content type of application/octet-stream - when doing this, I get a response of:

Code: 38
Message: Missing Parameter Media

In fact, I also get the same response when setting the content type to multipart/form-data as suggested in other pages from Twitter

I have tried various combinations of add the image data to the webrequest, and all seem to fail.

media=<my image byte data here>
Add header of 'media' with image data in the request

and as many other combinations I can think of. I even get the same issues when trying to send the Base64 version (which I'd rather not do).

Having read through lots of other questions I don't seem to be able to see what I am doing wrong.

Can anyone help?

I have found the problem, and it all comes down to the content being sent in the request stream.

As twitter says, only send in the oauth_xxxx parameters, the content based ones are not needed for this request.

The trick is the building up of the multipart form, I have done the following:

  1. I am using an HttpWebrequest, so set it up to send the multipart form headers:

     string boundary = "----" + DateTime.UtcNow.Ticks.ToString("x"); webRequest.ContentType = "multipart/form-data; boundary=" + boundary; 
  2. Build the content to be sent, which has both a prefix and a suffix to the actual image data

     StringBuilder prefixData = new StringBuilder(); prefixData.Append("--"); prefixData.Append(boundary); prefixData.Append(Environment.NewLine); prefixData.Append("Content-Disposition: form-data; name=\\"media\\""); prefixData.Append(Environment.NewLine); prefixData.Append(Environment.NewLine); byte[] prefix = Encoding.UTF8.GetBytes(prefixData.ToString()); StringBuilder suffixData = new StringBuilder(); suffixData.Append(Environment.NewLine); suffixData.Append("--"); suffixData.Append(boundary); suffixData.Append("--"); byte[] suffix = Encoding.UTF8.GetBytes(suffixData.ToString()); 
  3. Join each of the data sections together to post to the stream:

     byte[] data = new byte[prefix.Length + imageData.LongLength + suffix.Length]; Buffer.BlockCopy(prefix, 0, data, 0, prefix.Length); Buffer.BlockCopy(imageData, 0, data, prefix.Length, imageData.Length); Buffer.BlockCopy(suffix, 0, data, prefix.Length + imageData.Length, suffix.Length); 
  4. Write the data to the request stream as normal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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