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:

Unknown said...

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

Regards
Simon.

Dr. M. Elkstein said...

Thanks Simon! I've fixed it now.

Unknown said...

"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.

Dr. M. Elkstein said...

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

Andy said...

Awesome! Thanks Dr. M!

Kapil Dobal said...

Great work Elkstein

Shiv said...

Very well written...thanks!

Srinivasan said...

Nice Post Doc, will you provide some samples in Xquery

Sean Glover said...

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

Unknown said...

Just use @param as the variable name

Kyle said...

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

Dr. M. Elkstein said...

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

vijay said...

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

vijay said...

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

Unknown said...

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

Unknown said...

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

Dr. M. Elkstein said...

Hello LaRae,

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

xweeta said...

Thanks a lot for this amazing article!

Unknown said...

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?

Unknown said...

Very Helpful , Thank you!

Unknown said...

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.