Search code examples
c#asp.net-corepostasp.net-web-apihttpwebrequest

Returning byte[] data on POST request in does not return the same data I need when calling it through HttpWebRequest


I have a simple POST method in my ASP.NET Core Controller and I'm calling it through HttpWebRequest to demonstrate the problem.

Here is my code for the controller method:

[HttpPost]
[Route("test")]
public byte[] Test()
{
    var resp = new byte[] {1, 2, 3};
    return resp;
}

And here is my client code that calls it:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://127.0.0.1:8080/SCVP/test");
request.Method = "POST";

WebResponse response = request.GetResponse();
Stream dataStream = response.GetResponseStream();

using (MemoryStream ms = new MemoryStream())
{
     dataStream.CopyTo(ms);
     byte[] data = ms.ToArray();
}

The issue is, when I debug, I see that the byte[] being sent back from the controller is correctly [1, 2, 3], however, when I receive it in the client, it has length of 6 and the bytes are entirely different.

I thought this may have to do with Content Type but after some Google searches it seems returning a byte[] should not need a specific Content Type to be provided.

What am I missing here?

EDIT: I need it to be POST since I'm posting data but I omitted that here for simplicity. I also need to return an array of bytes.


Solution

  • I figured out what the problem was.

    ASP.NET converts the byte[] to Base64 behind the scenes. Therefore, the byte[] I was receiving should be converted like this:

    using (MemoryStream ms = new MemoryStream())
    {
       dataStream.CopyTo(ms);
       byte[] data = ms.ToArray();
       byte[] originalData = 
           Convert.FromBase64String(Encoding.UTF8.GetString(data).Replace("\"", ""));
    }
    

    Alternatively (to avoid having to replace "\"" with ""), I changed the controller method to this:

    [HttpPost]
    [Route("test")]
    public IActionResult Test()
    {
       var resp = new byte[] {1, 2, 3};
       return Content(Convert.ToBase64String(resp));
    }
    

    And the client call like this:

    using (MemoryStream ms = new MemoryStream())
    {
       dataStream.CopyTo(ms);
       byte[] data = ms.ToArray();
       byte[] originalData = 
           Convert.FromBase64String(Encoding.UTF8.GetString(data));
    }