I have been trying for a while to get the update_profile_image method
to work without much luck. I have been able to successfully call
several other methods including ./friendships/create/ and account/
verify_credentials.xml, but have been having trouble with this method.
The exception returned is: The remote server returned an error: (403)
Forbidden.
And the status on the exception is: ProtocolError
I have verified that the image I am trying to upload will upload using
the settings page on my Twitter account. It is a 30x30 jpg.
I am using c# and the HttpWebRequest class. I am sure there is a
problem with how I am generating the multi-part form data because if I
change the name of the image parameter I get the same message which
I think means the service can't parse the request data the way I am
sending it.
Code is below along with the error message and response object I get
back from the server. If anyone has any ideas about what I am doing
wrong I would really appreciate the help. Thanks.
Code:
private void UploadFile(string filename)
{
string url = @http://twitter.com/account/
update_profile_image.xml;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create
(url);
string boundary = 7d72b92a170f1a;
string headerBoundary = --7d72b92a170f1a; //
two dashes less than boundary
string newline = \r\n;
request.ContentType = multipart/form-data; boundary= +
headerBoundary;
request.Method = POST;
MemoryStream data = new MemoryStream();
StreamWriter sw = new StreamWriter(data);
sw.Write(boundary + newline);
// Write file to data
sw.Write(Content-Disposition: form-data; name=\image\;
image=\{0}\{1}, filename, newline);
sw.Flush();
byte[] file = File.ReadAllBytes(filename);
data.Write(file, 0, file.Length);
sw.Write(newline);
sw.Write(newline);
sw.Write({0}--{1}, boundary, newline);
sw.Flush();
// write data to request
request.ContentLength = data.Length;
request.Headers.Add(Authorization, Basic +
System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes
(username:password)));
using (Stream s = request.GetRequestStream())
{
data.WriteTo(s);
}
data.Close();
try
{
// use the request object to get to the response
WebResponse response = request.GetResponse();
if (response != null)
{
StreamReader sr = new StreamReader
(response.GetResponseStream());
string result = sr.ReadToEnd();
}
}
catch (WebException exception)
{
HttpWebResponse httpResponse = (HttpWebResponse)
exception.Response;
}
}
Exception and response details:
CharacterSetutf-8
ContentEncoding
ContentLength 183
ContentType application/xml; charset=utf-8
Cookies {System.Net.CookieCollection}
Headers {Status: 403 Forbidden
Pragma: no-cache
Vary: Accept-Encoding
Connection: close
Content-Length: 183
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-
check=0
Content-Type: application/xml; charset=utf-8
Date: Fri, 05 Dec 2008 15:26:28 GMT
Expires: Tue, 31 Mar 1981 05:00:00 GMT
Last-Modified: Fri, 05 Dec 2008 15:26:28 GMT
Set-Cookie:
_twitter_sess=BAh7BzoHaWQiJTgxZmIyODE1ZjY3MGI3YjRiOGE1MmFkODJmNjhlOGQwIgpm
%250AbGFzaElDOidBY3Rpb25Db250cm9sbGVyOjpGbGFzaDo6Rmxhc2hIYXNoewAG
%250AOgpAdXNlZHsA--b336ca8846bc144106c5160724c82d54b2bfe824;
domain=.twitter.com; path=/
Server: hi
System.Net.WebHeaderCollection
IsMutuallyAuthenticated FALSE
LastModified{12/5/2008 9:26:28 AM}
Method POST
ProtocolVersion {1.1}
ResponseUri {http://twitter.com/account/update_profile_image.xml}
Server hi
StatusCode Forbidden
StatusDescription Forbidden
ExceptionStatus ProtocolError