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?
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)
{
}
}