Monday 9 June 2008

How do I submit web requests at runtime in C#.NET?

This utility class will make a web request programmatically and return the response as a string. I use it for calling ReST services that simply return custom XML which is then parsed using my serialization techniques mentioned in a previous post.

using System;
using System.IO;
using System.Net;
using System.Runtime.Serialization;
using System.Text;

public class WebRequestResult
{
private HttpStatusCode outcome;

public HttpStatusCode Outcome
{
get { return outcome; }
set { outcome = value; }
}

private string response;

public string Response
{
get { return response; }
set { response = value; }
}
}

public enum HTTPMethod
{
DELETE,
GET,
POST,
PUT
};

public static class WebRequestUtility
{
private const string DEFAULT_CONTENT_TYPE = "text/plain";
private const string XML_CONTENT_TYPE = "text/xml";

#region No authentication
public static WebRequestResult Submit( string uri, HTTPMethod httpMethod, WebHeaderCollection headers )
{
return Submit( uri, null, null, httpMethod, DEFAULT_CONTENT_TYPE, headers, null );
}

public static WebRequestResult Submit( string uri, HTTPMethod httpMethod, string data )
{
return Submit( uri, null, null, httpMethod, DEFAULT_CONTENT_TYPE, null, data );
}

public static WebRequestResult Submit( string uri, HTTPMethod httpMethod, WebHeaderCollection headers, string data )
{
return Submit( uri, null, null, httpMethod, DEFAULT_CONTENT_TYPE, headers, data );
}

public static WebRequestResult Submit( string uri, HTTPMethod httpMethod, string contentType, WebHeaderCollection headers )
{
return Submit( uri, null, null, httpMethod, contentType, headers, null );
}

public static WebRequestResult Submit( string uri, HTTPMethod httpMethod, string contentType, string data )
{
return Submit( uri, null, null, httpMethod, contentType, null, data );
}

public static WebRequestResult Submit( string uri, HTTPMethod httpMethod, string contentType, WebHeaderCollection headers, string data )
{
return Submit( uri, null, null, httpMethod, contentType, headers, data );
}
#endregion

#region Username/password authentication
public static WebRequestResult Submit( string uri, string username, string password, HTTPMethod httpMethod )
{
return Submit( uri, username, password, httpMethod, DEFAULT_CONTENT_TYPE, null, null );
}

public static WebRequestResult Submit( string uri, string username, string password, HTTPMethod httpMethod, WebHeaderCollection headers )
{
return Submit( uri, username, password, httpMethod, DEFAULT_CONTENT_TYPE, headers, null );
}

public static WebRequestResult Submit( string uri, string username, string password, HTTPMethod httpMethod, string data )
{
return Submit( uri, username, password, httpMethod, DEFAULT_CONTENT_TYPE, null, data );
}

public static WebRequestResult Submit( string uri, string username, string password, HTTPMethod httpMethod, string contentType, WebHeaderCollection headers )
{
return Submit( uri, username, password, httpMethod, contentType, headers, null );
}

public static WebRequestResult Submit( string uri, string username, string password, HTTPMethod httpMethod, string contentType, string data )
{
return Submit( uri, username, password, httpMethod, contentType, null, data );
}
#endregion

public static WebRequestResult Submit( string uri, string username, string password, HTTPMethod httpMethod, string contentType, WebHeaderCollection headers, string data )
{
WebRequestResult result = new WebRequestResult();

StringBuilder response = new StringBuilder();

HttpWebRequest httpWebRequest = null;
HttpWebResponse httpWebResponse = null;

try
{
httpWebRequest = ( HttpWebRequest )WebRequest.Create( uri );

if ( !string.IsNullOrEmpty( username ) && !string.IsNullOrEmpty( password ) )
{
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add( new Uri( uri ), "Basic", new NetworkCredential( username, password ) );

httpWebRequest.Credentials = credentialCache;
}

if ( headers != null )
{
foreach ( string key in headers.Keys )
{
httpWebRequest.Headers.Add( key, headers[key] );
}
}

httpWebRequest.Method = httpMethod.ToString();
httpWebRequest.ContentType = contentType;

if ( !string.IsNullOrEmpty( data ) )
{
using ( StreamWriter streamWriter = new StreamWriter( httpWebRequest.GetRequestStream() ) )
{
streamWriter.WriteLine( data );
}
}
else
{
httpWebRequest.ContentLength = 0;
}

httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

if ( httpWebResponse != null )
{
result.Outcome = httpWebResponse.StatusCode;

using ( StreamReader streamReader = new StreamReader( httpWebResponse.GetResponseStream() ) )
{
while ( streamReader.Peek() != -1 )
{
response.Append( streamReader.ReadLine() );
}
}
}
}
catch ( WebException exception )
{
httpWebResponse = exception.Response as HttpWebResponse;

if ( httpWebResponse != null )
{
result.Outcome = httpWebResponse.StatusCode;
}
else
{
result.Outcome = HttpStatusCode.InternalServerError;
}

response.Append( exception.Message );
}
catch ( Exception exception )
{
result.Outcome = HttpStatusCode.InternalServerError;

response.Append( exception.Message );
}
finally
{
try
{
if ( httpWebRequest != null )
{
httpWebRequest.GetRequestStream().Close();
}
}
catch { }

try
{
if ( httpWebResponse != null )
{
httpWebResponse.GetResponseStream().Close();
}
}
catch { }
}

result.Response = response.ToString();

return result;
}

#region No authentication
public static WebRequestResult SubmitXML( string uri, HTTPMethod httpMethod, WebHeaderCollection headers, string xml )
{
return Submit( uri, httpMethod, XML_CONTENT_TYPE, headers, xml );
}
#endregion

#region Username/password authentication
public static WebRequestResult SubmitXML( string uri, string username, string password, HTTPMethod httpMethod, string xml )
{
return Submit( uri, username, password, httpMethod, XML_CONTENT_TYPE, xml );
}

public static WebRequestResult SubmitXML( string uri, string username, string password, HTTPMethod httpMethod, WebHeaderCollection headers, string xml )
{
return Submit( uri, username, password, httpMethod, XML_CONTENT_TYPE, headers, xml );
}
#endregion
}

1 comment:

Anonymous said...

Andrew,

Thanks for making this post. I really like the utility.

However I get a 401 error when using basic authentication with a null user name or an empty string as the username. By default the web site I am trying access uses a blank user name with a password.

I believe this is actually a limitation to the HttpWebRequest class or the NetworkCredential class and not your application.
Do you have any thoughts on this?