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).
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()
};
}