Martin Normark's blog

Posted on by Martin Normark


I’ve spent some time lately, playing around with the Twitter API. And along with that belongs the TwitPic’s API. I’m using Twitter a lot, to stay in touch with tech news, other developers and just for fun. But it’s getting more and more used for a lot of different things, and I needed it to integrate with an E-commerce platform I’m developing.

The code for post a picture to TwitPic looks like this:

    /// <summary>
    /// URL for the TwitPic API's upload method
    /// </summary>
    private const string TWITPIC_UPLADO_API_URL = "http://twitpic.com/api/upload";

    /// <summary>
    /// URL for the TwitPic API's upload and post method
    /// </summary>
    private const string TWITPIC_UPLOAD_AND_POST_API_URL = "http://twitpic.com/api/uploadAndPost";

    /// <summary>
    /// Uploads the photo and sends a new Tweet
    /// </summary>
    /// <param name="binaryImageData">The binary image data.</param>
    /// <param name="tweetMessage">The tweet message.</param>
    /// <param name="filename">The filename.</param>
    /// <returns>Return true, if the operation was succeded.</returns>
    public bool UploadPhoto(byte[] binaryImageData, string tweetMessage, string filename)
    {
      // Documentation: http://www.twitpic.com/api.do
      string boundary = Guid.NewGuid().ToString();
      string requestUrl = String.IsNullOrEmpty(tweetMessage) ? TWITPIC_UPLADO_API_URL : TWITPIC_UPLOAD_AND_POST_API_URL;
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);
      string encoding = "iso-8859-1";

      request.PreAuthenticate = true;
      request.AllowWriteStreamBuffering = true;
      request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
      request.Method = "POST";

      string header = string.Format("--{0}", boundary);
      string footer = string.Format("--{0}--", boundary);

      StringBuilder contents = new StringBuilder();
      contents.AppendLine(header);

      string fileContentType = GetImageContentType(filename);
      string fileHeader = String.Format("Content-Disposition: file; name=\"{0}\"; filename=\"{1}\"", "media", filename);
      string fileData = Encoding.GetEncoding(encoding).GetString(binaryImageData);

      contents.AppendLine(fileHeader);
      contents.AppendLine(String.Format("Content-Type: {0}", fileContentType));
      contents.AppendLine();
      contents.AppendLine(fileData);

      contents.AppendLine(header);
      contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "username"));
      contents.AppendLine();
      contents.AppendLine(this.Username);

      contents.AppendLine(header);
      contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "password"));
      contents.AppendLine();
      contents.AppendLine(this.Password.ToInsecureString());

      if (!String.IsNullOrEmpty(tweetMessage))
      {
        contents.AppendLine(header);
        contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "message"));
        contents.AppendLine();
        contents.AppendLine(tweetMessage);
      }

      contents.AppendLine(footer);

      byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(contents.ToString());
      request.ContentLength = bytes.Length;

      using (Stream requestStream = request.GetRequestStream())
      {
        requestStream.Write(bytes, 0, bytes.Length);

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
          using (StreamReader reader = new StreamReader(response.GetResponseStream()))
          {
            string result = reader.ReadToEnd();

            XDocument doc = XDocument.Parse(result);

            XElement rsp = doc.Element("rsp");
            string status = rsp.Attribute(XName.Get("status")) != null ? rsp.Attribute(XName.Get("status")).Value : rsp.Attribute(XName.Get("stat")).Value;

            return status.ToUpperInvariant().Equals("OK");
          }
        }
      }
    }

About the author

Martin Normark Martin Normark works as a freelance web developer (consultant). He blogs about web, software and programming experiments, daily code battles, specific How To posts and what else comes to mind.

Posted on by Martin Normark | Posted in C# | Tagged

  • DJ

    In your code, are you missing a function?

    string fileContentType = GetImageContentType(filename);

    GetImageContentType, I’m only familiar with this in Java.

  • DJ

    Sorry, I figured it out, however, I’m not sure how to pass binaryImageData, have an example? Thanks alot.

  • http://martinnormark.com Martin H. Normark

    You can use the System.IO.File class to do that:

    byte[] binaryImageData = File.ReadAllBytes("c:\img.jpg");
    UploadPhoto(binaryImageData, "Test", "img.jpg");

  • DJ

    One more problem.
    I’m using the following but still getting errors with
    XDocument doc = XDocument.Parse(result);

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Xml.Schema;
    using System.IO;
    using System.Xml;
    //using System.Security.Cryptography.X509Certificates;
    using System.Net.Security;

  • http://martinnormark.com Martin H. Normark

    You need to include System.Xml.Linq as well: using System.Xml.Linq;

  • Sanil

    Thanks!
    I was really stucked at the "posting the image to TwitPic" part, and was really frustated after trying many ways to do that, I even read the whole RFC # 2388 :(

    your post really helped me, and that means I’ve completed the project :)
    It’s now on codeplex http://twipli.codeplex.com

  • balu

    HI
    thanks for your code.But the
    contents.AppendLine();
    property is not available in windows mobile projects.I tried
    contents.Append("\n"); instead but its not working.
    Is there any other way.
    Regards
    Balu

  • http://martinnormark.com Martin H. Normark

    Hi Balu

    According to this: http://msdn.microsoft.com/en-us/library/system.text.stringbuilder_members.aspx

    The AppendLine is available in the Compact Framework as well. Which version of the .Net Compact Framework are you using?

  • Pingback: Upload an image to Twitpic by using Oauth Echo - Ronald Rajagukguk