1

I'm a beginner in Unity3D; i have to develop a mobile app and i need to manage user profile data; i have to communicate these data with server using REST services. Everything works fine when i send Json (eg name, email, phone number, etc.) from my app, but I can't update the profile picture.

What i need is: Content-Type = multipart/form-data key="profile_picture", value=file_to_upload (not the path)

I read a lot about networking in Unity and tried different combinations of UnityWebRequest, List, WWWform but nothing seems to work for this kind of PUT service.

UnityWebRequest www = new UnityWebRequest(URL + user.email, "PUT");
    www.SetRequestHeader("Content-Type", "multipart/form-data");
    www.SetRequestHeader("AUTHORIZATION", authorization);
    //i think here i'm missing the correct way to set up the content

I can correctly simulate the update from Postman, so it's not a problem with server; i'm pretty sure that the problem is that i can't convert this logic inside the app.

Upload from Postman correctly working(1)

enter image description here

Upload from Postman correctly working(2)

enter image description here

Any kind of help and code suggestion will be appreciated. Thanks

Alain Merigot
  • 10,667
  • 3
  • 18
  • 31
  • There is a helper class upload handler https://docs.unity3d.com/ScriptReference/Networking.UploadHandler.html. Perhaps that helps? – Kieran Feb 01 '19 at 11:24
  • Yes, that should be the way, but i'm missing the correct way to set up the upload handler, because i need something like a form with a KEY=VALUE structure – Adriano Alemanno Feb 01 '19 at 12:02

1 Answers1

1

With Put you usually only send file data but without a form.

You can add a multipart form using UnityWebRequest.Post

IEnumerator Upload() 
{
    List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
    formData.Add(new MultipartFormFileSection("profile_picture", byte[], "example.png", "image/png"));

    UnityWebRequest www = UnityWebRequest.Post(url, formData);

    // change the method name
    www.method = "PUT"; 

    yield return www.SendWebRequest();

    if(www.error) 
    {
        Debug.Log(www.error);
    }
    else 
    {
        Debug.Log("Form upload complete!");
    }
}

using a MultipartFormFileSection


Or alternatively you can use a WWWForm

IEnumerator Upload()
{
    WWWForm form = new WWWForm();
    form.AddBinaryData("profile_picture", bytes, "filename.png", "image/png");

    // Upload via post request
    var www = UnityWebRequest.Post(screenShotURL, form);

    // change the method name
    www.method = "PUT";        

    yield return www.SendWebRequest();

    if (www.error) 
    {
        Debug.Log(www.error);
    }
    else 
    {
        Debug.Log("Finished Uploading Screenshot");
    }
}

using WWWForm.AddBinaryData


Note that for user authentication you have to encode your credentials properly:

string authenticate(string username, string password)
{
    string auth = username + ":" + password;
    auth = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(auth));
    auth = "Basic " + auth;
    return auth;
}

www.SetRequestHeader("AUTHORIZATION", authenticate("user", "password"));

(Source)

derHugo
  • 83,094
  • 9
  • 75
  • 115
  • That's just better than what i tried, but it bring me to the same error: if i use POST request i have Error 405, because POST request is not implemented on server. On the other side, if i try tu upload only the file i have Error 500. Using postman, i can correctly use PUT service – Adriano Alemanno Feb 04 '19 at 09:57
  • Afaik there is no standard way for sending multiform data with PUT. You might however try to simply change the method by using somehing like `www.method = "PUT";` – derHugo Feb 04 '19 at 10:14
  • I just included user authentication, i have problems only in this case – Adriano Alemanno Feb 04 '19 at 10:15
  • This is a great workaround. Please keep in mind that MultipartFormFileSection may require all the "four paramaters" as specified by derHugo – Mert Sevinc Aug 10 '21 at 06:04