I have an Owin middleware class that I'm using. The purpose is to overwrite the response body when a 401, 403, or 405 HTTP status code is detected and replace the body with a JSON object. This is my method so far:

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;
            }

        }

For the most part it is working, however the response body is being appended to instead of replaced. For example, in the case of a 401 error, the response body is:

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

instead of:

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

I'm sure that it has something to do with the way I'm writing to the response body but nothing so far has resolved the issue.

Any suggestions would be greatly appreciated.

Thank You

1 Answers

0
Raed Noor On

When you first set the response body to the memory stream, the cursor(current position ) would move to the end of it. owinResponse.Body = responseBuffer; , as a result, we got {"message":"Authorization has been denied for this request."}stored and the cursor points at the end.

Again, at the end of your method, you write the new response owinResponse.Body = owinResponseStream; which has the message {"IsError":true,"StatusCode":401,"Data":null,"Message":"unauthorized request"}

Since the current position is pointing at the end of the stream, therefore it will append.

Try to remove the first set of the body owinResponse.Body = responseBuffer; as you don't need the original response message.