Issue with Concatenating Variable in UnityWebRequest.Post()

Essentially I’m trying to put a variable (preview3DID) into the data parameter of the post method and it’s not working. When I manually put in the ID it works fine but when I try to add the ID with concatenation it doesn’t work. Is there another method of concatenation that I should be using or does this just not work entirely. Code is below.

    IEnumerator Create3DRefineRequest()
    {
        yield return new WaitForSeconds(30);
        using (UnityWebRequest refineRequest = UnityWebRequest.Post("https://api.meshy.ai/openapi/v2/text-to-3d", "{\"mode\": \"refine\", \"preview_task_id\": \"" + preview3DID + "\",  \"enable_pbr\": true}", "application/json"))
        {
            refineRequest.SetRequestHeader("Authorization", "Bearer ");

            yield return refineRequest.SendWebRequest();

            if (refineRequest.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError(refineRequest.downloadHandler.text);
                Debug.LogError(refineRequest.error);
            }
            else
            {
                Debug.Log("Refining complete!");
                preview3DID = refineRequest.downloadHandler.text;
                Debug.Log(preview3DID);

            }
        }

    }
}

and below is curl formatting for the API provided by the website

curl https://api.meshy.ai/openapi/v2/text-to-3d \
  -H 'Authorization: Bearer ${YOUR_API_KEY}' \
  -H 'Content-Type: application/json' \
  -d '{
  "mode": "refine",
  "preview_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578"
  "enable_pbr": true,
}'

Send the same request to https://httpbin.org/post and print out the output. It sends back json containing the stuff it itself received from you. Most likely there is something weird, such as some non-printable characters involved.

2 Likes

Well what I’m not understanding is that when I replace preview3DID with the string that it represents

  using (UnityWebRequest refineRequest = UnityWebRequest.Post("https://api.meshy.ai/openapi/v2/text-to-3d", "{\"mode\": \"refine\", \"preview_task_id\": \"0194b2ba-2eb0-71ad-b564-06d10f8f7237 \",  \"enable_pbr\": true}", "application/json"))

it works. But if I set preview3DID to that exact same value it gives 400: Bad Request

string preview3DID = 0194b2ba-2eb0-71ad-b564-06d10f8f7237
  using (UnityWebRequest refineRequest = UnityWebRequest.Post("https://api.meshy.ai/openapi/v2/text-to-3d", "{\"mode\": \"refine\", \"preview_task_id\": \"" + preview3DID + "\",  \"enable_pbr\": true}", "application/json"))

            refineRequest.SetRequestHeader("Authorization", "Bearer API KEY");

Here’s the full code if that can elucidate things

using System.Collections;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;

public class MEshyAPI : MonoBehaviour
{
    public int thingy = 2;
    string fart;
    void Start()
    {
        StartCoroutine(Upload());
    }
    void Update()
    {
        if (thingy == 3)
        {
            thingy = 4;
            StartCoroutine(Create3DRefineRequest());
        }
    }
    public string preview3DID;
//Creating preview ID    
IEnumerator Upload()
    {
        
        using (UnityWebRequest previewRequest = UnityWebRequest.Post("https://api.meshy.ai/openapi/v2/text-to-3d", "{\"mode\": \"preview\",  \"prompt\": \"a monster mask\",  \"art_style\": \"realistic\",  \"should_remesh\": true}", "application/json"))
        {
            previewRequest.SetRequestHeader("Authorization", "Bearer API Key");

            yield return previewRequest.SendWebRequest();

            if (previewRequest.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError(previewRequest.error);
            }
            else
            {
                Debug.Log("Preview complete!");
                preview3DID = previewRequest.downloadHandler.text;
                preview3DID = preview3DID.Remove(0, 11);
                preview3DID = preview3DID.Remove(36, 2);
                Debug.Log(preview3DID);
                thingy = 3;
                fart = "{\"mode\": \"refine\", \"preview_task_id\": \"0194b127-b64c -7156-8679-36c5cb90c0b0\",  \"enable_pbr\": true}";
                Debug.Log(fart);
            }
            
        }

    }
//Refining Task using preview ID    
IEnumerator Create3DRefineRequest()
    {
        yield return new WaitForSeconds(30);
        using (UnityWebRequest refineRequest = UnityWebRequest.Post("https://api.meshy.ai/openapi/v2/text-to-3d", "{\"mode\": \"refine\", \"preview_task_id\": \"" + preview3DID +"\",  \"enable_pbr\": true}", "application/json"))
        {
            refineRequest.SetRequestHeader("Authorization", "Bearer API KEY");

            yield return refineRequest.SendWebRequest();

            if (refineRequest.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError(refineRequest.downloadHandler.text);
                Debug.LogError(refineRequest.error);
            }
            else
            {
                Debug.Log("Refining complete!");
                preview3DID = refineRequest.downloadHandler.text;
                Debug.Log(preview3DID);

            }

Uhm, the snippet you posted doesn’t really have the string in quotation marks. So where / when is that string variable actually filled? The snippet you posted would not work

You would need to do

string preview3DID = "0194b2ba-2eb0-71ad-b564-06d10f8f7237";

What on earth are you doing here:

What output do you actually get from the first API? I would assume that you get json back, right? So you should properly parse the json.

I actually wrote my SimpleJSON specifically for requesting webservices. With it you could simply do

var data = JSON.Parse(previewRequest.downloadHandler.text);
preview3DID = data["result"].Value;

You can also use it to create your request json

JSONNode data = new JSONObject();
data["mode"] = "preview";
data["prompt"] = "a monster mask";
data["art_style"] ="realistic";
data["should_remesh"] = true;

string json = data.ToString();

And for your other request:

JSONNode data = new JSONObject();
data["mode"] = "refine";
data["preview_task_id"] = preview3DID;
data["enable_pbr"] = true;

string json = data.ToString();

You can use any json library, but most require to either create a class for each request / response or are quite large. Mine is a single script file and the aim was ease of use :slight_smile:

1 Like

I believe this is the problem. Here you have a conversion to UTF-8 string and that string includes Unicode BOM. When output it to console, you don’t see it, as it’s non-printable.
This may help:

Or if the token is guaranteed to be like that, convert bytes to string using ASCII encoding.

1 Like

So I did what you said and the json worked for the first request but for the second it’s still saying that the preview task isn’t there. Here’s the code:

    IEnumerator Create3DRefineRequest()
    {
        JSONNode data = new JSONObject();

        data["mode"] = "refine";
        data["preview_task_id"] = preview3DID;
        data["enable_pbr"] = true;

        string json = data.ToString();
        Debug.Log(json);
        yield return new WaitForSeconds(30);
        using (UnityWebRequest refineRequest = UnityWebRequest.Post("https://api.meshy.ai/openapi/v2/text-to-3d", json, "application/json"))
        {
            refineRequest.SetRequestHeader("Authorization", "Bearer APIKEY");

            yield return refineRequest.SendWebRequest();

            if (refineRequest.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError(refineRequest.downloadHandler.text);
                Debug.LogError(refineRequest.error);
            }
            else
            {
                var jsonID = SimpleJSON.JSON.Parse(refineRequest.downloadHandler.text);
                preview3DID = jsonID["result"].Value;
                Debug.Log(preview3DID);
                Debug.Log("Preview complete!");

            }
        }

    }
}

and when I logged the json var to the console it gave me this:

{"mode":"refine","preview_task_id":"0194b311-4a61-71c4-88c4-b6e0c76f9996","enable_pbr":true}

which should work when I put it in the request but it still doesn’t so I’m very confused