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.

this screen shot android studio taken when debugging code, shows visit.image value retrieved database

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

Popular posts from this blog

java - Jasper subreport showing only one entry from the JSON data source when embedded in the Title band -

mapreduce - Resource manager does not transit to active state from standby -

serialization - Convert Any type in scala to Array[Byte] and back -