12.1. Using REST in C#

Issuing HTTP GET Requests
The key classes here are HttpWebRequest and HttpWebResponse from System.Net.

The following method issues a request and returns the entire response as one long string:

static string HttpGet(string url) {
  HttpWebRequest req = WebRequest.Create(url)
                       as HttpWebRequest;
  string result = null;
  using (HttpWebResponse resp = req.GetResponse()
                                as HttpWebResponse)
  {
    StreamReader reader =
        new StreamReader(resp.GetResponseStream());
    result = reader.ReadToEnd();
  }
  return result;
}

Remember that if the request URL includes parameters, they must be properly encoded (e.g., a space is %20, etc.). The System.Web namespace has a class called HttpUtility, with a static method called UrlEncode for just such encoding.

Issuing HTTP POST Requests
URL encoding is also required for POST requests -- in addition to form encoding, as shown in the following method:

static string HttpPost(string url, 
    string[] paramName, string[] paramVal)
{
  HttpWebRequest req = WebRequest.Create(new Uri(url)) 
                       as HttpWebRequest;
  req.Method = "POST";  
  req.ContentType = "application/x-www-form-urlencoded";

  // Build a string with all the params, properly encoded.
  // We assume that the arrays paramName and paramVal are
  // of equal length:
  StringBuilder paramz = new StringBuilder();
  for (int i = 0; i < paramName.Length; i++) {
    paramz.Append(paramName[i]);
    paramz.Append("=");
    paramz.Append(HttpUtility.UrlEncode(paramVal[i]));
    paramz.Append("&");
  }

  // Encode the parameters as form data:
  byte[] formData =
      UTF8Encoding.UTF8.GetBytes(paramz.ToString());
  req.ContentLength = formData.Length;

  // Send the request:
  using (Stream post = req.GetRequestStream())  
  {  
    post.Write(formData, 0, formData.Length);  
  }

  // Pick up the response:
  string result = null;
  using (HttpWebResponse resp = req.GetResponse()
                                as HttpWebResponse)  
  {  
    StreamReader reader = 
        new StreamReader(resp.GetResponseStream());
    result = reader.ReadToEnd();
  }

  return result;
}

For more examples, see this page on the Yahoo! Developers Network.

21 comments:

  1. Your code for GET request has a slight typo - instead of "response" it should say "result".

    Regards
    Simon.

    ReplyDelete
  2. "params" is a keyword in C# now.
    http://msdn.microsoft.com/en-us/library/w5zay9db%28VS.71%29.aspx

    Maybe you could modify the code (POST example) to avoid using it.

    ReplyDelete
  3. Thanks Amr! I've changed it to "paramz". Hopefully, that won't become a keyword anytime soon...

    ReplyDelete
  4. Nice Post Doc, will you provide some samples in Xquery

    ReplyDelete
  5. It's a better idea to use System.Uri.EscapeUriString to encode URL's instead of UrlEncode. UrlEncode doesn't encode spaces as their hex representation %20. An old post, but still relevant: http://blogs.msdn.com/b/yangxind/archive/2006/11/09/don-t-use-net-system-uri-unescapedatastring-in-url-decoding.aspx. EscapeUriString MSDN doc: http://msdn.microsoft.com/en-us/library/system.uri.escapeuristring.aspx

    ReplyDelete
  6. Make sure to capitalize the "Append", "ToString", and "ContentLength". It didnt like that it was lower case.

    ReplyDelete
  7. Thanks, Kyle J. I've fixed the code now.

    ReplyDelete
  8. Hi,

    Thanks a lot for the tutorial. i was breaking my head before. this helped me a lot specially with C#. can i also request you to post some example methods for ALM(QC)

    thanks
    Bhargav

    ReplyDelete
  9. Hi,

    Thanks a lot for the tutorial. i was breaking my head before. this helped me a lot specially with C#. can i also request you to post some example methods for ALM(QC)

    thanks
    Bhargav

    ReplyDelete
  10. Thank you for such a helpful tutorial, recently I am gathering knowledge about WS testing, your documentations helped me a lot!

    ReplyDelete
  11. Could you explain the byte lenght you're passing into the request and why this is needed?

    ReplyDelete
  12. Hello LaRae,

    It's for the HTTP Content-Length request header (see here for details about it).

    ReplyDelete
  13. Thanks a lot for this amazing article!

    ReplyDelete
  14. Hello!

    I dont understand about POST-request.
    Should i send xml into service? *service written at java*

    or, i shoult fill string[] paramName, string[] paramVal just like Dictionary?

    ReplyDelete
  15. paramz.remove((paramz.length - 1), 1) should be added after the for loop in the example post request above to take off the "&" that is currently being left on the end of the StringBuilder object.

    ReplyDelete