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