resthttpsap-cloud-foundry

Unity occurs a 400 Bad Request when calling a HTTP-Post on an SAP Rest API


I want to call a REST API with an Unity-Script but it occurs me the Error

400 Bad Request

It is maybe because of the http-header. Maybe you can help me. SAP offers a Code Snippet in Java which I want to show you first:

DataOutputStream dataOut = null;
BufferedReader in =null;

try {

//API endpoint for API sandbox 
  String url = "https://sandbox.api.sap.com/mlfs/api/v2/image/scene-text- 
recognition";


  //Available API Endpoints
  //https://mlfproduction-scene-text- 
  recognition.cfapps.eu10.hana.ondemand.com/api/v2/image
  //https://mlfproduction-scene-text- 
  recognition.cfapps.us10.hana.ondemand.com/api/v2/image

  URL urlObj = new URL(url);
  HttpURLConnection connection = (HttpURLConnection)         
urlObj.openConnection();
  //setting request method
  connection.setRequestMethod("POST");

  //adding headers
  connection.setRequestProperty("content-type","multipart/form-data;                 
  boundary=---011000010111000001101001");
  //API Key for API Sandbox

  connection.setRequestProperty("APIKey","----api-Key---");


  //Available Security Schemes for productive API Endpoints
  //OAuth 2.0

  connection.setDoInput(true);

  //sending POST request
    connection.setDoOutput(true);
  dataOut = new DataOutputStream(connection.getOutputStream());
  dataOut.writeBytes("-----011000010111000001101001\r\nContent-            
Disposition: form-data; name=\"files\"; filename=\"<file_name>\"\r\nContent-Type: <file_type>\r\n\r\n<file_contents>\r\n-----011000010111000001101001--");
  dataOut.flush();

  int responseCode = connection.getResponseCode();
  in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
  String inputLine;
  StringBuffer response = new StringBuffer();
  while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
  }

  //printing response
  System.out.println(response.toString());

} catch (Exception e) {
  //do something with exception
  e.printStackTrace();
} finally {
  try {
    if(dataOut != null) {
      dataOut.close();
    }
    if(in != null) {
      in.close();
    }

  } catch (IOException e) {
    //do something with exception
    e.printStackTrace();
  }
}

My UnityCode looks something like this:

public void ExecutePost()
 {
     Debug.Log("execute started");
     byte[] img =     
     File.ReadAllBytes(@"C:\Users\InnovationLab\Documents\ECENTA\ECENTA 
 FSE\Bild1.jpg");
     string url = "https://sandbox.api.sap.com/mlfs/api/v2/image/scene- 
text-recognition";
     coroutine = Post(url, img);
     StartCoroutine(coroutine);
 }



public IEnumerator Post(string url,byte[] image)
{
    WWWForm form = new WWWForm();
    form.AddBinaryData("imageField", image, "HoloImg");

    var headers = new Dictionary<string, string> {
        {"content-type", "multipart/form-data; boundary=---011000010111000001101001" },
        {"APIKey", "---here I implemented the key---" }
    };
    WWW www = new WWW(url, image, headers);
    yield return www;
    if (www.error != null && www.error != "")
    {       // on error, show information and return
        Debug.Log("Network Error occured: " + www.error);
        yield break;
    }
    while (!www.isDone)
    {
        Debug.Log(www.text);
    }
    
  }
}

So my question is, how to change the unity code so that it works?


Solution

  • I fixed it by using MultipartFormSections. The problem was that the api expected form-data not a binary Array.

     public IEnumerator Upload(string url, byte[] img)
    {
        List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
        MultipartFormFileSection myFormFile = new MultipartFormFileSection("files", img, 
    "Bild1.jpg", "multipart/form-data");
        formData.Add(myFormFile);
        Debug.Log(formData.ToString());
        UnityWebRequest www = UnityWebRequest.Post(url, formData);
        www.SetRequestHeader("APIKey", "<api-key>");
        yield return www.SendWebRequest();
    
        if (www.isNetworkError || www.isHttpError)
        {
            throw new Exception(www.downloadHandler.text ?? www.error);
        }
        else
        {
            Debug.Log("Done!!!!!");
        }
    
        Debug.Log(www.downloadHandler.text);
    
        var ResultObject = JsonUtility.FromJson<TextPrediction>(www.downloadHandler.text);
    
        foreach (var result in ResultObject.texts)
        {
    
        }
    }