3

As the title says, the code is as below. I have tried setting chunkedTransfer=false, Content-Type application/json, WWWForm, building the JSON object manually, and HttpClient. For Content-Type application/json, the API isn't even hit. For the rest, the body is an empty object. I have no idea what the issue is here looking through StackOverflow, YouTube, Unity documentation, and all the other resources.

As of this morning I am using Newtonsoft.Json to serialize the JSON body. I think the biggest issue right now is that when I set webRequest.SetRequestHeader("Content-Type", "application/json"); the API route doesn't even receive the request.

async Task<string> makeRequest()
        {
            string url = API_BASE + "/users"; 
            
            Dictionary<string, string> body = new Dictionary<string, string>();
            body.Add("username", username);
            body.Add("password", password);
            body.Add("email", email);

            using (UnityWebRequest webRequest = UnityWebRequest.Post(url, JsonConvert.SerializeObject(body)))
            {
                await webRequest.SendWebRequest();

                string result = Encoding.UTF8.GetString(webRequest.downloadHandler.data);

                if (webRequest.result != UnityWebRequest.Result.Success)
                {
                    JSONNode error = JSON.Parse(result);

                    registerAndLoginError.GetComponent<Text>().text = error["error"]["message"];
                    registerAndLoginError.SetActive(true);

                    return "";
                }
            }

            BasicLogin();
            return "";
        }
Rory L.
  • 308
  • 2
  • 13

3 Answers3

10

So I had seen this solution elsewhere, but I continued ignoring it because it's hacky af and seems like something that should be addressed. However, I'm at the point of not caring right now.

  1. Use UnityWebRequest.Put instead of UnityWebRequest.Post
  2. Set webRequest.method = "POST";
  3. Set webRequest.SetRequestHeader("Content-Type", "application/json");

This works, but it feels really bad and doesn't make any sense.

Rory L.
  • 308
  • 2
  • 13
0

The builtin JsonUtility does NOT support Dictionary! It follows the same serialization rules as the Inspector, see Script Serialization.

=> The JsonUtility.ToJson(body) will just return "" or in best case "{}".

Try to rather create the JSON string "manually" like e.g.

var json = "{\"username\":\""+username+"\", \"password\":\""+password+"\", \"email\":\""+email+"\"}";

or use a different library like e.g. Newtonsoft .NET Json (available as Package via the PackageManager) which supports direct (de)serialization of collections and Dictionary.

derHugo
  • 83,094
  • 9
  • 75
  • 115
  • Thanks for the response! I did actually try that too, I forgot to include it. Same issue. Edit: Updated to include the JSON object manual creation attempt. – Rory L. Jun 28 '21 at 11:58
0

I used all of the methods above and im still being told my body is blank {}

Whats somewhat hilarious is i used

private IEnumerator SendScores(int score)
{

    WWWForm form = new WWWForm();
    form.AddField("score", score);
    form.AddField("module_id", _moduleID);
    form.AddField("user_id", _userCode);

    Debug.Log(form);
    UnityWebRequest www = UnityWebRequest.Post("http://pbs-web-git-sc-14-order-and-payment-system-pbs-labs.vercel.app/api/scores", form);

    yield return www.SendWebRequest();
    if (www.result != UnityWebRequest.Result.Success)
    {
        Debug.Log(www.error);
        Debug.Log("Response: " + www.downloadHandler.text);
    }
    else
    {
        Debug.Log("Form upload complete!");
    }

    QuizManager.Instance.ResetQuizScore();
}

and sending it as a form actually got accepted by the API.

When i went to do it later though once again im getting told the API is receiving a empty body.

when i send it to a mock API though the JSON version and the FORM version are both posting a correctly formatted body as sent.