Request/Response Objects



Request/Response Objects

A client program generally wants to send a network request to a server and receive some sort of response. The .NET Framework provides a protocol-independent way of doing this through the abstract base classes WebRequest and WebResponse. These protocol-independent classes enforce a common programmatic interface onto their protocol-specific descendant classes, an architecture known as "pluggable protocols." This is analogous to the way the abstract base class System.IO.Stream enforces a common programmatic interface onto all streams regardless of their backing medium.

A client that wants to perform a network request/response operation obtains a WebRequest-derived object by calling the static method WebRequest.Create, passing the URI of the desired target. The system looks up the protocol prefix (e.g., "http:"), finds which WebRequest-derived class is registered as handling that protocol, and returns an instance of it. The creator of the derived instance (often the derived class itself, sometimes a separate factory object) must implement the IWebRequestCreate interface to support this creation mechanism. The protocols are registered with the system at deployment time via the static method WebRequest.Register. The method WebRequest.GetResponse sends the request to the server, optionally uploading data with it, and receives a WebResponse object containing the server's response.

Client applications will often need to set properties of the WebRequest before making the call to GeTResponse. For example, servers often require clients to authenticate themselves with some sort of credentials. The WebRequest carries these credentials in a property called Credentials, which contains an object that implements the ICredentials interface. The class NetworkCredential provides a default implementation of this interface which you can use for this purpose. If your application is communicating with several different servers, you might find it easier to use an object of class CredentialCache, which also implements the ICredentials interface. It can hold multiple sets of credentials, each associated with a separate URI. When the server requests authentication credentials, the CredentialCache searches for the URI and returns the right set of credentials for it.

When the client makes a request, a server that requires authentication will send back a challenge to the client, asking for the user's credentials. This challenge is interpreted by an authentication module, which is an object that implements the IAuthenticationModule interface. This interface contains methods that interpret the server's challenge and return an Authorization object containing the correct set of user's credentials. The static class AuthenticationManager manages one or more authentication modules.

The client may need to supply network headers for its request, and look at the network headers returned by the server. The Headers property of a WebRequest or WebResponse object contains an object of class WebHeaderCollection, which holds the name/value pair headers sent to and received from the server.

Network requests often need to go through proxy servers, for example, to pass through firewalls. Since it is common for all requests in an application to go through the same proxy, the class GlobalProxySelection contains static methods to set the proxy server for all WebRequests that don't explicitly override it. You can override the global settings by using the Proxy property of the WebRequest, supplying an object that implements the IWebProxy interface. The class WebProxy provides a default implementation of this interface.

The classes HttpWebRequest and HttpWebResponse provide HTTP-specific implementations of the abstract, protocol-agnostic WebRequest and WebResponse classes. Internally, they use the object of class HttpVersion to specify the version of HTTP that a specific WebRequest or WebResponse is using. The status of an HttpWebResponse is a member of the HttpStatusCode enumeration. If you'd like to override the default behavior of a "continue" request in HTTP, you can plug in your own handler using an object of class HttpContinueDelegate.

The WebClient class provides a simple wrapper through which a client can make a network request and receive a response. It uses the WebRequest-and WebResponse-derived classes internally without exposing them to the caller. It is simpler to program for the most common cases.