Created
September 7, 2022 12:02
-
-
Save petitviolet/d6be3158e77633b25e2facd467d46d44 to your computer and use it in GitHub Desktop.
Json over HTTP in Unity C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Cysharp.Threading.Tasks; | |
using UnityEngine; | |
using UnityEngine.Networking; | |
namespace MyNamespace | |
{ | |
public class JsonHttp | |
{ | |
public class HttpError : Exception | |
{ | |
public readonly long StatusCode; | |
public HttpError(long statusCode, string message) : base(message) | |
{ | |
StatusCode = statusCode; | |
} | |
public HttpError(long statusCode, string message, Exception baseException) : base(message, baseException) | |
{ | |
StatusCode = statusCode; | |
} | |
override public string ToString() | |
{ | |
return $"HttpError(statusCode: {StatusCode}, message: {Message})"; | |
} | |
} | |
private readonly Uri _baseUri; | |
public JsonHttp(string baseUri) | |
{ | |
this._baseUri = new Uri(baseUri); | |
} | |
public async Task<Result<T, HttpError>> Get<T>(string path, Dictionary<string, string> query = null, Dictionary<string, string> headers = null, int timeoutSec = 3) | |
{ | |
var urlParameter = query != null ? $"?{String.Join("&", query.Select(pair => pair.Key + "=" + pair.Value))}" : ""; | |
var url = new Uri(_baseUri, $"{path}{urlParameter}"); | |
Debug.Log($"GET url: {url}, query: {query}"); | |
var request = UnityWebRequest.Get(url); | |
return await ProcessJsonRequest<T>(request, headers, timeoutSec); | |
} | |
public async Task<Result<T, HttpError>> Post<T>(string path, object requestBody, Dictionary<string, string> headers = null, int timeoutSec = 3) | |
{ | |
var url = new Uri(_baseUri, path); | |
var body = JsonUtility.ToJson(requestBody); | |
Debug.Log($"POST url: {url}, body: {body}"); | |
var request = new UnityWebRequest(url, "POST"); | |
request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(body)); | |
request.downloadHandler = new DownloadHandlerBuffer(); | |
return await ProcessJsonRequest<T>(request, headers, timeoutSec); | |
} | |
private async Task<Result<T, HttpError>> ProcessJsonRequest<T>(UnityWebRequest request, Dictionary<string, string> headers, int timeoutSec) | |
{ | |
request.timeout = timeoutSec; | |
request.SetRequestHeader("Content-Type", "application/json"); | |
request.SetRequestHeader("Accept", "application/json"); | |
if (headers != null) | |
{ | |
foreach (var entry in headers) | |
{ | |
request.SetRequestHeader(entry.Key, entry.Value); | |
} | |
} | |
try | |
{ | |
await request.SendWebRequest().WithCancellation(CancellationToken.None); | |
var text = request.downloadHandler.text; | |
Debug.Log($"result: {request.result}, responseCode: {request.responseCode}, body: {text}, error: {request.error}"); | |
// Consider the request succeeded only when it gets 200-399 HTTP status code | |
if (request.result == UnityWebRequest.Result.Success && request.responseCode >= 200 && request.responseCode < 400) | |
{ | |
var body = JsonUtility.FromJson<T>(text); | |
return Result<T, HttpError>.Succeeded(body); | |
} | |
else | |
{ | |
return Result<T, HttpError>.Failed(new HttpError(request.responseCode, request.error.Length > 0 ? request.error : text)); | |
} | |
} | |
catch (Exception e) | |
{ | |
return Result<T, HttpError>.Failed(new HttpError(request.responseCode, $"ProcessJsonRequest failed due to {e}")); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Result
type defined here https://gist.github.com/petitviolet/d29d7cd4d3f967ebda06a7b429d05070