-
Notifications
You must be signed in to change notification settings - Fork 2.1k
OutputFormatter provides no way to disable text encoding #2739
Description
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
-
Create new Web API app (using
"Microsoft.AspNet.Mvc": "6.0.0-beta4"
) -
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); } } }
-
Add the output formatter in
Startup.cs
:services.AddMvc().Configure<MvcOptions>(options => { options.OutputFormatters.Add(new MyBinaryOutputFormatter()); });
-
Add a controller and action like the following:
[HttpGet] public byte[] Test() { return new byte[] { 0xFF }; }
-
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.