android - Web API 2 cannot read byte[] sent via Retrofit 2 -
i'm trying upload objects form client sq-lite database mssql using retrofit 2 & web api 2.
the app working without issue if assign null
or new byte[1000]
visit. image, whenever assigned value retrieved sq-lite database error response code 400
{ "message": "the request invalid.", "modelstate": { "visit.image[0]": [ "an error has occurred." ], "visit.image[1]": [ "an error has occurred." ] } }
here model in android:
public class visit { public int visitid; public string dealermid; public byte[] image; // read image database (blob data type) }
this code how retrieve values database , making visit object
public visit getvisitbyvisitid(long visitid) { sqlitedatabase db = this.getreadabledatabase(); string selectquery = "select * " + table_visit + " " + key_id + " = " + visitid; cursor c = db.rawquery(selectquery, null); if (c != null) c.movetofirst(); visit visit = new visit(); visit.visitid = c.getint(c.getcolumnindex(key_id)); visit.dealermid = c.getstring(c.getcolumnindex(key_dealer_mid)); visit.image= c.getblob(c.getcolumnindex(key_picture)); return visit ; }
and used interface retrofit service:
@post("visits/postvisit") public call<integer> postvisit(@body visit visit);
this activity code:
visit vistit = db.getvisitbyid(1) ; // note : every thing working fine // if visit.image = null or visit.image = new byte[1000] or visit.image = new byte[]{1,4,3 ..} // receiving error 400 when visit.image contains value database call<integer> call = retrofitservice.postvisit(visit); call.enqueue(new callback<integer>() { @override public void onresponse(call<integer> call, response<integer>response){ //.... } @override public void onfailure(call<integer> call, throwable t) { //.... } });
and web api 2 code
[httppost] public ihttpactionresult postvisit(visit visit) { if (!modelstate.isvalid) { return badrequest(modelstate); } db.visits.add(visit); try { db.savechanges(); } catch (dbupdateexception) { if (visitexists(visit.visitid)) { return ok(-1); } else { throw; } } return ok(visit.visitid); }
the below screenshot android studio shows retrieved content of visit.image, , sure there no problem content self because can read on android app in imageview.
well, posting bytes java c#. problem java bytes has range between -128 , 127 whilst c# bytes ranges from 0 255. when post bytes java got serialized json string (['-128', '-30', '127']) webapi controller receives them , tries deserialize them c# bytes (ranging 0 255). unfortunately, fails because of negative numbers. have make deserialize correctly.
option 1: use sbyte
in conroller.
in webapi, change model to:
public class visit { public int visitid; public string dealermid; public sbyte[] image; // c# }
webapi contoller deserialize array successfully sbyte
(range: -128 127) , can convert them byte (taken so answer):
byte[] imagebytes = (byte[]) (array)myvisitmodel.image;
option 2: send int[]
java
send bytes int[] send bytes ranging 0 255.
change model in java to:
public class visit { public int visitid; public string dealermid; public int[] image; }
convert byte[] int[]:
byte[] imagebytes = c.getblob(c.getcolumnindex(key_picture)); visit.image= converttointarray(imagebytes);
convert method (taken jon skeet's answer):
public static int[] converttointarray(byte[] input) { int[] ret = new int[input.length]; (int = 0; < input.length; i++) { ret[i] = input[i] & 0xff; // range 0 255, not -128 127 } return ret; }
note: i'd recommend 1st option, done on server-side while 2nd option might take long during converting int[]
on client-side.
Comments
Post a Comment