Отправьте строку json в webAPI из единицы C #;HttpClient или UnityWebRequest? - PullRequest
0 голосов
/ 03 апреля 2019

Я пытаюсь отправить строку JSON в веб-API и в настоящее время получил этот код:

async Task<Uri> Post(CapturedImage image)
{
    string json = JsonConvert.SerializeObject(image);
    var content = new StringContent(json.ToString(), Encoding.UTF8, "application/json");
    HttpResponseMessage response = await client.PostAsync(url, content);
    response.EnsureSuccessStatusCode();
    Debug.Log("Request Message Information:- \n\n" + response.RequestMessage + "\n");

    Debug.Log(json.ToString());

    // return URI of the created resource.
    return response.Headers.Location;
}

Код еще не готов, поэтому я не уверен, что этот тип я хочу вернуть в конце (в конце у меня будет новая строка json с информацией о конкретном автомобиле, предположительно).

Unity зависает, когда дело доходит до линии HttpResponseMessage response = await client.PostAsync(url, content);, и мне приходится принудительно закрывать приложение Unity.

Как я могу успешно использовать httpClient? В данный момент я не использую unityWebRequest, потому что я не понимаю, каким образом отправляется WWWForm (как объект, который я Угадай). И я не хочу, чтобы byte [] также отправлялся, но была строкой json, и я могу предположить, что WWWForm похож на строку json, но разделен-иш. Кроме того, я не получаю, какой тип должен быть получен в веб-API, когда это WWWForm. Например, если это строка json, у меня просто есть параметр вроде (string json).

Неужели я думаю, что не правильно использовать unityWebRequest вместо httpClient? Я должен использовать JSON, если это возможно.

1 Ответ

1 голос
/ 03 апреля 2019

UnityWebRequest.Post(string URL, string data) также принимает string в качестве ввода данных не только WWWForm.

Обычно вы используете его в сопрограмме

Чтобы получить результат обратно, вы можете добавить простой обратный вызов

IEnumerator Upload(string URL, string jsonData, Action<string> callback)
{
    using (UnityWebRequest www = UnityWebRequest.Post(URL, jsonData))
    {
        www.SetRequestHeader("Content-Type", "application/json");

        yield return www.SendWebRequest();

        if (www.isNetworkError || www.isHttpError)
        {
            Debug.Log(www.error);
        }
        else
        {
            Debug.Log("Form upload complete!");
            callback?.Invoke(www.GetResponseHeader("Location"));
        }
    }
}

и используйте его с

StartCoroutine(Upload(someURL, someJsonData, 
    // e.g. as lambda expression
    result => 
    {
        Debug.Log(result);
    }
));

или методом

StartCoroutine(Upload(someURL, someJsonData, HandleUploadResult);

...

private void HandleUploadResult(string result)
{
    Debug.Log(result);
}

Но если вам действительно нужно использовать его с await, как сказано , то выглядит многообещающе (хотя neevr и пробовал):

public class UnityWebRequestAwaiter : INotifyCompletion
{
    private UnityWebRequestAsyncOperation asyncOp;
    private Action continuation;

    public UnityWebRequestAwaiter(UnityWebRequestAsyncOperation asyncOp)
    {
        this.asyncOp = asyncOp;
        asyncOp.completed += OnRequestCompleted;
    }

    public bool IsCompleted { get { return asyncOp.isDone; } }

    public void GetResult() { }

    public void OnCompleted(Action continuation)
    {
        this.continuation = continuation;
    }

    private void OnRequestCompleted(AsyncOperation obj)
    {
        continuation();
    }
}

public static class ExtensionMethods
{
    public static UnityWebRequestAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp)
    {
        return new UnityWebRequestAwaiter(asyncOp);
    }
}

Это выглядит сложно, но ... с этим ничего не нужно делать, просто положите это куда-нибудь в свой Assets.

Тогда, насколько я понимаю, вы можете просто использовать что-то вроде

www = UnityWebRequest.Post(URL, jsonData);
www.SetRequestHeader("Content-Type", "application/json");
await www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
    Debug.Log(www.error);
}
else
{
    Debug.Log("Form upload complete!");
    var result = www.GetResponseHeader("Location");
}

Есть другие источники , которые делают что-то подобное ... может быть, лучше?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...