- Home /
Blank web server response in multiple type data submission
When I attach image resources to web service api call, its giving me blank server side response as well nothing submitted to server as well.
I was using following code for this purpose:
IEnumerator RegisterVoterProfile ()
{
WWW localFile = new WWW ("file:///Users/gaminguruz/Desktop/messi.jpg");
yield return localFile;
if (localFile.error == null)
Debug.Log ("Loaded file successfully");
else {
Debug.Log ("Open file error: " + localFile.error);
yield break; // stop the coroutine here
}
Dictionary<string,string> headerDisc = new Dictionary<string, string> ();
// headerDisc.Add ("Content-Type", "multipart/form-data");
headerDisc.Add ("Api-Key", "Api-Key Paste Here");
WWWForm form = new WWWForm ();
form.AddField (GameConstants.REGISTRATION_USERNAME_ARG, userNameInput.text);
form.AddField (GameConstants.REGISTRATION_PASSWORD_ARG, passwordInput.text);
form.AddField (GameConstants.REGISTRATION_EMAIL_ARG, emailInput.text);
form.AddBinaryData (GameConstants.REGISTRATION_PROFILE_PIC_ARG, localFile.bytes);
form.AddField (GameConstants.REGISTRATION_USERTYPE_ARG, GameConstants.VOTER_USER_TYPE);
byte[] rawData = form.data;
WWW www = new WWW (GameConstants.REGISTRATION_BASE_URL, rawData, headerDisc);
yield return www;
if (www.error == null)
Debug.Log ("Data: " + www.text);
else
Debug.Log ("Error: " + www.error);
}
Attaching output image too:
If I remove following line from source code then data get submitted over and get proper response as well. Even if I just upload image only then also task completed successfully.
form.AddBinaryData (GameConstants.REGISTRATION_PROFILE_PIC_ARG, localFile.bytes);
Even in PostMan and DHC all things working perfectly.
Now at which place, I was doing mistake that I can't able to find so please help me in this.
Answer by Bunny83 · Jun 29, 2016 at 12:44 PM
The way you setup your headers is a bit wrong. The WWWForm class will setup the basic header information which you ignore since you pass your own header dictionary. The general procedure when applying cusom headers is this:
WWWForm form = new WWWForm();
// add your form data here
form.AddField(...);
// [...]
var headers = form.headers;
// add your custom headers here
headers.Add(..., ...);
// Send your request
WWW www = new WWW ( ... , form.data, headers);
yield return www;
The default headers contain the proper "content type" which is determined from the actual form data. A multipart content type needs a boundary marker which is created by the WWWForm class and is used to seperate the different parts. The boundary marker is a random 40 character string that is generated in the WWWForm internally. When reading the "data" property the WWWForm uses this internally generated boundary marker to seperate the parrs. The content type header need the same boundary marker or the request won't work.
The "headers" property of the WWWForm class looks like this:
public Dictionary<string, string> headers
{
get
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
if (this.containsFiles)
{
dictionary["Content-Type"] = "multipart/form-data; boundary=\"" + Encoding.UTF8.GetString(this.boundary, 0, this.boundary.Length) + "\"";
}
else
{
dictionary["Content-Type"] = "application/x-www-form-urlencoded";
}
return dictionary;
}
}
@Bunny83, Really thanks for your reply :) Now I have one question in this too, I have now changed my code to some thing like this,
WWWForm form = new WWWForm ();
form.AddField (GameConstants.REGISTRATION_USERNA$$anonymous$$E_ARG, userNameInput.text);
form.AddField (GameConstants.REGISTRATION_PASSWORD_ARG, passwordInput.text);
form.AddField (GameConstants.REGISTRATION_E$$anonymous$$AIL_ARG, emailInput.text);
form.AddBinaryData (GameConstants.REGISTRATION_PROFILE_PIC_ARG, localFile.bytes, "virat.jpg", "image/jpeg");
form.AddField (GameConstants.REGISTRATION_USERTYPE_ARG, GameConstants.VOTER_USER_TYPE);
Dictionary<string,string> headerDisc = form.headers;
headerDisc ["Content-Type"] = "multipart/form-data; boundary=\"" + Encoding.UTF8.GetString (this.boundary, 0, this.boundary.Length) + "\"";
WWW www = new WWW ("http://photo-competition.basketballtriviaguru.com/restapi/register_demo", form.data, headerDisc);
// WWW www = new WWW (GameConstants.REGISTRATION_BASE_URL, rawData, headerDisc);
yield return www;
So what come at place of this.boundary because my project not contains anything like this.
I think you misunderstood my answer ^^. You should not set the Content-Type yourself. That's the whole point in using the WWWForm class. It handles that for you. Just remove the line where you set the Content-Type.
The "boundary" field is a private field inside the WWWForm class. It's a byte array which is automatically initialized with random characters when you create the WWWForm. Putting together the post data for a multipart content isn't that difficult, just a bit tedious. Here's the code that actually builds the post data (just for reference). There the internal boundary field is used to put the different parts together.
Though when you use the WWWForm class you shouldn't care about the actual implementation.
@Binny83 thanks for this awesome reply. I got your point for this. Now my updated code.
WWWForm form = new WWWForm ();
form.AddField (GameConstants.REGISTRATION_USERNA$$anonymous$$E_ARG, userNameInput.text);
form.AddField (GameConstants.REGISTRATION_PASSWORD_ARG, passwordInput.text);
Dictionary<string,string> headerDisc = form.headers;
headerDisc.Add ("Api-$$anonymous$$ey", "Your API $$anonymous$$ey");
WWW www = new WWW (GameConstants.UPDATE_REGISTRATION_BASE_URL, form.data, headerDisc);
yield return www;
Your answer
Follow this Question
Related Questions
Upload large files 0 Answers
GET Request Wrapper 1 Answer
uploading png with wwwform 0 Answers
How do I send data over the internet? 0 Answers