Not sure what's going on but I have working code for a desktop app/mobile app I'm trying to port to WebGL. Upon testing the WebGL is not making calls to the API. Its almost like its unable to send the object. API Backend: Code (CSharp): [Route("api/WhiteBoXGaming/Post_TestAPI")] [HttpPost] public WBGString WhiteBoxGaming_Test([FromBody]OAuth oAuth) { bool AccessGranted = _DataHelper.OAuth(oAuth.Administrator, oAuth.Password); WBGString WBGString = new WBGString(); if (AccessGranted) { WBGString.Http_Response = "White Box Gaming Established 2018 All Rights Reserved"; } else { WBGString.Http_Response = "Access Denied"; } return WBGString; } Client/App Code (CSharp): using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Http; using UnityEngine; using UnityEngine.UI; using WBG_4; public class send : MonoBehaviour { public Text txtResponse; private string _Response; public void Send() { string uri = WBG_Config._EndPoint + "api/WhiteBoXGaming/Post_TestAPI"; OAuth oAuth = new OAuth(); oAuth.Administrator = WBG_Config._OAuth_Admin; oAuth.Password = WBG_Config._OAuth_Password; StartCoroutine(Testwebrequest(uri, oAuth)); txtResponse.text = _Response; } IEnumerator Testwebrequest(string uri, object obj) { string json = JsonConvert.SerializeObject(obj); var client = new HttpClient(); var webRequest = WebRequest.Create(uri); webRequest.Method = "POST"; webRequest.ContentType = "application/json"; using (var streamWriter = new StreamWriter(webRequest.GetRequestStream())) { streamWriter.Write(json); } var httpResponse = (HttpWebResponse)webRequest.GetResponse(); using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) { var result = streamReader.ReadToEnd(); _Response = Convert.ToString(result); } yield return _Response; } }
Debug and figure out what's happening. Is the code even running? Is the request getting to the server? Is there an error coming back from the server? What kind of error is coming back from the server?
Its never making it to the API. I have the API running locally for testing. I assume this code is not right or at least not how WebGL interacts with http request to an api. Thats the part i dont know. If someone has a working snipett of how to send a http request to an api using webgl that would likely help.
Are you testing in a web browser? Have you tried using your browser's developer tools to see what happens with the request? I suspect @Kurt-Dekker 's theory about CORS is probably correct.
@Kurt-Dekker I'm trying to convert my code to use the Unity Web Request as suggested but keeps sending null. What did I do wrong here? Code (CSharp): IEnumerator TestUnityWebRequest(string uri, object obj) { string json = JsonConvert.SerializeObject(obj); UnityWebRequest www = UnityWebRequest.Post(uri, json); yield return www.SendWebRequest(); if (www.isNetworkError || www.isHttpError) { Debug.Log(www.error); } else { Debug.Log("Sent"); } }
Tried this as well but still failed: Code (CSharp): private IEnumerator Testwebrequest2(string uri, object obj) { string json = JsonConvert.SerializeObject(obj); var request = UnityWebRequest.Post(uri, json); request.SetRequestHeader("Content-Type", "application/json"); yield return request.SendWebRequest(); if (request.isNetworkError || request.isHttpError) { Debug.Log(request.error); } else { Debug.Log("Sent"); } yield return request; } Can some one please convert my working request to Unity Web Request Please. Thanks
I got the request working now I need to get the response converted to a Object: Code (CSharp): IEnumerator Post(string url, string bodyJsonString) { var request = new UnityWebRequest(url, "POST"); byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); yield return request.Send(); Debug.Log("Status Code: " + request.responseCode); var response = request.downloadHandler.text; using (var streamReader = new StreamReader(response)) { var result = streamReader.ReadToEnd(); _Response = Convert.ToString(result); } yield return _Response; txtResponse.text = request.ToString(); } getting illegal character error
Figured it out. After a lot of trial and error here is working code sample: Code (CSharp): IEnumerator Post(string url, string bodyJsonString) { var request = new UnityWebRequest(url, "POST"); byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); yield return request.Send(); Debug.Log("Status Code: " + request.responseCode); var response = request.downloadHandler.text; using (var streamReader = new StreamReader(response)) { var result = streamReader.ReadToEnd(); _Response = Convert.ToString(result); } yield return _Response; txtResponse.text = request.ToString(); }
I got the Unity Web Request working but its still not working when I test outside of the editor. Please here is the call: Code (CSharp): using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.IO; using System.Net; using System.Net.Http; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; using WBG_4; public class send : MonoBehaviour { public Text txtResponse; private string _Response; public void Send() { string uri = WBG_Config._EndPoint + "api/WhiteBoXGaming/Post_TestAPIJson"; //"api/WhiteBoXGaming/Post_TestAPI";// OAuth oAuth = new OAuth(); oAuth.Administrator = WBG_Config._OAuth_Admin; oAuth.Password = WBG_Config._OAuth_Password; string json = JsonConvert.SerializeObject(oAuth); StartCoroutine(Post(uri, json)); } IEnumerator Post(string url, string bodyJsonString) { var request = new UnityWebRequest(url, "POST"); byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); yield return request.Send(); Debug.Log("Status Code: " + request.responseCode); var response = request.downloadHandler.data; string json = System.Text.Encoding.UTF8.GetString(response); var _Response = JsonConvert.DeserializeObject<string>(json); yield return _Response; txtResponse.text = _Response; } } I'm testing locally using Firefox not sure if that makes a difference. It works in the Unity editor but out side of that it fails.
I also just tried this way and still not working. Does anyone have working WebGL that can make calls to an API? Code (CSharp): IEnumerator GetJsonContent(string url, string bodyJsonString) { var request = UnityWebRequest.Post(url, "{}"); request.method = "POST"; byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); yield return request.SendWebRequest(); while (!request.isDone) { yield return new WaitForEndOfFrame(); } if (request.isNetworkError) { Debug.Log(request.error); } else { //var jsonContent = request.downloadHandler.text; var response = request.downloadHandler.data; string json = System.Text.Encoding.UTF8.GetString(response); var _Response = JsonConvert.DeserializeObject<string>(json); txtResponse.text = _Response; } yield break; }
Well, we don't know where your WebGL content is hosted and if the API belongs to the same domain. If not the server that serves the API does not implement CORS, your browser will not allow any cross domain requests. Note that browsers like Chrome and FireFox usually restrict locally (file hosted) webcontent even more. There are some configuration flags that can be changed in the browsers to allow local file testing. If you want to test your webgl application I highly recommend that you use an actual web server to host your content. So first you should check if you are crossing domain borders and if you do, make sure the API server allows access from your domain (it's possible to allow any domain for that matter).
I have a web host I could use did not want to put it on there until i tested locally. So if your saying this should work then i'll put it on there just to test
No ^^ Testing can be done locally. However you should test it on a real server. Commonly you could simply install XAMPP or a similar package depending on your needs. Not related to Unity development but for some other business project I maintain I have setup some local fake domains in my windows's hosts file so I can actually register SSL certs localls to actually test everything well to the bone locally. It's still not clear if the API you are trying to reach actually belongs to your own server or if it's a third party service. If it's part of your own server, you can run that API also locally on your test server. The application I maintain uses a PHP backend with a MySql database. It's an ancient Zend based application -.-. Apart from that Xampp server which I only boot up when I'm actually working on that project, I also have an apache server on my raspberry pi running in my home network which is actually reachable from the internet. So I can test certain APIs even from the internet. Though I mainly use the webserver on my pi to host my computercraft scripts so i have them available no matter on which server I play minecraft
@mholmes You'll need to define "not working", how are you debugging? Is your web server receiving the request? Is this code actually executing? All this can be determined with Debug.Log statements, provide your output here. In my apps, I simply write the debug output to a UI Text element during development. You can also use Charles Proxy to monitor the actual networks requests for debugging Code (CSharp): private void MyDebug(string debug) { Debug.Log(debug); myText.text += "\r\n" + debug; } https://support.unity.com/hc/en-us/articles/115002917683-Using-Charles-Proxy-with-Unity https://forum.unity.com/threads/tips-for-new-unity-users.701864/#post-5057741 https://docs.unity3d.com/Manual/webgl-debugging.html
So I was right it does not work, I uploaded to my site and still not working. So does anyone have a sample code where you make calls to a working API using WebGL?
As mentioned, define "not working". How are you debugging? What is the return code from request.SendWebRequest, for example. You'll want to Debug.Log this value.
Are you guys reading all the post or just the last post? There is a huge history explaining the issues I'm having. Update: I have one final test I can do before I'm out of ideas on this issue
Personally I've been following the entire thread. You haven't confirmed if your code is actually executing, nor the if the web server is receiving the requests. Several persons have recommended that you debug your code, but I haven't seen any debug output yet. When debugging an API, you always check the API method return code. "Not working" could mean that your code isn't executing, or is executing and failing, please confirm with the debug output.
Sorry for delay on responses. I'm debugging by break points both on a local API and in app. The API is a known working API. I have a prod version as well I'm testing with as well. I've never used Unity Web Request. Only used HTTP, so Unity Web Request is new to me. Just trying to understand how it works in editor and on a desktop app built but not on Web GL. Right now I'm uploading it to my prod web server for more testing. After this im out of ideas on how to debug or even fix.
Thats fair. So original issue was it was not reaching the API. That got fixed. Issue 2 was it was returning but I di dnot know how to convert the returned from byte array into object. That got fixed and now I'm working on testing on a "built" WebGL version. Prior all testing was in Unity Editor. I hope that makes sense. Anyway now I'm posting the "built" webGl code on the hosted prod server for more testing to see if it will work since it was suggested locally testing via browser is likely the issue.
What is the return code from request.SendWebRequest? That will likely tell you the issue, my guess is 403-Unauthorized.
So here is the website testing on http://www.whiteboxgaming.com/webgl/ Its still not working. Here is the code: Code (CSharp): using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.IO; using System.Net; using System.Net.Http; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; using WBG_4; public class send : MonoBehaviour { public Text txtResponse; public Text txtDebug; private string _Response; public void Send() { string uri = WBG_Config._EndPoint + "api/WhiteBoXGaming/Post_TestAPI"; OAuth oAuth = new OAuth(); oAuth.Administrator = WBG_Config._OAuth_Admin; oAuth.Password = WBG_Config._OAuth_Password; string json = JsonConvert.SerializeObject(oAuth); //StartCoroutine(Post(uri, json)); StartCoroutine(GetJsonContent(uri, json)); } IEnumerator Post(string url, string bodyJsonString) { var request = new UnityWebRequest(url, "POST"); byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); txtDebug.text = request.ToString(); yield return request.Send(); Debug.Log("Status Code: " + request.responseCode); var response = request.downloadHandler.data; string json = System.Text.Encoding.UTF8.GetString(response); var _Response = JsonConvert.DeserializeObject<string>(json); yield return _Response; txtResponse.text = _Response; } IEnumerator GetJsonContent(string url, string bodyJsonString) { var request = UnityWebRequest.Post(url, "{}"); request.method = "POST"; byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); yield return request.SendWebRequest(); while (!request.isDone) { yield return new WaitForEndOfFrame(); } if (request.isNetworkError) { Debug.Log(request.error); } else { //var jsonContent = request.downloadHandler.text; var response = request.downloadHandler.data; string json = System.Text.Encoding.UTF8.GetString(response); var _Response = JsonConvert.DeserializeObject<WBGString>(json); txtResponse.text = _Response.Http_Response; } yield break; } } I have no way of debugging when its on live server. Update: I'll try to get return code let me update code Update well now it looks like its never even calling the co routine
Yes, you can debug on a live web server, I provided instructions previously. And I might recommend to create a "Hello Web Server" sample project to isolate your issue. Don't use a co-routine, just use a simple button click.
Ok let me try this last build Im making and then I can try to understand what those errors are you have in screen shot. I dont use browser tools that often so im not super familiar with it. Update I found this based on errors https://stackoverflow.com/questions/16359628/json-net-under-unity3d-for-ios Is everyone using this instead of Newtonsoft for unity?
You don't need browser tools to debug, following previous instructions. But they both provide the same output.
@JeffDUnity3D I assume you know the answer to this then. According to stack overflow the issue I have is because Newtonsoft and IL2CPP. It looks like the new versions of Newtonsoft are supported for 2018 and higher? I know I'm using a old version. Do you know what version supports IL2CPP?
You are having JSON errors? I thought you were having web request errors. So the server is returning a response? You need to provide the results of your debugging rather than this back and forth. I don't know the "the issue I have" that you refer to.
@JeffDUnity3D I literally just learned that the issue is JSon. @PraetorBlue pointed it out to me so I tested and they where right. Its a Json issue with IL2CPP. So Now I'm asking what version of Newtonsoft works with IL2CPP? Just a part of the troubleshooting process. Edit: it says latest version is Version 12.0.3. Will that work with IL2CPP?
Try it and see? What is the error that you receiving? I would not want to guess at a specific recommendation without knowing the cause and the error. Take JSON out of the equation, just use text during testing and simplify your problem. Otherwise, JSON.NET is a good choice.
I'm going to update the server API but here is what I get error wise from browser: Code (CSharp): NotSupportedException: System.Reflection.Emit.DynamicMethod::.ctor (Filename: currently not available on il2cpp Line: -1) 4252c009-27c1-44f6-b9df-3078cec7e1f8:8:48377 _JS_Log_Dump blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8:8 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:1581907 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:1585629 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:1584803 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:1578799 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:1639944 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:5137826 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:12267550 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:12267627 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:6172720 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:12281307 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:6172720 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:12249823 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:9280937 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:7138827 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:7166637 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:7171514 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:7170144 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:7168640 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:7167941 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:6173168 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:7143175 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:8604910 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:14515265 dynCall_iiiii blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8:8 invoke_iiiii blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8:8 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:8191020 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:8053684 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:1638759 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:1638549 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:3629433 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:3624549 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:4840575 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:4839832 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:4013780 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:3685087 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:3685108 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:3681723 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:3675176 <anonymous> blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8 line 8 > WebAssembly.instantiate:14516183 dynCall_v blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8:8 browserIterationFunc blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8:8 runIter blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8:8 Browser_mainLoop_runner blob:null/4252c009-27c1-44f6-b9df-3078cec7e1f8:8 I just updated the local game Newtonsoft.dll to the lastest version. This appears to not even convert the object into json. So this appears to be inside Unity I think. I have so new debug code: Code (CSharp): using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.IO; using System.Net; using System.Net.Http; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; using WBG_4; public class send : MonoBehaviour { public Text txtResponse; public Text txtDebug; private string _Response; public void Send() { txtDebug.text = "Click button"; string uri = WBG_Config._EndPoint + "api/WhiteBoXGaming/Post_TestAPI"; OAuth oAuth = new OAuth(); txtDebug.text = "define object"; oAuth.Administrator = WBG_Config._OAuth_Admin; oAuth.Password = WBG_Config._OAuth_Password; txtDebug.text = "json"; string json = JsonConvert.SerializeObject(oAuth); txtDebug.text = "StartCoroutine"; StartCoroutine(GetJsonContent(uri, json)); } IEnumerator Post(string url, string bodyJsonString) { var request = new UnityWebRequest(url, "POST"); byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); txtDebug.text = request.ToString(); yield return request.Send(); Debug.Log("Status Code: " + request.responseCode); var response = request.downloadHandler.data; string json = System.Text.Encoding.UTF8.GetString(response); var _Response = JsonConvert.DeserializeObject<string>(json); yield return _Response; txtResponse.text = _Response; } IEnumerator GetJsonContent(string url, string bodyJsonString) { var request = UnityWebRequest.Post(url, "{}"); request.method = "POST"; byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); txtDebug.text = "Sent"; yield return request.SendWebRequest(); txtDebug.text = "Returned"; while (!request.isDone) { yield return new WaitForEndOfFrame(); } if (request.isNetworkError) { txtDebug.text = request.error; Debug.Log(request.error); } else { //var jsonContent = request.downloadHandler.text; var response = request.downloadHandler.data; string json = System.Text.Encoding.UTF8.GetString(response); var _Response = JsonConvert.DeserializeObject<WBGString>(json); txtResponse.text = _Response.Http_Response; } yield break; } }
Breaks on line 33: https://whiteboxgaming.com/webgl/ Look at debug text you can see because next line should be Start Coroutine. So it wants to break when it trys to conver object to Json string
The error message means that Newtonsoft JSON is attempting to use dynamic code generation, which is not allowed with IL2CPP, so won't work with WebGL. You should be able to do JSON serialization, but make sure that the JSON library has an AOT mode.
That's why I always use my own SimpleJSON library for web communication. It's not an object mapper but a simple parser / generator which provides an easy interface to work with the json data. There's also an extension file for common Unity types which simplify reading writing vectors, colors and some other types. Personally I think strict object mapping is in general not a great approach for a json based web API as depending on the API you may receive different responses. Most APIs have a different structure when an error happened. Strongly typed languages are quite unflexible in this field. That's why my class uses strongly typed dictionary and array based classes which allow the usage without the need of manually casting the values. Though of course it depends on how you consume the data in the end. As great and versatile Json.Net is, especially for webGL builds the library is unnecessarily huge.
So here is the ultimate issue issue I ran into. My website that I uploaded WebGL too is HTTPS and the API lives on HTTP. I got a error that you cant receive data from HTTP to HTTPS. So the POST was blocked after I fixed the Json issue above. Those of you who are having issues with the Json issue here is Unity solution: https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347 No idea if there is a updated version of Json for Unity but it appears to work with IL2CPP. I'm going to try uploading to a non HTTPS host and see if I can get it working. I think their are some free hosts I can use for testing.
Update: I uploaded to this site:whiteboxgaming.infinityfreeapp.com I'm getting this error from CORS Access to XMLHttpRequest at 'http://www.whiteboxgaming.xyz:34188/api/WhiteBoXGaming/Post_TestAPI' from origin 'http://whiteboxgaming.infinityfreeapp.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Not sure what to make of this or how to fix this issue. Is this API side or Unity side? Update Just a shot in the dark I'm going to try adding this Code (CSharp): IEnumerator GetJsonContent(string url, string bodyJsonString) { var request = UnityWebRequest.Post(url, "{}"); request.method = "POST"; byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); request.GetResponseHeader("Access-Control-Allow-Origin"); txtDebug.text = "Sent"; yield return request.SendWebRequest(); txtDebug.text = "Returned"; while (!request.isDone) { yield return new WaitForEndOfFrame(); } if (request.isNetworkError) { txtDebug.text = request.error; Debug.Log(request.error); } else { //var jsonContent = request.downloadHandler.text; var response = request.downloadHandler.data; string json = System.Text.Encoding.UTF8.GetString(response); var _Response = JsonConvert.DeserializeObject<WBGString>(json); txtResponse.text = _Response.Http_Response; } yield break; }
I think I'm missing something, I'm getting this error: Access to XMLHttpRequest at 'http://www.whiteboxgaming.xyz:34188/api/WhiteBoXGaming/Post_TestAPI' from origin 'http://whiteboxgaming.infinityfreeapp.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. I've researched it and it says I need to add "Access-Control-Allow-Origin" Here is updated code: Code (CSharp): IEnumerator GetJsonContent(string url, string bodyJsonString) { var request = UnityWebRequest.Post(url, "{}"); request.method = "POST"; byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Access-Control-Allow-Origin", "*"); request.SetRequestHeader("Content-Type", "application/json"); txtDebug.text = "Sent"; yield return request.SendWebRequest(); txtDebug.text = "Returned"; while (!request.isDone) { yield return new WaitForEndOfFrame(); } if (request.isNetworkError) { txtDebug.text = request.error; Debug.Log(request.error); } else { //var jsonContent = request.downloadHandler.text; var response = request.downloadHandler.data; string json = System.Text.Encoding.UTF8.GetString(response); var _Response = JsonConvert.DeserializeObject<WBGString>(json); txtResponse.text = _Response.Http_Response; } yield break; }
getting a new error: InvalidOperationException: Header name contains invalid characters at UnityEngine.Networking.UnityWebRequest.SetRequestHeader (System.String name, System.String value) [0x00000] in <00000000000000000000000000000000>:0 code: Code (CSharp): IEnumerator GetJsonContent(string url, string bodyJsonString) { var request = UnityWebRequest.Post(url, "{}"); request.method = "POST"; byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); txtDebug.text = "Access-Control-Allow-Origin: *"; request.SetRequestHeader("Access-Control-Allow-Origin", "*"); txtDebug.text = "Access-Control-Allow-Origin: true"; request.SetRequestHeader("Access-Control-Allow-Credentials:", "true"); txtDebug.text = "Content type json"; request.SetRequestHeader("Content-Type", "application/json"); txtDebug.text = "Sent"; yield return request.SendWebRequest(); txtDebug.text = "Returned"; while (!request.isDone) { yield return new WaitForEndOfFrame(); } if (request.isNetworkError) { txtDebug.text = request.error; Debug.Log(request.error); } else { //var jsonContent = request.downloadHandler.text; var response = request.downloadHandler.data; string json = System.Text.Encoding.UTF8.GetString(response); var _Response = JsonConvert.DeserializeObject<WBGString>(json); txtResponse.text = _Response.Http_Response; } yield break; } Added some more debugging
Now im getting new error from Unity: base = "System.InvalidOperationException: Header name contains invalid characters\r\n at UnityEngine.Networking.UnityWebRequest.SetRequestHeader (System.String name, System.String value) [0x00053] in C:\\buildslave\\unity\\build\\Modules\\UnityWebRequest\\Public\... So I dont know how to resolve this: Code (CSharp): IEnumerator GetJsonContent(string url, string bodyJsonString) { string EndPoint = WBG_Config._EndPoint; var request = UnityWebRequest.Post(url, "{}"); request.method = "POST"; byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString); try { request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); txtDebug.text = "Access-Control-Allow-Origin: *"; request.SetRequestHeader("Access-Control-Allow-Origin", EndPoint); txtDebug.text = "Access-Control-Allow-Origin: true"; request.SetRequestHeader("Access-Control-Allow-Credentials:", "true"); txtDebug.text = "Content type json"; request.SetRequestHeader("Content-Type", "application/json"); } catch (Exception ex) { Debug.Log(ex.Message); } txtDebug.text = "Sent"; yield return request.SendWebRequest(); txtDebug.text = "Returned"; while (!request.isDone) { yield return new WaitForEndOfFrame(); } if (request.isNetworkError) { txtDebug.text = request.error; Debug.Log(request.error); } else { //var jsonContent = request.downloadHandler.text; var response = request.downloadHandler.data; string json = System.Text.Encoding.UTF8.GetString(response); var _Response = JsonConvert.DeserializeObject<WBGString>(json); txtResponse.text = _Response.Http_Response; } yield break; }
Was about to recommend that one, it's definitely a working solution, at least for most of the cases. Your server needs to add the information to its response's header. The client cannot do that.
Here is API code. Not sure what you want me to add? Code (CSharp): public WBGString WhiteBoxGaming_Test([FromBody]OAuth oAuth) { bool AccessGranted = _DataHelper.OAuth(oAuth.Administrator, oAuth.Password); WBGString WBGString = new WBGString(); if (AccessGranted) { WBGString.Http_Response = "White Box Gaming Established 2018 All Rights Reserved"; } else { WBGString.Http_Response = "Access Denied"; } return WBGString; }
You need to add configuration on your server. if you use ASP. NET Core on server follow this https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-5.0 if you use ASP. NET try this https://stackoverflow.com/questions...-mvc-simplest-possible-method/6290385#6290385