5

I am working on a public API where user will send byte[] in parameter. I have implemented the API method and want to do the testing for it but If I am trying in postman then not able to send the byte[]. Getting bellow error

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|e1896d86-412b7762126469ae.",
"errors": {
    "$": [
        "The JSON value could not be converted to System.Byte[]. Path: $ | LineNumber: 0 | BytePositionInLine: 1."
    ]
}

}

API method paramters

public IActionResult Upload(int clientId, string dtName, byte[] dtValues, bool append)
    {
 
}

Postman call

enter image description here

Arun Singh
  • 525
  • 2
  • 8
  • 20

2 Answers2

6

Firstly, asp.net core does not support post multiple parameters from body, you need put these parameters into a model then you could post them from body.

Then, what you did should be post from query. But it seems does not support byte[] from query.

  1. If you use JSON.NET, you could post clientId,dtName and append from query and post dtValues from body like below(Be sure your controller is declared with [ApiController]):

enter image description here

  1. If you use System.Text.Json,with Sytem.Text.Json a byte array (byte[]) will be serialized as base64 string. They stated that they won't add support for byte[] to be serialized as number array in a github issue.

Custom JsonConverter:

public class ByteArrayConverter : JsonConverter<byte[]>
{
    public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        short[] sByteArray = JsonSerializer.Deserialize<short[]>(ref reader);
        byte[] value = new byte[sByteArray.Length];
        for (int i = 0; i < sByteArray.Length; i++)
        {
            value[i] = (byte)sByteArray[i];
        }

        return value;
    }

    public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options)
    {
        writer.WriteStartArray();

        foreach (var val in value)
        {
            writer.WriteNumberValue(val);
        }

        writer.WriteEndArray();
    }
}

Register it:

services.AddControllers().AddJsonOptions(options =>
{
     options.JsonSerializerOptions.Converters.Add(new ByteArrayConverter());
}); 

Test in Postman:

enter image description here

BTW, not sure what is your scenario, if you post the byte array is something like file(e.g: image or .doc or .xlx file), you could use IFormFile and add [FromForm] before the parameter. Both JSON.NET or System.Text.Json supports receive IFormFile, no need custom JsonConverter here:

[Route("Upload")]
public IActionResult Upload(int clientId, string dtName, [FromForm]IFormFile dtValues, bool append)
{
        return Ok();
}

Post the data like below: enter image description here

If you do not want to separately post them from query and body, you could put them into a model and post them from body.

Model:

public class TestModel
{
    public int clientId { get; set; }
    public string dtName { get; set; }
    public byte[] dtValues { get; set; }
    public bool append { get; set; }
}

Post in Postman:

Note: if you use System.Text.Json, you still need to custom JsonConverter like above option 2 I shared.

enter image description here

Rena
  • 30,832
  • 6
  • 37
  • 72
  • Great research! my customer want to send the data in file format or byte[] format. So we have to give both options. I am able to work with file but not from byte[]. I will try your answer/ thanks – Arun Singh Jun 21 '21 at 07:58
1

You have to pass array and not string.

dtValues : [37,80]
dotnetstep
  • 17,065
  • 5
  • 54
  • 72