[c#] Setting the User-Agent header for a WebClient request

What is the proper way of setting the User-Agent header for a WebClient request for Windows Phone 7? I found 2 options, but not sure which one is the correct one. Considering a WebClient object:

WebClient client = new WebClient();

I saw 2 options:

  1. set the User-Agent using:

    client.Headers["User-Agent"] = "myUserAgentString";
    
  2. set the User-Agent using the WebHeaderCollection:

    WebHeaderCollection headers = new WebHeaderCollection();
    headers[HttpRequestHeader.UserAgent] = "userAgentString";
    client.Headers = headers;
    

Can you please advise which of the 2 methods above is the proper one?

This question is related to c# windows-phone-7

The answer is


I found that the WebClient kept removing my User-Agent header after one request and I was tired of setting it each time. I used a hack to set the User-Agent permanently by making my own custom WebClient and overriding the GetWebRequest method. Hope this helps.

public class CustomWebClient : WebClient
{
    public CustomWebClient(){}

    protected override WebRequest GetWebRequest(Uri address)
    {
        var request = base.GetWebRequest(address) as HttpWebRequest;
        request.UserAgent="Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/6.0;)";

        //... your other custom code...

        return request;
    }
}

You can also use that:

client.Headers.Add(HttpRequestHeader.UserAgent, "My app.");

const string ua = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
Request.Headers["User-Agent"] = ua;
var httpWorkerRequestField = Request.GetType().GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic);
if (httpWorkerRequestField != null)
{
    var httpWorkerRequest = httpWorkerRequestField.GetValue(Request);
    var knownRequestHeadersField = httpWorkerRequest.GetType().GetField("_knownRequestHeaders", BindingFlags.Instance | BindingFlags.NonPublic);
    if (knownRequestHeadersField != null)
    {
        string[] knownRequestHeaders = (string[])knownRequestHeadersField.GetValue(httpWorkerRequest);
                    knownRequestHeaders[39] = ua;
    }
}

As a supplement to the other answers, here is Microsoft's guidance for user agent strings for its browsers. The user agent strings differ by browser (Internet Explorer and Edge) and operating system (Windows 7, 8, 10 and Windows Phone).

For example, here is the user agent string for Internet Explorer 11 on Windows 10:

Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko 

and for Internet Explorer for Windows Phone 8.1 Update:

Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 520) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537

Templates are given for the user agent strings for the Edge browser for Desktop, Mobile and WebView. See this answer for some Edge user agent string examples.

Finally, another page on MSDN provides guidance for IE11 on older desktop operating systems.

IE11 on Windows 8.1:

Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko

and IE11 on Windows 7:

Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko

This worked for me:

var message = new HttpRequestMessage(method, url);
message.Headers.TryAddWithoutValidation("user-agent", "<user agent header value>");
var client = new HttpClient();
var response = await client.SendAsync(message);

Here you can find the documentation for TryAddWithoutValidation