C # HttpWebRequest vs WebRequest

112

J'ai vu ce morceau de code:

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

Pourquoi avez-vous besoin de lancer (HttpWebRequest)? Pourquoi ne pas simplement utiliser HttpWebRequest.Create? Et pourquoi fait HttpWebRequest.Createun WebRequest, pas un HttpWebRequest?

Inconnue
la source
post-related: stackoverflow.com/q/8209781/274502
cregox

Réponses:

134

La Createméthode est statique et n'existe que sur WebRequest. L'appeler HttpWebRequest.Createpeut sembler différent, mais il est en fait compilé à l'appel WebRequest.Create. Il ne semble être HttpWebRequestactivé qu'à cause de l'héritage.

La Createméthode utilise en interne le modèle de fabrique pour effectuer la création réelle des objets, en fonction de ce que Urivous lui passez. Vous pouvez en fait récupérer d'autres objets, comme un FtpWebRequestou FileWebRequest, selon le Uri.

David Wengier
la source
3
C'est juste. Cela aurait été bien s'il y avait un moyen d'obtenir un HttpWebRequest à partir de HttpWebRequest.Create ou de quelque chose comme HttpWebRequest.CreateHttp sans cast. Le premier serait quelque chose comme le nouveau HttpWebRequest Create statique public (string url). Dans tous les cas, si l'URL n'était pas HTTP (s), elle devrait simplement lancer une exception InvalidArgumentException.
Matthew Flaschen
4
Une très belle explication d'une décision de conception très étrange (oserais-je dire mal?) Par les créateurs de .NET.
IJ Kennedy
2
@IJKennedy Je suis complètement d'accord, une décision de conception très étrange, illogique et peu pratique.
Aidiakapi
8
HttpWebRequest.CreateHttp existe et crée une instance HttpWebRequest.
Peter Meinl
4
@Bobson WebRequest.CreateHttpest en 4.5
Mark
31

WebRequestest une classe abstraite, qui a une méthode de fabrique Createqui, en fonction de l'URL transmise, crée une instance d'une sous-classe concrète. Le fait que vous ayez besoin ou que vous vouliez HttpWebRequest httpreq = (HttpWebRequest)WebRequest.Create(strUrl);plutôt que cela WebRequest req = WebRequest.Create(strUrl);dépend de vos besoins et du type d'URL que vous transmettez.

Si vous ne passez que des URL HTTP:, alors l'ancien code vous permet d'accéder aux propriétés et méthodes HttpWebRequestimplémentées par la sous-classe en plus de celles définies sur la classe de baseWebRequest . Mais si vous transmettez une URL FTP:, la tentative de conversion HttpWebRequestéchoue.

Ce dernier est générique et n'échouera sur aucun des types d'URL pris en charge, mais bien sûr, sans transtypage vers une sous-classe, vous ne pouvez accéder qu'aux propriétés et aux méthodes définies par la classe de base.

- via Martin Honnen

Orhan Cinar
la source
12

Le cast n'est nécessaire que lorsque vous avez besoin d'accéder à des membres uniques à HttpWebRequest. L'idée est que si les propriétés / méthodes prises en charge sur WebRequest sont suffisantes, vous pouvez alors écrire une application qui fonctionnera avec de nombreux types de protocoles de demande / réponse. Dans ce cas, l'URI peut être quelque chose de donné par l'utilisateur en utilisant n'importe quel protocole pris en charge par des protocoles enfichables. De nouveaux protocoles peuvent même être pris en charge sans modifier le logiciel d'origine.

Si votre application a besoin de plus de contrôle sur les fonctionnalités spécifiques à un protocole particulier, vous pouvez restreindre requestUri à vos schémas pris en charge et convertir WebRequest dans la sous-classe spécifique au protocole appropriée. Cela limite les protocoles pris en charge par votre application, mais vous permet de modifier les fonctionnalités spécifiques au protocole.

Kevin
la source