Sending http requests in C# with Unity

2018-12-31 13:40发布

How can I send HTTP GET and POST requests in C# with Unity?

What I want is:

  • send json data in post request (I use Unity serializer, so no need in new one, I just want to pass string in post data and have ability to set ContentType to application/json);
  • get response code and body without any problems;
  • do it all asynchronous without blocking ui rendering.

What I've tried:

  • implementing with HttpWebRequest/HttpWebResponse, but it's too hard and low level (if I won't found anything better, I'll have to use it);
  • using unity WWW, but it doesn't match my requirements;
  • using some external packages from NuGet - Unity don't accept them :(

Most problems were with threading, I'm not experienced enough in it in C#. Text editor, I use, is Intellij Rider.

标签: c# http unity3d
2条回答
人间绝色
2楼-- · 2018-12-31 14:04

Use HttpClient and something like:

public static HttpContent DoPost(object payload, string subPath)
    {
        var httpClient = new HttpClient();

        HttpClient.BaseAddress = new Uri(Global.BaseUrl);
        HttpClient.DefaultRequestHeaders.Clear();
        HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // if you're using json service

        // make request
        var response = Global.HttpClient.PostAsJsonAsync(subPath.TrimLeadingSlash(), payload).Result;

        // check for error
        response.EnsureSuccessStatusCode();

        // return result
        return response.Content;
    }

Payload is an object to be serialized to json. If all requests are going to the same baseUrl, you can set up HttpClient globally, and reuse it here

查看更多
弹指情弦暗扣
3楼-- · 2018-12-31 14:14

The WWW API should get this done but UnityWebRequest replaced it so I will answer the newer API. It's really simple. You have to use coroutine to do this with Unity's API otherwise you have have to use one of C# standard web request API and Thread. With coroutine you can yield the request until it is done. This will not block the main Thread or prevent other scripts from running.

Note:

For the examples below, if you are using anything below Unity 2017.2, replace SendWebRequest() with Send() and then replace isNetworkError with isError. This will then work for the lower version of Unity. Also, if you need to access the downloaded data in a binary form instead, replace uwr.downloadHandler.text with uwr.downloadHandler.data. Finally, the SetRequestHeader function is used to set the header of the request.

GET request:

void Start()
{
    StartCoroutine(getRequest("http:///www.yoururl.com"));
}

IEnumerator GetRequest(string uri)
{
    UnityWebRequest uwr = UnityWebRequest.Get(uri);
    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Error While Sending: " + uwr.error);
    }
    else
    {
        Debug.Log("Received: " + uwr.downloadHandler.text);
    }
}

POST request with Form:

void Start()
{
    StartCoroutine(postRequest("http:///www.yoururl.com"));
}

IEnumerator PostRequest(string url)
{
    WWWForm form = new WWWForm();
    form.AddField("myField", "myData");
    form.AddField("Game Name", "Mario Kart");

    UnityWebRequest uwr = UnityWebRequest.Post(url, form);
    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Error While Sending: " + uwr.error);
    }
    else
    {
        Debug.Log("Received: " + uwr.downloadHandler.text);
    }
}

POST request with Json:

 void Start()
 {
     StartCoroutine(postRequest("http:///www.yoururl.com", "your json"));
 }

 IEnumerator PostRequest(string url, string json)
 {
     var uwr = new UnityWebRequest(url, "POST");
     byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(json);
     uwr.uploadHandler = (UploadHandler)new UploadHandlerRaw(jsonToSend);
     uwr.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
     uwr.SetRequestHeader("Content-Type", "application/json");

     //Send the request then wait here until it returns
     yield return uwr.SendWebRequest();

     if (uwr.isNetworkError)
     {
         Debug.Log("Error While Sending: " + uwr.error);
     }
     else
     {
         Debug.Log("Received: " + uwr.downloadHandler.text);
     }
 }

POST request with Multipart FormData/Multipart Form File:

void Start()
{
    StartCoroutine(postRequest("http:///www.yoururl.com"));
}

IEnumerator PostRequest(string url)
{
    List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
    formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
    formData.Add(new MultipartFormFileSection("my file data", "myfile.txt"));

    UnityWebRequest uwr = UnityWebRequest.Post(url, formData);
    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Error While Sending: " + uwr.error);
    }
    else
    {
        Debug.Log("Received: " + uwr.downloadHandler.text);
    }
}

PUT request:

void Start()
{
    StartCoroutine(putRequest("http:///www.yoururl.com"));
}

IEnumerator PutRequest(string url)
{
    byte[] dataToPut = System.Text.Encoding.UTF8.GetBytes("Hello, This is a test");
    UnityWebRequest uwr = UnityWebRequest.Put(url, dataToPut);
    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Error While Sending: " + uwr.error);
    }
    else
    {
        Debug.Log("Received: " + uwr.downloadHandler.text);
    }
}

DELETE request:

void Start()
{
    StartCoroutine(deleteRequest("http:///www.yoururl.com"));
}

IEnumerator DeleteRequest(string url)
{
    UnityWebRequest uwr = UnityWebRequest.Delete(url);
    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Error While Sending: " + uwr.error);
    }
    else
    {
        Debug.Log("Deleted");
    }
}
查看更多
登录 后发表回答