Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

OutputFormatter provides no way to disable text encoding #2739

@timothy-shields

Description

@timothy-shields

Title

OutputFormatter provides no way to disable text encoding

Functional impact

It seems impossible to write a class derived from OutputFormatter for handling a custom binary media type that uses no text encoding.

Minimal repro steps

  1. Create new Web API app (using "Microsoft.AspNet.Mvc": "6.0.0-beta4")

  2. Add a MyBinaryOutputFormatter class:

    public class MyBinaryOutputFormatter : OutputFormatter
    {
        public MyBinaryOutputFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/x-mybinary"));
            SupportedEncodings.Add(Encoding.UTF8);
        }
    
        public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
        {
            return context.Object is byte[];
        }
    
        public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            using (var stream = new System.IO.MemoryStream())
            {
                byte[] data = (byte[])context.Object;
                await context.ActionContext.HttpContext.Response.Body.WriteAsync(data, 0, data.Length);
            }
        }
    }
    
  3. Add the output formatter in Startup.cs:

    services.AddMvc().Configure<MvcOptions>(options =>
    {
        options.OutputFormatters.Add(new MyBinaryOutputFormatter());
    });
    
  4. Add a controller and action like the following:

    [HttpGet]
    public byte[] Test()
    {
        return new byte[] { 0xFF };
    }
    
  5. Start the service and do a GET request to the action method using a HTTP client that allows you to inspect the response body contents as hex.

Expected result

Since I write to the response body stream directly, I would expect the bytes I write to be exactly those seen in the response body client-side. That is the response body seen client side should be the single byte FF (hex).

Actual result

The response body seen client side is the single byte FD (hex).

Further technical details

Using Encoding.ASCII instead in the MyBinaryOutputFormatter constructor seems to be a hacky workaround to this problem, but then all responses have a Content-Type header of application/x-mybinary; charset=us-ascii, which doesn't look great to clients.

If the single-byte response is not convincing that the problem is the encoding, try returning a larger byte[] from the Test action method. It quickly becomes evident that the encoding is corrupting the data.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions