2

I wrote the following program in C# using .NET 4.7.1:

var req = (HttpWebRequest) WebRequest.Create(myUrl); req.AllowAutoRedirect = false; var rsp = req.GetResponse(); Console.WriteLine(rsp.Headers["Location"]); 

The site I am requesting from is returning a 301 response, and the "Location" header contains the URL to redirect to.

If I do the exact same thing using .NET Core 2.1, I will instead get a WebException thrown from the call to GetResponse. How can I avoid this?

2
  • 1
    Don't use HttpWebRequest to begin with. Use HttpClient and check the status code in the response Commented Oct 16, 2018 at 14:03
  • 1
    It's legacy code. So no not for me to choose. Commented Oct 17, 2018 at 11:30

2 Answers 2

2

Based on this, you need to trap it in try/catch block and inspect the WebException:

If you set AllowAutoRedirect, then you will end up not following the redirect. That means ending up with the 301 response. HttpWebRequest (unlike HttpClient) throws exceptions for non-successful (non-200) status codes. So, getting an exception (most likely a WebException) is expected. So, if you need to handle that redirect (which is HTTPS -> HTTP by the way), you need to trap it in try/catch block and inspect the WebException etc. That is standard use of HttpWebRequest.

That is why we recommend devs use HttpClient which has an easier use pattern.

Something like this:

WebResponse rsp; try { rsp = req.GetResponse(); } catch(WebException ex) { if(ex.Message.Contains("301")) rsp = ex.Result; } 
Sign up to request clarification or add additional context in comments.

Comments

0

I pretty much figured it out while I was working on it, but I thought I'd post it here in case others run into the same issue.

The response is included as part of the exception that is throw, so I was able to get the same behavior as in .NET 4.7.1 by modifying my code to this:

var req = (HttpWebRequest) WebRequest.Create(myUrl); req.AllowAutoRedirect = false; try { var rsp = req.GetResponse(); Console.WriteLine(rsp.Headers["Location"]); } catch (WebException e) { var rsp = (HttpWebResponse) e.Response; if (rsp.StatusCode == HttpStatusCode.Moved || rsp.StatusCode == HttpStatusCode.MovedPermanently || rsp.StatusCode == HttpStatusCode.Found) { Console.WriteLine(rsp.Headers["Location"]); } else throw; } 

5 Comments

Why are you using HttpWebRequest in the first place? Why not HttpClient.GetAsync?
.NET Core isn't legacy almost by definition. You are converting this code already. The workaround you posted here is new code, not legacy. By using HttpWebRequest you lose all HTTP-related benefits provided by .NET Core
Indeed, it's a conversion. And I'm sure you can appreciate that such a rewrite is not always desirable during a conversion.
You just found out why it is. You can't just use 8 year old code in a new runtime - HttpClient was introduced in 2012, along with async/await. The highest priority in ASP.NET Core was given to HttpClient and async/await. All this code could be replaced with a single var response=await httpClient.GetAsync(...); response.Headers.Location ...
"You can't just use 8 year old code in a new runtime" you have been able to all the way through .net framework.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.