I am receiving a System.Net.WebException with the message "The remote name could not be resolved" when trying to do a call to a Web Service with HttpClient in ASP.NET MVC. Bafflingly enough, I have a console application and accompanying unit test that has virtually identical code that works perfectly.
Here's the factory method that creates the HttpClient:
public HttpClient GetHttpClient(bool acceptVersion = true, string acceptType = @"application/json")
    {
        // This line was required to make this run without exception for
        // my unit test
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        string key = "key"; // Obviously, abbreviated
        var client = new HttpClient();
        if (acceptVersion)
        {
            client.DefaultRequestHeaders.Add("Accept-version", "beta");
        }
        client.DefaultRequestHeaders.Add("AccessToken", key);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(acceptType) { CharSet = "utf-8" });
        client.BaseAddress = new Uri("API uri"); // Obviously, edited
        return client;
    }
My factory method is literally line-for-line identical for my working unit test.
Here's the ASP.NET code:
public static async Task<double> PercentOfUsersCurrentlyActive()
    {
        string json;
        using (var client = (new ConnectionFactory()).GetHttpClient(false))
        {
            // The exception occurs on this line
            HttpResponseMessage message = await client.GetAsync("users");
            json = await message.Content.ReadAsStringAsync();
        }
        UserCollection collection = JsonConvert.DeserializeObject<UserCollection>(json);
        int numActive = collection.content.Count(usr => usr.active);
        double average = (double)((double)numActive / (double)collection.content.Count);
        return average;
    }
And my controller:
public class UserController : AsyncController
{
    // GET: User
    public async Task<ActionResult> Index()
    {
        // I get the exception on here
        double user = await Reports.General_Classes.User.GetActiveUsers();
        return View(user);
    }
}
My stack trace is:
[WebException: The remote name could not be resolved: '...']
   System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) +606
   System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar) +64
[HttpRequestException: An error occurred while sending the request.]
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +28
   Reports.General_Classes.<GetActiveUsers>d__36.MoveNext() in ...\User.cs:49
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +24
   Report_Retriever.Controllers.<Index>d__0.MoveNext() in ...\UserController.cs:17
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +97
   System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeAsynchronousActionMethod>b__36(IAsyncResult asyncResult) +17
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +48
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +50
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +225
   System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +48
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
   System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +48
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +48
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36
   System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +48
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +48
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +129  
And here's the working code from my DLL and unit test:
[TestMethod]
public async Task GetActiveUserTests()
{
    double percent = await User.GetActiveUsers();
    Assert.IsTrue(percent >= 0 && percent <= 1);
}
And here's the GetActiveUsers method from my console application DLL (which is essentially identical to the method I'm using above):
public static async Task<double> GetActiveUsers()
{
    string json;
    using (var client = UtilityMethods.GetHttpClient(false))
    {
        HttpResponseMessage message = await client.GetAsync("users");
        json = await message.Content.ReadAsStringAsync();
    }
    UserCollection collection = JsonConvert.DeserializeObject<UserCollection>(json);
    int numActive = collection.content.Count(usr => usr.active);
    double average = (double)((double)numActive / (double)collection.content.Count);
    return average;
}
As part of my research, I read the following Stack Overflow posts:
- ASP.NET Exception: The remote name could not be resolved: 'apiconnector.com'
- System.Net.WebException: The remote name could not be resolved:
In both of those cases, they could access the remote location from a browser but not programmatically. My case is somewhat different, though: I can perform calls against the API from a unit test, but not from an ASP.NET MVC application.
In this post, the original poster was able to access this locally but not from a server. Again, though, this doesn't exactly apply to my case because both are running locally within Visual Studio.
The result is the same no matter how many times I run them - i.e. the unit test always passes and the ASP.NET MVC call always fails.
My question, then, is why does the code work in a unit test but virtually identical code fails in ASP.NET MVC?
