@demiash

C# HttpWebRequest получить описание ошибки сервера при StatusCode 500?

Оправляю запрос на сервер, где ошибка 500 и в браузере возвращается описание внутренней ошибки сервера
В WebException получаю Status = ConnectionClosed (Запрос был прерван: Соединение было неожиданно закрыто.)
Соответственно в WebException.Response = null

Как мне это обойти и получить ответ сервера, даже если там внутренняя ошибка?

код:
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create("http://localhost/test/request");
            webRequest.Credentials = CredentialCache.DefaultCredentials;
            webRequest.Method = "POST";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] byte1 = encoding.GetBytes("SourceId=15");
            webRequest.ContentLength = byte1.Length;
            using (Stream newStream = webRequest.GetRequestStream()) {
                newStream.Write(byte1, 0, byte1.Length);
            }
            try {
                HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
                using (Stream receiveStream = webResponse.GetResponseStream()) {
                    Encoding encode = System.Text.Encoding.GetEncoding("windows-1251");
                    using (StreamReader readStream = new StreamReader(receiveStream, encode)) {
                        return readStream.ReadToEnd();
                    }
                }
            } catch (WebException ex) {
                HttpWebResponse httpResponse = (HttpWebResponse)ex.Response;
                if (ex.Response != null) {
                    using (Stream stream = ex.Response.GetResponseStream()) {
                        StreamReader reader = new StreamReader(stream, Encoding.UTF8);
                        return reader.ReadToEnd();
                    }
                }

            }
  • Вопрос задан
  • 1138 просмотров
Решения вопроса 1
@demiash Автор вопроса
помогла установка параметра запроса: webRequest.ProtocolVersion = HttpVersion.Version10;

в этом случае в WebException.Response показывает содержимое ответа
и WebException.Status не ConnectionClosed (Запрос был прерван: Соединение было неожиданно закрыто.)
а ProtocolError (Удаленный сервер возвратил ошибку: (500) Внутренняя ошибка сервера.)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
ayazer
@ayazer
Sr. Software Engineer
Никак. На то это и внутренняя ошибка, что клиенту ничего про нее знать не нужно. В браузере вы можете что-то видеть только если сервер запущен с тестовой конфигурацией (когда в случае ошибки отображает страницу со стектрейсом).

UPD

нужное вам поведение можно получить как-то так:

[ApiController]
    public class TestController : ControllerBase
    {
        [HttpGet]
        public Task ChangeStatus()
        {
            throw new Exception("My test exception");
        }
    }


public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter
{
        public void OnActionExecuted(ActionExecutedContext context)
        {
            if (context.Exception != null)
            {
                context.Result = new ObjectResult(new
                {
                    ErrorText = context.Exception.Message,
                    Stacktrace = context.Exception.StackTrace
                })
                { StatusCode = (int)HttpStatusCode.BadRequest };

                context.Exception = null;

                return;
         }
}


тогда дергнув контроллера вы обратно получите 400ую ошибку с контентом

{
"errorText": "My test exception",
"stacktrace": "stacktrace was here"
}

UPD2:
ну и насколько я помню (а я могу быть не прав, но не могу перепроверить сейчас) - HttpWebRequest будет кидать ексепшн для всех не 200 хттп статусов. Потому возможно стектрейс прийдется доставать не очень красиво

WebRequest request = ...;
try
{
  using var response = request.GetResponse();
  ...
}
catch (WebException e)
{
  using var webResponse = (HttpWebResponse)e.Response;
  var code = webResponse.StatusCode;
  var body = ...;

  //...

}


или использовть HttpClient, который ексепшн кидает только если попросить
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы