1

I have a Controller class (in C#) which has to return a byte array from its login method. Please find the below source code of my Controller class for my Login functionality.

[RoutePrefix("Account")]
    public class AccountsController : ApiController     
    {
        [Route("Login")]
        [HttpPost]   
        public byte[] Login()
        {
            byte[] mSessionID = new Session().getmSessionID();
            return mSessionID;
        }
    }

While Testing, the web service returns a base64Encoded string value as "LVpgqWBYkyXX1FlDg95vlA==". I want my Web service to return a byte array response (which is in JSON response).

2
  • It looks like you are using ASP.NET 5 WebApi or lower. Correct? By default, WebAPI returns byte[] as Base64-encoded. You can change how the response is returned, but how do you want to see the information? Should it be an array of hex values in a JSON object? Or should it be an octet-stream response? Please provide an example of what you want your API to return. Commented Aug 15, 2016 at 4:10
  • I am not aware of both formats. But the format I would want to should look as given below: {Numbers : 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 11, 12, 13, 14, 15,2,45 }; . I want the web service to return a byte array itself Commented Aug 15, 2016 at 4:13

2 Answers 2

2

If you want to get the response in this format:

{
  "Numbers": [
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10,
    1,
    11,
    12,
    13,
    14,
    15,
    2,
    45
  ]
}

Solution 1: JSON Formatters

You need to modify the way that JSON is serialized. WebAPI uses JSON.Net unser the hood to format WebAPI responses as JSON. We can override the byte[] formatter as follows:

Create a custom formatter

public class ByteArrayFormatter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(byte[]);
    }
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var byteArray = (byte[])value;
        writer.WriteStartArray();
        if (byteArray != null && byteArray.Length > 0)
        {
            foreach (var b in byteArray)
            {
                writer.WriteValue(b);
            }
        }
        writer.WriteEndArray();
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Register the formatter globally in the Application_Start method in Global.asax.cs (note that ALL byte[] types will be serialised this way):

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
jsonFormatter.SerializerSettings.Converters.Add(new ByteArrayFormatter());

Create a model so that your JSON response has a Numbers property:

public class NumbersModelByte
{
    public byte[] Numbers { get; set; }
}

Modify your controller to use this model:

[Route("login")]
[System.Web.Http.AcceptVerbs("GET")]
[System.Web.Http.HttpGet]
public NumbersModelByte Login()
{
    byte[] mSessionID = new Session().getmSessionID();
    return new NumbersModelByte
    {
        Numbers = mSessionID
    };
}

Solution 2: The quick and dirty

You will need to return an object (a model).

NumbersModelInt.cs (notice the int[] type)

public class NumbersModelInt
{
    public int[] Numbers { get; set; }
}

Then you need to cast all of your bytes in your byte array to ints in the response:

[Route("Login")]
[HttpPost]   
public byte[] Login()
{
    byte[] mSessionID = new Session().getmSessionID();
    return new NumbersModelInt
    {
        Numbers = mSessionID.Select(b => (int) b).ToArray()
    };
}
Sign up to request clarification or add additional context in comments.

3 Comments

No problem. Let me know how it goes
Thanks Joao.. I tried the first option and it works perfectly fine.. Thank you so much.. I was struggling with this for a while and got a clearer idea on how to implement things in C# (I am new to it).. Cheers...
No worries. Glad to have been able to help
0

Answering my second question. (Passing a JSON Object into method of Controller)

I got help from my colleague, and she was able to find a proper link.

https://weblog.west-wind.com/posts/2013/dec/13/accepting-raw-request-body-content-with-aspnet-web-api....

The code changes I made to fix the issue are

 public async Task<UserSession> Login()
        {
            string input = await Request.Content.ReadAsStringAsync();            dynamic data = Newtonsoft.Json.Linq.JObject.Parse(input); 
        }

(input -returns as a string in in JSON format) (data - returns the JSON Object)

1 Comment

Can I return a sbyte[] from ByteArrayFormatter.cs in CanConvert method

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.