- Home /
UnityWebRequest ContentType not Overriding
I am constructing a file post to a REST api. The REST api is specifically looking for mulipart/form-data content. Seems like now matter how I try and override it, the content-type when it gets to the server is always "application/x-www-form-urlencoded". Does anyone know how to send content as "multipart/form-data"?
byte[] data = File.ReadAllBytes (@"<file location>");
List<IMultipartFormSection> postForm = new List<IMultipartFormSection> ();
postForm.Add (new MultipartFormDataSection ("SectionHeader", "data", "text/plain"));
postForm.Add (new MultipartFormDataSection ("SectionHeader", "data", "text/plain"));
postForm.Add (new MultipartFormDataSection ("SectionHeader", "data", "text/plain"));
postForm.Add (new MultipartFormDataSection ("SectionHeader", "data", "text/plain"));
postForm.Add (new MultipartFormDataSection ("SectionHeader", "data", "text/plain"));
postForm.Add (new MultipartFormDataSection ("SectionHeader", "data", "text/plain"));
postForm.Add(new MultipartFormFileSection("SectionHeader", data, "data", "application/octet-stream"));
string boundaryString = "---NextPart_" + Guid.NewGuid ().ToString () + "---";
byte[] boundary = Encoding.ASCII.GetBytes (boundaryString);
UnityWebRequest www = UnityWebRequest.Post(baseApiUrl + dataApiUrl, postForm, boundary);
www.uploadHandler.contentType = "multipart/form-data";
www.SetRequestHeader ("Authorization", completeToken.token_type + " " + completeToken.access_token);
yield return www.Send();
if(www.isError) {
Debug.LogError(www.error);
}
else if (www.responseCode != 200) {
<report responsecode and associated server/client error>
//This is where I am getting 415 Unsupported Media Type
}
else{
Debug.Log("Form upload complete!");
}
If it's possible to do so in your code, I have found a method to do this using HTTPWebrequest vice UnityWebRequest, see answer below.
I have reported it:
https://fogbugz.unity3d.com/default.asp?826626_htlchp13nh8th2to
The code below worked for me. $$anonymous$$y WebAPI service was able to get the object.
string requestData = JsonSerializer(userRequest); UploadHandler uploader = new UploadHandlerRaw(Encoding.UTF8.GetBytes(requestData)); uploader.contentType = "application/json"; UnityWebRequest unityWebRequest = new UnityWebRequest(apiUrl + "/test"); unityWebRequest.useHttpContinue = false; unityWebRequest.method = "POST"; unityWebRequest.SetRequestHeader("Accept", "application/json"); unityWebRequest.SetRequestHeader("Content-Type", "application/json"); unityWebRequest.uploadHandler = uploader; unityWebRequest.downloadHandler = new DownloadHandlerBuffer();
Answer by mlawrence · Sep 06, 2016 at 05:39 PM
The following code has worked for me to craft an HTTPWebRequest as a multipart/form-data request. Copying for ease of use (source at the bottom), I have also added some comments to make the code as clear as possible.
///<summary>Uploads form fields, and n files to REST endpoint</summary>
///<param name="url">URL to upload data to</param>
///<param name="files">Array containing string paths to files to upload</param>
///<param name="formFIelds">NameValueCollection containing all non-file fields from the form, default is null if no other fields provided</param>
public static string UploadFilesToRemoteUrl(string url, string[] files, NameValueCollection formFields = null)
{
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
request.ContentType = "multipart/form-data; boundary=" +
boundary;
request.Method = "POST";
request.KeepAlive = true;
//stream contains request as you build it
Stream memStream = new System.IO.MemoryStream();
var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "\r\n");
var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "--");
//this is a multipart/form-data template for all non-file fields in your form data
string formdataTemplate = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
if (formFields != null)
{
//utilizing the template, write each field to the request, convert this data to bytes, and store temporarily in memStream
foreach (string key in formFields.Keys)
{
string formitem = string.Format(formdataTemplate, key, formFields[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
memStream.Write(formitembytes, 0, formitembytes.Length);
}
}
//this is a multipart/form-data template for all fields containing files in your form data
string headerTemplate =
"Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n";
//Using the template write all files in your files[] input array to the request
//"uplTheFile" is the destination file's name
for (int i = 0; i < files.Length; i++)
{
memStream.Write(boundarybytes, 0, boundarybytes.Length);
var header = string.Format(headerTemplate, "uplTheFile", files[i]);
var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
//Convert files to byte arrays for upload
using (var fileStream = new FileStream(files[i], FileMode.Open, FileAccess.Read))
{
var buffer = new byte[1024];
var bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
}
}
memStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
request.ContentLength = memStream.Length;
//Write the data through to the request
using (Stream requestStream = request.GetRequestStream())
{
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
}
//Capture the response from the server
using (var response = request.GetResponse())
{
Stream stream2 = response.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
return reader2.ReadToEnd();
}
}
Source StackOverflow
Answer by toddheckel · Oct 03, 2016 at 06:00 AM
I ran into a similar problem. I think you need to change:
www.uploadHandler.contentType = "multipart/form-data";
to:
www.SetRequestHeader("Content-Type", "multipart/form-data");