Envío de solicitudes http en C#con Unity
unity3d (2)
¿Cómo puedo enviar solicitudes HTTP GET y POST en C # con Unity?
Lo que quiero es:
- enviar datos json en la solicitud posterior (uso el serializador de Unity, por lo que no es necesario en uno nuevo, solo quiero pasar una cadena en los datos de la publicación y tener la capacidad de configurar ContentType en application / json);
- obtener el código de respuesta y el cuerpo sin ningún problema;
- hazlo todo asíncrono sin bloquear la representación de la interfaz de usuario.
Lo que probé:
- implementando con HttpWebRequest / HttpWebResponse, pero es demasiado difícil y de bajo nivel (si no encuentro nada mejor, tendré que usarlo);
- usando unity WWW, pero no cumple con mis requisitos;
- usando algunos paquetes externos de NuGet - Unity no los acepta :(
La mayoría de los problemas fueron con subprocesos, no tengo suficiente experiencia en C #. El editor de texto, que uso, es Intellij Rider.
La API
WWW
debería hacerlo, pero
UnityWebRequest
reemplazó, por lo que responderé a la API más nueva.
Es muy simple
Debe usar la rutina para hacer esto con la API de Unity; de lo contrario, debe usar una de las API y subprocesos de solicitud web estándar de C #.
Con coroutine puede ceder la solicitud hasta que esté hecha.
Esto no bloqueará el subproceso principal ni evitará que se ejecuten otros scripts.
Nota :
Para los ejemplos a continuación, si está utilizando algo debajo de
Unity 2017.2
, reemplace
SendWebRequest()
con
Send()
y luego reemplace
isNetworkError
con
isError
.
Esto funcionará para la versión inferior de Unity.
Además, si necesita acceder a los datos descargados en forma binaria, reemplace
uwr.downloadHandler.text
con
uwr.downloadHandler.data
.
Finalmente, la función
SetRequestHeader
se usa para establecer el encabezado de la solicitud.
OBTENER solicitud :
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);
}
}
Solicitud POST con formulario :
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);
}
}
Solicitud POST con 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);
}
}
Solicitud POST con 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);
}
}
PONER solicitud :
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);
}
}
Solicitud ELIMINAR :
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");
}
}
Use HttpClient y algo como:
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;
}
La carga útil es un objeto para ser serializado a json. Si todas las solicitudes van a la misma baseUrl, puede configurar HttpClient globalmente y reutilizarlo aquí