Перезаписать тело ответа в промежуточном программном обеспечении Owin - PullRequest
0 голосов
/ 23 апреля 2019

У меня есть класс связующего ПО Owin, который я использую. Цель состоит в том, чтобы перезаписать тело ответа при обнаружении кода состояния HTTP 401, 403 или 405 и заменить тело объектом JSON. Это мой метод до сих пор:

public override async Task Invoke(IOwinContext context)
        {
            await Next.Invoke(context);

            if (context.Response.StatusCode == 401 || context.Response.StatusCode == 403 || context.Response.StatusCode == 405)
            {

                var owinResponse = context.Response;
                var owinResponseStream = owinResponse.Body;
                var responseBuffer = new MemoryStream();
                owinResponse.Body = responseBuffer;

                string message;

                switch (context.Response.StatusCode)
                {
                    case 401:
                        message = "unauthorized request";
                        break;
                    case 403:
                        message = "forbidden request";
                        break;
                    default:
                        message = "request not allowed";
                        break;
                }
                var newResponse = new ResponseMessage<string>
                {
                    IsError = true,
                    StatusCode = (HttpStatusCode) Enum.Parse(typeof(HttpStatusCode), context.Response.StatusCode.ToString()),
                    Data = null,
                    Message = message
                };

                var customResponseBody = new StringContent(JsonConvert.SerializeObject(newResponse));
                var customResponseStream = await customResponseBody.ReadAsStreamAsync();
                await customResponseStream.CopyToAsync(owinResponseStream);
                owinResponse.ContentType = "application/json";
                owinResponse.ContentLength = customResponseStream.Length;
                owinResponse.StatusCode = 200;
                owinResponse.Body = owinResponseStream;
            }

        }

По большей части это работает, но вместо ответа вместо него добавляется тело ответа. Например, в случае ошибки 401 тело ответа:

{"message":"Authorization has been denied for this request."}
{"IsError":true,"StatusCode":401,"Data":null,"Message":"unauthorized request"}

вместо:

{"IsError":true,"StatusCode":401,"Data":null,"Message":"unauthorized request"}

Я уверен, что это как-то связано с тем, как я пишу в тело ответа, но пока ничего не решило проблему.

Любые предложения будут с благодарностью.

Спасибо

1 Ответ

0 голосов
/ 23 апреля 2019

Когда вы вначале устанавливаете тело ответа на поток памяти, курсор (текущая позиция) перемещается в его конец. owinResponse.Body = responseBuffer; , в результате мы получили {"message":"Authorization has been denied for this request."} сохранено и курсор указывает на конец.

Опять же, в конце вашего метода вы пишете новый ответ owinResponse.Body = owinResponseStream;, в котором есть сообщение {"IsError":true,"StatusCode":401,"Data":null,"Message":"unauthorized request"}

Так как текущая позиция указывает на конец потока, следовательно, он будет добавлен.

Попробуйте удалить первый набор тела owinResponse.Body = responseBuffer; , поскольку вам не нужно исходное ответное сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...