Toutes les réponses précédentes décrivent le problème sans apporter de solution. Voici une méthode d'extension qui résout le problème en vous permettant de définir n'importe quel en-tête via son nom de chaîne.
Usage
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.SetRawHeader("content-type", "application/json");
Classe d'extension
public static class HttpWebRequestExtensions
{
static string[] RestrictedHeaders = new string[] {
"Accept",
"Connection",
"Content-Length",
"Content-Type",
"Date",
"Expect",
"Host",
"If-Modified-Since",
"Keep-Alive",
"Proxy-Connection",
"Range",
"Referer",
"Transfer-Encoding",
"User-Agent"
};
static Dictionary<string, PropertyInfo> HeaderProperties = new Dictionary<string, PropertyInfo>(StringComparer.OrdinalIgnoreCase);
static HttpWebRequestExtensions()
{
Type type = typeof(HttpWebRequest);
foreach (string header in RestrictedHeaders)
{
string propertyName = header.Replace("-", "");
PropertyInfo headerProperty = type.GetProperty(propertyName);
HeaderProperties[header] = headerProperty;
}
}
public static void SetRawHeader(this HttpWebRequest request, string name, string value)
{
if (HeaderProperties.ContainsKey(name))
{
PropertyInfo property = HeaderProperties[name];
if (property.PropertyType == typeof(DateTime))
property.SetValue(request, DateTime.Parse(value), null);
else if (property.PropertyType == typeof(bool))
property.SetValue(request, Boolean.Parse(value), null);
else if (property.PropertyType == typeof(long))
property.SetValue(request, Int64.Parse(value), null);
else
property.SetValue(request, value, null);
}
else
{
request.Headers[name] = value;
}
}
}
Scénarios
J'ai écrit un wrapper pour HttpWebRequest
et je ne voulais pas exposer les 13 en-têtes restreints en tant que propriétés dans mon wrapper. Au lieu de cela, je voulais utiliser un simple Dictionary<string, string>
.
Un autre exemple est un proxy HTTP dans lequel vous devez prendre des en-têtes dans une requête et les transmettre au destinataire.
Il existe de nombreux autres scénarios où il n'est tout simplement pas pratique ou possible d'utiliser des propriétés. Forcer l'utilisateur à définir l'en-tête via une propriété est une conception très rigide, c'est pourquoi une réflexion est nécessaire. L'avantage est que la réflexion est abstraite, elle est toujours rapide (0,001 seconde dans mes tests) et, en tant que méthode d'extension, elle semble naturelle.
Remarques
Les noms d'en-tête sont insensibles à la casse selon la RFC, http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2