skip to Main Content

I was speculating how to receive a clean byte array from a web-api (no encode/decode in base64). I still don’t know if this is possible. Possibly there are things that I am doing wrong, or that I don’t know yet. I have created a simple example to explain the issue. As you can see I’m just trying to send a text string encoded in a byte array, and decode it on the client side.

Backend, a minimal API

using System.Net;
using System.Net.Http.Headers;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/GetQuote", () => HttpBinaryDataTest.GetQuote());

app.Run();

class HttpBinaryDataTest
{
    public static HttpResponseMessage GetQuote()
    {
        var text = "I became insane, with long intervals of horrible sanity.";
        var bytes = Encoding.UTF8.GetBytes(text);

        var response = new HttpResponseMessage(HttpStatusCode.OK) {
            Content = new ByteArrayContent(bytes)
        };
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

        return response;
    }
}

Frontend Test, a console application

using System.Text;

Console.WriteLine("Http Binary Test");
Console.WriteLine("Press any key to start...");
Console.ReadKey();

var h = new HttpTest();

var quote = await h.GetQuote();
Console.WriteLine(quote);

Console.WriteLine("Press any key to end...");
Console.ReadKey();

h.Dispose();

// -------------------------------------------------------

class HttpTest : IDisposable
{
    string apiRoot = "http://localhost:5274/"; // ApiTest
    readonly HttpClient client;

    public HttpTest()
    {
        client = new HttpClient {
            BaseAddress = new Uri(apiRoot)
        };
    }

    public async Task<string> GetQuote()
    {
        var response = await client.GetAsync($"GetQuote");

        var bytes = await response.Content.ReadAsByteArrayAsync();

        var decodedText = Encoding.UTF8.GetString(bytes);

        // Should be:
        // I became insane, with long intervals of horrible sanity.

        return decodedText;
    }

    public void Dispose() => client?.Dispose();
}


When I run the client, what I get is a JSON, without errors, but I don’t know how to get the data I expect. What am I missing? What am I doing wrong? The response:

 {
"version": "1.1",
"content": {
    "headers": [{
            "key": "Content-Type",
            "value": ["application/octet-stream"]
        }
    ]
},
"statusCode": 200,
"reasonPhrase": "OK",
"headers": [],
"trailingHeaders": [],
"requestMessage": null,
"isSuccessStatusCode": true
}

2

Answers


  1. You can do it by editing the server code as follow:

    using System.IO;
    using System.Net;
    using System.Net.Http.Headers;
    using System.Text;
    
    var builder = WebApplication.CreateBuilder(args);
    
    var app = builder.Build();
    
    app.MapGet("/GetQuote", () => Results.Stream(HttpBinaryDataTest.GetQuote()));
    
    app.Run();
    
    class HttpBinaryDataTest
    {
        public static MemoryStream GetQuote()
        {
            var text = "I became insane, with long intervals of horrible sanity.";
            var bytes = Encoding.UTF8.GetBytes(text);
            var ms = new MemoryStream(bytes);
            return ms;
        }
    }
    

    The console app execution result was

    Http Binary Test Press any key to start…
    I became insane, with long intervals of horrible sanity.
    Press any key to end…

    In your code sample the minimal API was taking the HTTP response you are creating as body of An HTTP response. So not the right approach.
    I used Postman to test, it made it easier to discover that.

    Since you need binary or As we call it stream, Looking at MS docs for minimal API I found this: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis?view=aspnetcore-6.0#stream

    Login or Signup to reply.
  2. How about using Results.Bytes() :

    using System.Text;
    
    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    app.MapGet("/GetQuote", () => Results.Bytes(HttpBinaryDataTest.GetQuote()));
    
    app.Run();
    
    class HttpBinaryDataTest
    {    
        public static byte[] GetQuote()
        {
            var text = "I became insane, with long intervals of horrible sanity.";
    
            return Encoding.UTF8.GetBytes(text);
        }
    }
    

    This works for your test application

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search