0

I'm trying to translate this piece of code written to fetch data from basis's website (the activity tracker). The task I want to achieve here is to fetch the access_token returned in the Http response header. There is no problem with the original PHP code, however, there are a few cUrl options I don't know how to map to C#'s WebClient implementation. These options include CURLOPT_RETURNTRANSFER, CURLOPT_FOLLOWLOCATION and CURLOPT_COOKIESESSION.

The detail problem is listed below, here is the piece of PhP code:

    $login_data = array(
        'username' => $this->username,
        'password' => $this->password,
    );

    // Initialize the cURL resource and make login request
    $ch = curl_init();
    curl_setopt_array($ch, array(
        CURLOPT_URL => 'https://app.mybasis.com/login',
        CURLOPT_RETURNTRANSFER => false, //default: true
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $login_data,
        CURLOPT_FOLLOWLOCATION => true, // defulat: true
        CURLOPT_HEADER => 1,
        CURLOPT_COOKIESESSION => true,
        CURLOPT_COOKIEJAR => $this->cookie_jar
    ));

Using this code, the result would be: (which contains the access token I need)

HTTP/1.1 100 Continue

HTTP/1.1 302 Found
Date: Sun, 22 Jun 2014 02:03:47 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Connection: keep-alive
Server: TornadoServer/3.2
Location: https://app.mybasis.com
Cache-Control: max-age=0
Set-Cookie: access_token=f0659120d52f3fde9edfw1d908b81f0f; Domain=.    mybasis.com; expires=Sun, 01 Jan 2040 00:00:00 GMT; Path=/
Set-Cookie: scope=login; Domain=.mybasis.com; expires=Sun, 01 Jan     2040 00:00:00 GMT; Path=/
Set-Cookie: refresh_token=982ff518bfe114e2c03f360f0dfbfke1; Domain=.    mybasis.com; expires=Sun, 01 Jan 2040 00:00:00 GMT; Path=/

HTTP/1.1 200 OK
Server: nginx/1.4.3
Date: Sun, 22 Jun 2014 02:03:47 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 5619
Last-Modified: Fri, 25 Apr 2014 04:42:49 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: "5359e7c9-15f3"
Accept-Ranges: bytes

However, when I use C# WebClient to communicate with basis like below:

 var data = new NameValueCollection
 {
     { "username", username},
     { "password", password},
 };

 HttpWebResponse response = client.UploadValues("https://app.mybasis.com/login", "POST", data);

 foreach (string name in client.ResponseHeaders.Keys)
 {
     Console.WriteLine(name+"="+client.ResponseHeaders[name]);
 }

I could only get this:

Connection=keep-alive
Vary=Accept-Encoding
Accept-Ranges=bytes
Content-Length=5619
Content-Type=text/html; charset=utf-8
Date=Sun, 22 Jun 2014 02:17:44 GMT
ETag="53f3e7c9-99f3"
Last-Modified=Fri, 25 Apr 2014 04:42:49 GMT
Server=nginx/1.4.3

as response.

Does anyone know why I cannot get the first two Http responses but the third one only?

cchuang
  • 37
  • 6
  • check this (duplicate) question http://stackoverflow.com/questions/7929013/making-a-curl-call-in-c-sharp – xmojmr Jun 24 '14 at 11:53

2 Answers2

0

In order to get the functionality out of C# you are looking for you need to use the Http web Request API within the .NET framework. It should provide the capability you are looking for.

Ryanb58
  • 351
  • 1
  • 16
  • Yes I do use the HttpWebRequest API, however, my problem is I cannot find the options to translate CURLOPT_RETURNTRANSFER, CURLOPT_FOLLOWLOCATION and CURLOPT_COOKIESESSION to .NET. – cchuang Jun 22 '14 at 13:15
  • C# isn't PHP so try to think of it differently. I believe the HttpWebRequest Library that MS provides will already return the data with out you needing to ask, along with following location headers and such. As for the cookie session you can refer to this post : http://stackoverflow.com/questions/4158448/c-sharp-webrequest-using-cookies – Ryanb58 Jul 01 '14 at 17:47
0

I did the same thing but used the 4.5 HttpClient

        CookieContainer cookies = new CookieContainer();
        HttpClientHandler handler = new HttpClientHandler();
        handler.CookieContainer = cookies;

        HttpClient client = new HttpClient(handler);


        // Create the HttpContent for the form to be posted.
        var requestContent = new FormUrlEncodedContent(new[] {
            new KeyValuePair<string, string>("username", "***"),
            new KeyValuePair<string, string>("password", "***"),
        });

        // Get the response.
        HttpResponseMessage response = await client.PostAsync(
            "https://app.mybasis.com/login",
            requestContent);

        // Get the response content.
        HttpContent responseContent = response.Content;


        Uri uri = new Uri("https://app.mybasis.com/login");
        IEnumerable<Cookie> responseCookies = cookies.GetCookies(uri).Cast<Cookie>();
        foreach (Cookie cookie in responseCookies)
            Console.WriteLine(cookie.Name + ": " + cookie.Value);
Bryan Roberts
  • 3,449
  • 1
  • 18
  • 22