OdeToCode IC Logo

Byte Arrays and ASP.NET Core Web APIs

Thursday, February 22, 2018

I’ve decided to write down some of the steps I just went through in showing someone how to create and debug an ASP.NET Core controller. The controller is for an API that needs to accept a few pieces of data, including one piece of data as a byte array. The question asked specifically was how to format data for the incoming byte array.

Instead of only showing the final solution, which you can find if you read various pieces of documentation, I want to show the evolution of the code and a thought process to use when trying to figure out the solution. While the details of this post are specific to sending byte arrays to an API, I think the general process is one to follow when trying to figure what works for an API, and what doesn’t work.

To start, collect all the information you want to receive into a single class. The class will represent the input model for the API endpoint.

public class CreateDocumentModel
    public byte[] Document { get; set; }
    public string Name { get; set; }
    public DateTime CreationDate { get; set; }

Before we use the model as an input to an API, we’ll use the model as an output. Getting output from an API is usually easy. Sending input to an API can be a little bit trickier, because we need to know how to format the data appropriately and fight through some generic error messages. With that in mind, we’ll create a simple controller action to respond to a GET request and send back some mock data.

public IActionResult Get()
    var model = new CreateDocumentModel()
        Document = new byte[] { 0x03, 0x10, 0xFF, 0xFF },
        Name = "Test",
        CreationDate = new DateTime(2017, 12, 27)

    return new ObjectResult(model);

Now we can use any tool to see what our data looks like in a response. The following image is from Postman.

Simple GET Request ASP.NET Core Byte Array

What we see in the response is a string of characters for the “byte array” named document. This is one of those situations where having a few years of experience can help. To someone new, the characters look random. To someone who has worked with this type of data before, the trailing “=” on the string is a clue that the byte array was base64 encoded into the response. I’d like to say this part is easy, but there is no substitute for experience. For beginners, one also has to see how C# properties in PascalCase map to JSON properties in camelCase, which is another non-obvious hurdle to formatting the input correctly. 

Once you’ve figured out to use base64 encoding, it’s time to try to send this data back into the API. Before we add any logic, we’ll create a simple echo endpoint we can experiment with.

public IActionResult CreateDocument([FromBody] CreateDocumentModel model)
    return new ObjectResult(model);

With the endpoint in place, we can use Postman to send data to the API and inspect the response. We’ll make sure to set a Content-Type header to application/json, and then fire off a POST request by copying data from the previous response.

Posting byte array to asp.net core


The model the API returns looks just like the model we sent to the API. Being able to roundtrip the model is a good sign, but we are only halfway through the journey. We now have a piece of code we can experiment with interactively to understand how the code will behave in different circumstances. We want a deeper understanding of how the code behaves because our clients might not always send the model we expect, and we want to know what can go wrong before the wrong things happen.

Here are some questions to ask.

Q: Is a base64 encoded string the only format we can use for the byte array?

A: No. The ASP.NET Core model binder for byte[] also understands how to process a JSON array.

    "document": [1, 2, 3, 254],
    "name": "Test input",
    "creationDate": "2017-12-27T00:00:00"

Q: What happens if the document property is missing in the POST request?

A: The Document property on the input model will be null.

Q: What happens if the base64 encoding is corrupt, or when using an array, a value is outside the range of a byte?

A: The model input parameter itself will be null

I’m sure you can think of other interesting questions.


There are two points I’m making in this post:

1. When trying to figure out how to get some code to work, take small steps that are easy to verify.

2. Once the code is working, it is often worthwhile to spend a little more time to understand why the code works and how the code will behave when the inputs aren’t what you expect.