title: Using C# to login to a website, not returning cookies back
body: <p>I am trying to write some C# code that will log into the Battlelog for Battlefield 3 on the PC.  I have found an open source API written in php, but when i translate it to C# it's not quite working.  I used fiddler to make sure the headers match, both request look the same but the C# app won't return any cookies like the pc browser.  Also, is there anyway to tell when you post a form to a site the querystring id's that are being posted and the values?  I could not find that in fiddler, just the headers.  Here is my code:</p>
  
  <pre><code> //LOGIN
          string formUrl = "https://battlelog.battlefield.com/bf3/gate/login/"; // NOTE: This is the URL the form POSTs to, not the URL of the form (you can find this in the "action" attribute of the HTML's form tag
          string formParams = string.Format("email={0}&amp;password={1}&amp;submit={2}&amp;redirect={3}", "TEST@TEST.com", "PASS", "Sign in","|bf3|");
          HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl);
          req.Method = "POST";
          req.ContentType = "application/x-www-form-urlencoded";
          byte[] bytes = UTF8Encoding.UTF8.GetBytes(formParams);
  
          //ADD THE HEADERS
          ((HttpWebRequest)req).UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.106 Safari/535.2";
          ((HttpWebRequest)req).Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
          ((HttpWebRequest)req).Referer = "http://battlelog.battlefield.com/bf3/gate/";
  
          req.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
          req.Headers.Add("Cache-Control", "max-age=0");
          req.Headers.Add("Accept-Language", "en-us,en;q=0.8");
          req.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
  
  
  
          using (Stream os = req.GetRequestStream())
          {
              os.Write(bytes, 0, bytes.Length);
          }
          HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
          ((HttpWebRequest)req).CookieContainer = new CookieContainer();
          ((HttpWebRequest)req).CookieContainer.Add(resp.Cookies);
  </code></pre>
  
  <p>here is the open source php if it helps
                  
  
  <pre><code>            /**
               * Battlelog API
               * 
               * This API allows for the grabbing of Battlefield 3 player stats.
               * Note: It seems a valid EA login is still required to pull down
               * data...
               * 
               * For examples, updates and additional information, see the project page
               * at http://www.blakeharley.com/projects/battlelogapi/.
               * 
               * @author      Blake Harley &lt;contact@blakeharley.com&gt;
               * @version     1.3
               * @package     BattlelogApi
               * @copyright   Copyright (c) 2011, Blake Harley
               * @license     http://creativecommons.org/licenses/by/3.0/
               * @since       1.0-beta
               */
  
              require_once 'BF3Container.class.php';
              require_once 'BattlelogLang.inc.php';
              require_once 'BF3Soldier.class.php';
              require_once 'BF3Server.class.php';
  
              /**
               * This is where the cookies will be stored while connecting with the Battlelog
               * servers. Make sure PHP has read and write access to the file location.
               * 
               * @package BattlelogApi
               * @var string
               * @since 1.0-beta
               */
              define('BLA_COOKIE_FILE', 'cookies.txt');
  
              /**
               * You can change this is you want. Some user agents have been blocked, so it's
               * best to stick with impersonating a real browser.
               * For the curious, the current user agent is Mozilla Firefox 6.0.2 on Windows 7 64-bit.
               * 
               * @package BattlelogApi
               * @var string
               * @since 1.2-pre
               */
              define('BLA_USER_AGENT', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2');
  
              /**
               * You probably shouldn't touch this.
               * 
               * @package BattlelogApi
               * @var string
               * @since 1.0-beta
               */
              define('BLA_LOGIN_URL', 'https://battlelog.battlefield.com/bf3/gate/login/');
  
  
              /**
               * This class is the main accessor for the stats engine.
               * 
               * Example:
               * &lt;code&gt;
               * $battlelog = new BattlelogApi('player@email.com', 'p4ssword');
               * $jones = $battlelog-&gt;getBF3Player('123456789');
               * echo $jones-&gt;getScorePerMinute();
               * &lt;/code&gt;
               * 
               * @author      Blake Harley &lt;contact@blakeharley.com&gt;
               * @package     BattlelogApi
               * @since       1.0-beta
               */
              class BattlelogApi
              {
                  /**
                   * @access private
                   * @var string
                   * @since 1.0-beta
                   */
                  private $_username = null;
  
                  /**
                   * @access private
                   * @var string
                   * @since 1.0-beta
                   */
                  private $_password = null;
  
                  /**
                   * @access private
                   * @var bool
                   * @since 1.0-beta
                   */
                  private $_hasCredentials = false;
  
                  /**
                   * @access private
                   * @var BattlelogLang
                   * @since 1.3
                   */
                  private $_lang = null;
  
                  /**
                   * Stores the EA credentials so accounts can be scraped.
                   * 
                   * @access public
                   * @param string $username The EA account name
                   * @param string $password The EA account password
                   * @param string $lang The language to use for the translator (experimental)
                   * @since 1.0-beta
                   */
                  public function __construct($username, $password, $lang = null)
                  {
                      $this-&gt;_username = (string) $username;
                      $this-&gt;_password = (string) $password;
  
                      $this-&gt;_lang = new BattlelogLang($this, $lang);
                  }
  
                  /**
                   * Creates and returns a BF3Soldier using the given soldier's
                   * ID.
                   * 
                   * @access public
                   * @param string $soldierId The ID of the soldier
                   * @return BF3Solider The requested soldier
                   * @since 1.0-beta
                   */
                  public function getBF3Soldier($soldierId)
                  {
                      return new BF3Soldier($this, $soldierId, true);
                  }
  
                  /**
                   * Creates and returns a BF3Server using the given server's
                   * ID.
                   * 
                   * @access public
                   * @param string $serverId The ID of the server
                   * @return BF3Server The requested server
                   * @since 1.3
                   */
                  public function getBF3Server($serverId)
                  {
                      return new BF3Server($this, $serverId, true);
                  }
  
                  /**
                   * Uses the current session to get the text on the given url.
                   * 
                   * @access public
                   * @param string $url The url to grab data from
                   * @param bool $battlelog Whether or not this use is a subportion of 'http://battlelog.battlefield.com/' and needs the cookies
                   * @return string The contents of the given url
                   * @since 1.3
                   */
                  public function getUrl($url, $battlelog = true)
                  {
                      if (!$this-&gt;_hasCredentials)
                      {
                          $this-&gt;_getCredentials();
                          $this-&gt;_hasCredentials = true;
                      }
  
                      if ($battlelog === true)
                      {
                          $ch = curl_init("http://battlelog.battlefield.com/$url");
                          curl_setopt($ch, CURLOPT_COOKIEFILE, BLA_COOKIE_FILE);
                      }
                      else
                      {
                          $ch = curl_init($url);
                      }
                      curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                              'Expect:',
                              'User-Agent: ' . BLA_USER_AGENT,
                              'Accept: */*',
                              'Accept-Language: en-us,en;q=0.5',
                              'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7',
                              'X-Requested-With: XMLHttpRequest',
                              'X-AjaxNavigation: 1'
                      ));
                      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                      curl_setopt($ch, CURLOPT_ENCODING, "gzip");
                      $data = curl_exec($ch);
                      curl_close($ch);
  
                      return $data;
                  }
  
                  /**
                   * Gets credentials required the connect to the Battlelog servers. 
                   * 
                   * @access private
                   * @since 1.0-beta
                   */
                  private function _getCredentials()
                  {
                      $postchars = http_build_query(array(
                              'redirect' =&gt; '|bf3|',
                              'email' =&gt; $this-&gt;_username,
                              'password' =&gt; $this-&gt;_password,
                              'submit' =&gt; 'Sign+in'
                      ), '', '&amp;');
  
                      $ch = curl_init(BLA_LOGIN_URL);
                      curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                              'Expect:',
                              'User-Agent: ' . BLA_USER_AGENT,
                              'Accept: */*',
                              'Accept-Language: en-us,en;q=0.5',
                              'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7'
                      ));
                      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                      curl_setopt($ch, CURLOPT_COOKIEJAR, BLA_COOKIE_FILE);
                      curl_setopt($ch, CURLOPT_POST, 1);
                      curl_setopt($ch, CURLOPT_POSTFIELDS, $postchars);
                      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                      curl_exec($ch);
                      curl_close($ch);
                  }
  
                  /**
                   * Runs the given nameplate through the BF3 locale file to get the
                   * actual name of the item.
                   * 
                   * @access public
                   * @param string $string The nameplate to run through the translator
                   * @return mixed The translated id
                   * @since 1.3
                   */
                  public function translate($string)
                  {
                      return $this-&gt;_lang[$string];
                  }
              }
  
  
              /**
               * Provides common utility methods for miscellaneous battlelog things.
               * 
               * @author      Blake Harley &lt;contact@blakeharley.com&gt;
               * @package     BattlelogApi
               * @since       1.0-beta
               */
              class BattlelogUtils
              {
                  /**
                   * Returns the URL of a rank from the Battlelog CDN.
                   * 
                   * @param string $size The desired image size. Valid sizes are 'tiny', 'small', 'medium' and 'large'. Default size is small.
                   * @since 1.0-beta
                   */
                  public static function getRankImage($rank, $size = 'small')
                  {
                      $validSizes = array('tiny', 'small', 'medium', 'large');
                      $size = strtolower($size);
  
                      if (!in_array($size, $validSizes))
                      {
                          throw new BattlelogException("Invalid size '$size' specified");
                      }
  
                      return "http://battlelog-cdn.battlefield.com/public/profile/bf3/stats/ranks/$size/r$rank.png";
                  }
  
                  /**
                   * Returns the URL of a kit image from the Battlelog CDN.
                   * 
                   * @param string $kit The kit name. Valid kit names are 'assault', 'support', 'engineer', 'recon'.
                   * @param string $team The team designation. Valid teams are 'us' and 'ru'. Defaults to 'us'.
                   * @param string $size The image size. Valid image sizes are 'small', 'medium' and 'large'.
                   * @since 1.0-beta
                   */
                  public static function getKitImage($kit, $team = 'us', $size = 'medium')
                  {
                      $validKits = array('assault', 'recon', 'engineer', 'support');
                      $validTeams = array('us', 'ru');
                      $validSizes = array('small', 'medium', 'large');
                      $kit = strtolower($kit);
                      $team = strtolower($team);
                      $size = strtolower($size);
  
                      if (!in_array($kit, $validKits))
                      {
                          throw new BattlelogException("Invalid kit '$kit' specified");
                      }
                      if (!in_array($team, $validTeams))
                      {
                          throw new BattlelogException("Invalid team '$team' specified");
                      }
                      if (!in_array($size, $validSizes))
                      {
                          throw new BattlelogException("Invalid size '$size' specified");
                      }
  
                      return "http://battlelog-cdn.battlefield.com/public/profile/kits/{$size[0]}/bf3-$team-$kit.png";
                  }
  
                  /**
                   * Returns the URL of a ribbon image from the Battlelog CDN.
                   * 
                   * @param string|int $id The ribbon id.
                   * @param string $size The image size. Valid image sizes are 'small', 'medium' and 'large'.
                   * @since 1.0-beta
                   */
                  public static function getRibbonImage($id, $size = 'medium')
                  {
                      $validSizes = array('small', 'medium', 'large');
                      $size = strtolower($size);
  
                      if (!in_array($size, $validSizes))
                      {
                          throw new BattlelogException("Invalid size '$size' specified");
                      }
  
                      $id = str_pad($id, 2, '0', STR_PAD_LEFT);
                      return "http://battlelog-cdn.battlefield.com/public/profile/bf3/stats/ribbons/{$size[0]}/r$id.png";
                  }
  
                  /**
                   * Returns the URL of a medal image from the Battlelog CDN.
                   * 
                   * @param string|int $id The medal id.
                   * @param string $size The image size. Valid image sizes are 'small', 'medium' and 'large'.
                   * @since 1.3
                   */
                  public static function getMedalImage($id, $size = 'medium')
                  {
                      $validSizes = array('small', 'medium', 'large');
                      $size = strtolower($size);
  
                      if (!in_array($size, $validSizes))
                      {
                          throw new BattlelogException("Invalid size '$size' specified");
                      }
  
                      $id = str_pad($id, 2, '0', STR_PAD_LEFT);
                      return "http://battlelog-cdn.battlefield.com/public/profile/bf3/stats/medals/{$size[0]}/m$id.png";
                  }
  
                  /**
                   * Returns the URL of an item image from the Battlelog CDN.
                   * 
                   * @param string $name The item name
                   * @param string $size The image size. Valid sizes are 'tiny', 'small', 'medium' and 'large'. Default size is medium.
                   * @since 1.0-beta
                   */
                  public static function getItemImage($name, $size = 'medium')
                  {
                      $validSizes = array(
                              'tiny'      =&gt; '79x43',
                              'small'     =&gt; '90x54',
                              'medium'    =&gt; '147x88',
                              'large'     =&gt; '512x308'
                      );
                      $size = strtolower($size);
  
                      if (!array_key_exists($size, $validSizes))
                      {
                          throw new BattlelogException("Invalid size '$size' specified");
                      }
  
                      $name = strtolower($name);
                      return "http://battlelog-cdn.battlefield.com/public/profile/bf3/stats/items_{$validSizes[$size]}/$name.png";
                  }
              }
  
              /**
               * Part of my efforts to produce proper error messages.
               * 
               * @author      Blake Harley &lt;contact@blakeharley.com&gt;
               * @package     BattlelogApi
               * @since       1.3
               */
              class BattlelogException extends Exception { }
  </code></pre>
  
  <p>I really appreciate any help! and thanks for your time!</p>