C# HttpWebRequest vs WebRequest
Asked Answered
N

4

116

I saw this piece of code:

var request = (HttpWebRequest) WebRequest.Create("http://www.google.com");

Why do you need to cast (HttpWebRequest)? Why not just use HttpWebRequest.Create? And why does HttpWebRequest.Create make a WebRequest, not a HttpWebRequest?

Natty answered 22/5, 2009 at 3:35 Comment(1)
M
137

The Create method is static, and exists only on WebRequest. Calling it as HttpWebRequest.Create might look different, but its actually compiled down to calling WebRequest.Create. It only appears to be on HttpWebRequest because of inheritance.

The Create method internally, uses the factory pattern to do the actual creation of objects, based on the Uri you pass in to it. You could actually get back other objects, like a FtpWebRequest or FileWebRequest, depending on the Uri.

Maeda answered 22/5, 2009 at 3:38 Comment(7)
This is right. It would have been nice if there was a way to get a HttpWebRequest from either HttpWebRequest.Create or something like HttpWebRequest.CreateHttp without casting. The first would be something like public new static HttpWebRequest Create(string url). Either way, if the url wasn't HTTP(s), it should just throw some InvalidArgumentException.Greenquist
A very nice explanation of a very strange design decision (dare I say wrong?) by the .NET creators.Drawstring
@I.J.Kennedy I completely agree, a very strange, illogical, and unpractical design decision.Flogging
HttpWebRequest.CreateHttp does exist and does create a HttpWebRequest instance.Pfeiffer
This didn't answer it to me, at all (though, after I did understand the difference, this makes all sense). Researching more and more, did. To me, seems like the difference is actually just a code design choice.Gambrell
@PeterMeinl - As far as I can tell, that only exists in the PCL version.Tempest
@Tempest WebRequest.CreateHttp is in 4.5Hoxie
M
34

WebRequest is an abstract class, which has a factory method Create that, depending on the URL passed in, creates an instance of a concrete subclass. Whether you need or want HttpWebRequest httpreq = (HttpWebRequest)WebRequest.Create(strUrl); instead of WebRequest req = WebRequest.Create(strUrl); depends on your needs, and on what kind of URLs you pass in.

If you only pass in HTTP: URL's, then the former code allows you to access the properties and methods the subclass HttpWebRequest implements in addition to those defined on the base class WebRequest. But if you passed in a FTP: URL then the attempt to cast to HttpWebRequest would fail.

The latter is generic and won't fail on any of the types of supported URL's but of course without casting to any subclass you can only access the properties and methods the base class defines.

-- via Martin Honnen

Moriyama answered 8/10, 2009 at 10:7 Comment(0)
B
12

The cast is only necessary when you need access to members unique to HttpWebRequest. The idea is that if the properties/methods supported on WebRequest are sufficient, then you can write an application that will work against many types of request/response protocols. In this case the URI could be something given by the user using any protocol supported by pluggable protocols. New protocols can even be supported without altering the original software.

If your application needs more control over features specific to a particular protocol then you can restrict requestUri to your supported scheme(s) and cast WebRequest to the appropriate protocol-specific subclass. This limits the protocols supported by your application, but enables you to tweak protocol-specific features.

Brufsky answered 2/5, 2012 at 23:4 Comment(0)
K
0

We will be using WebRequest method because it will work as generic method for transparently retriving file from

  • Web servers,
  • FTP servers and
  • File server

So

var httpRequest = WebRequest.Create("http://somedomain.com");       // return an instance of type(HttpWebRequest)
var ftpRequest = WebRequest.Create("ftp://ftp.somedomain.com");     // return an instance of type(FtpWebRequest)
var fileRequest = WebRequest.Create("file://files.somedomain.com"); // return an instance of type(FileWebRequest)

Return Type of all three methods (HttpWebRequest, FtpWebRequest, FileWebRequest) all drive from base class WebRequest which is return type of WebRequest.Create(string). Now which subclass to instantiate is determined using the protocol prefixes (http:, https:, ftp:, file:)

So, any URI string (with any of these four prefixes) you pass to the Create method will be transparently handled by the WebRequest base class so you don't even have to know specifically what sub-class was returned

Kith answered 4/7, 2022 at 12:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.