Todas las respuestas anteriores describen el problema sin proporcionar una solución. Aquí hay un método de extensión que resuelve el problema al permitirle configurar cualquier encabezado a través de su nombre de cadena.
Uso
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.SetRawHeader("content-type", "application/json");
Clase de extensión
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;
}
}
}
Escenarios
Escribí un contenedor para HttpWebRequest
y no quería exponer los 13 encabezados restringidos como propiedades en mi contenedor. En cambio, quería usar un simpleDictionary<string, string>
.
Otro ejemplo es un proxy HTTP donde necesita tomar encabezados en una solicitud y reenviarlos al destinatario.
Hay muchos otros escenarios en los que no es práctico ni posible usar propiedades. Forzar al usuario a establecer el encabezado a través de una propiedad es un diseño muy inflexible, por lo que se necesita reflexión. Lo bueno es que el reflejo se abstrae, sigue siendo rápido (0,001 segundo en mis pruebas) y, como método de extensión, se siente natural.
Notas
Los nombres de encabezado no distinguen entre mayúsculas y minúsculas según RFC, http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2