A note before beginning, I know that WWW and WWWForm work, but since Unity is trying to get people off of that system, I would like to know why their new system breaks in my case. I’m using Unity 5.6
Goal: To take a screenshot and send it to a server
Problem: UnityWebRequest sends the data in a large data chunk rather than the correct multipart data even when it has the correct content-type header and boundary.
The server code was tested using tools such as postman to check it was working (server code isn’t mine but expects multipart form-data with a ‘file’ field and an image as it’s data) and the Unity and Postman requests were compared to identify the issue
This will be a long post, please bear with me as I explain what all I tried and how it broke:
//get screenshot and start coroutine to make request
//using dataPath so it is in assets folder for now.
Application.CaptureScreenshot(Application.dataPath + "/screenshot.png");
StartCoroutine(sendImage());
and the coroutine: (note: this code resulted in a 500 error from the server)
IEnumerator sendImage()
{
/*validation to find file*/
//read in file to bytes
byte[] img = File.ReadAllBytes(Application.dataPath + "/screenshot.png");
//create multipart list
List<IMultipartFormSection> requestData = new List<IMultipartFormSection>();
requestData.Add( new MultipartFormFileSection("file", img,
"screenshot.png", "image/png"));
//url3 is a string url defined earlier
UnityWebRequest request = UnityWebRequest.Post(url3, requestData);
request.SetRequestHeader("Content-Type", "multipart/form-data");
yield return request.Send();
print("request completed with code: " + request.responseCode);
if(request.isError) {
print("Error: " + request.error);
}
else {
print("Request Response: " + request.downloadHandler.text);
}
}
So that was the format giving us problems. Here is a screenshot from wireshark of what that request looked like.
For comparison, here is a good request made using Postman:
as you can see, the valid request breaks up the multipart form into it’s sections, where as the UnityWebRequest.Post() was not. Does anyone know why this is? The best guess a few others and myself could come up with was the fact that the .Post() forces the data to be URLEncoded via WWWTranscoder.URLEncode prior to transmission per the docs.
Can someone verify that this is indeed the case? I only saw 1 post that mentioned that after hours of searching and trying to fix this.
I will post an answer below with all of the methods we attempted/found to try and fix this so they are all in one place (seriously I had way too many tabs open with different posts trying to find solutions). We ended up using a hybrid solution using UnityWebRequest.Post() but using WWWForm data instead of the iMultipartFormSection class, but I’d love to hear if there is a better way.