How does one configure HttpClient not to automatically redirect when it receives a 301 HTTP Status Code?

35,446

Try:

var handler = new HttpClientHandler() 
{
    AllowAutoRedirect = false
};

HttpClient client = new HttpClient(handler);
Share:
35,446
bloudraak
Author by

bloudraak

Born in Cape Town, South Africa, now living in San Francisco, CA.

Updated on September 25, 2020

Comments

  • bloudraak
    bloudraak over 3 years

    Consider an ASP.NET Web API service that redirects

    public class ThisController : ApiController
    {
        /* more methods */
    
        public override HttpResponseMessage Post()
        {
            var result = new HttpResponseMessage(HttpStatusCode.MovedPermanently);
            // Post requests should be made to "ThatController" instead.
            string uri = Url.Route("That", null);
            result.Headers.Location = new Uri(uri, UriKind.Relative);
            return result;
        }
    }
    

    Trying to verify that POST'ing data to "api/this" will redirect you to "api/that", I have the following test method:

    [TestMethod]
    public void PostRedirects()
    {
        using (var client = CreateHttpClient("application/json"))
        {
            var content = CreateContent(expected, "application/json");
            using (var responseMessage = client.PostAsync("api/this", content).Result)
            {
                Assert.AreEqual(HttpStatusCode.MovedPermanently, responseMessage.StatusCode);
                Assert.AreEqual(new Uri("https://api.example.com/api/that"), responseMessage.Headers.Location);
            }
        }
    }
    
    protected HttpClient CreateHttpClient(string mediaType)
    {
        var client = new HttpClient();
        client.BaseAddress = new Uri("http://api.example.com/");
        MediaTypeWithQualityHeaderValue headerValue = MediaTypeWithQualityHeaderValue.Parse(mediaType);
        client.DefaultRequestHeaders.Accept.Add(headerValue);
        client.DefaultRequestHeaders.AcceptEncoding.Add(StringWithQualityHeaderValue.Parse("gzip"));
        client.DefaultRequestHeaders.AcceptEncoding.Add(StringWithQualityHeaderValue.Parse("deflate"));
        client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(new ProductHeaderValue("MyProduct", "1.0")));
        client.MaxResponseContentBufferSize = 1024*1024*8;
        return client;
    }
    
    protected ObjectContent CreateContent(T model, string mediaType)
    {
        var requestMessage = new HttpRequestMessage();
        MediaTypeFormatter mediaTypeFormatter = null;
        switch (mediaType)
        {
            case "application/json":
                mediaTypeFormatter = new JsonMediaTypeFormatter();
                break;
    
            case "application/xml":
            case "text/xml":
                mediaTypeFormatter = new XmlMediaTypeFormatter();
                break;
    
            default:
                Assert.Fail();
                break;
        }
    
        return requestMessage.CreateContent(
            model,
            new[] { mediaTypeFormatter },
            new FormatterSelector());
    }
    

    What really happens that is that a HTTP Status Code is sent to the client with the correct Location header and that HttpClient then automatically performs a GET on that URI. As a result, my test never passes.

    How do I configure the HttpClient not to automatically redirect when it receives a 301 so that I can verify that my server response?