Coding Away Coding Away - 3 months ago 10
AngularJS Question

Web Api Data in JSON is wrapped in an object , why is this and how can I tell the Web Api owner what to do to fix this

I am trying to consume some Web Api data in which it is handled by a different team and they do not seem to think there is anything wrong with the data.

While I realize that it is valide JSON, I would like to tell them what I prefer them send in order to not have more work to do on my client end.

Postman and Angular ( anything ) ends up getting the data wrapped in this "Devices"

{
"Devices": [
{
"DeviceId": "00022B9A000000010001",
"StagedManifestIdList": [],
"PendingManifestId": null,
"PendingTimeStamp": "0001-01-01T00:00:00",
"ManifestIdList": [
"00000002",
"00000001",
"00000003"
],
"DeviceStatus": 3,
"Aid": "oAAABTUAAg==",
"DKiIndex": "DKi00000002",
"Sha": "R2tiZRQgY/iohXZt5O4HaQwtVe/adWU2VOcKaelJ3Us=",
"DefaultPayload": "C:\\ProgramData\\ABC\\124\\Payloads\\M4PayloadAuto.xml"
}
]
}


So above the Devices is just painful for me to work with.

They DID send me the code of their Web Api Method, what can they change so I do not get this "Device" wrapper name?

public class DeviceController : ApiController
{
private static readonly ILog Log = LogManager.GetLogger(typeof (DeviceController).Name);

[ResponseType(typeof (RetrieveDeviceResponse))]
public IHttpActionResult Get(string id = null)
{
IHttpActionResult httpActionResult;
var returnVal = new RetrieveDeviceResponse();

try
{
byte[] deviceIdBytes = null;

if (!string.IsNullOrWhiteSpace(id))
{
deviceIdBytes = ByteArray.ConvertHexStringToByteArray(id);
}

var deviceInfoArray = DeviceManager.RetrieveDevice(deviceIdBytes);

if (deviceInfoArray == null)
{
returnVal.Success = false;
returnVal.ErrorMessage = "Get: RetrieveDevice returned null";
}
else
{
returnVal.Devices = new List<DeviceInfo>();

foreach (var deviceInfoObj in deviceInfoArray)
{
DeviceInfo deviceInfo = new DeviceInfo
{
Aid = deviceInfoObj.AID,
DKiIndex = deviceInfoObj.DKiIndex,
DefaultPayload = deviceInfoObj.DefaultPayload,
DeviceId = ByteArray.ConvertToHexString(deviceInfoObj.DevID),
StagedManifestIdList = deviceInfoObj.StagedManifestIDList,
PendingManifestId = deviceInfoObj.PendingManifestID,
PendingTimeStamp = deviceInfoObj.PendingTimeStamp,
ManifestIdList = deviceInfoObj.ManifestIDList,
DeviceStatus = (DeviceStatus) deviceInfoObj.DeviceStatus,
Sha = deviceInfoObj.SHA
};

returnVal.Devices.Add(deviceInfo);
}

returnVal.Success = true;
}
}
catch (Exception ex)
{
returnVal.ErrorMessage = "Get: Exception. " + DebugMode.ShowMessage(ex.Message);
returnVal.Success = false;
Log.Error(returnVal.LastErrorMessage);
}


if (returnVal.Success)
{
httpActionResult = Ok(returnVal);
Log.Debug("Get: Success");
}
else
{
httpActionResult = Content(HttpStatusCode.BadRequest, returnVal);
Log.Error("Get Failed: " + returnVal.ErrorMessage);
}

return httpActionResult;
}

}

Answer

Can you please say exactly why is it painful? As I can see, they are returning not only info about devices, but also exceptions and success statuses. For example, if there will be an error, you will receive something like that:

{
  "Devices": [], 
  "ErrorMessage" : "Some Error Message",
  "Success" : false
}

It is possible that ignoring this will lead to some problems.

However, if you insist that you need only a list of Devices and nothing else, tell them to return not returnVal wrapped in HttpActionResult, but returnVal.Devices. For example, change this

  if (returnVal.Success)
  {
       httpActionResult = Ok(returnVal);
       Log.Debug("Get: Success");
  }

To this:

  if (returnVal.Success)
  {
       httpActionResult = Ok(returnVal.Devices);
       Log.Debug("Get: Success");
  }

However, I insist you to use what they provide. It is very simple and not painful to get Devices on client-side from their provided object.