Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Yoconn · Sep 28, 2021 at 10:13 PM · jsonapiwebrequestpost

Can you post a json string as a body in Unity?

I'm trying to post a json string as the body of a UnityWebRequest but it just fails throws protocolerror and doesnt work.

I can post using postman.

I can get data using pretty much the exact same function except for a few changes.

Post just isnt working for me.

 public static async Task<string> PostData(string url, string data)
 {
       using(UnityWebRequest request = UnityWebRequest.Post(url, data))
         {
             request.SetRequestHeader("Content-Type", "application/json");
             request.SetRequestHeader("Accept", "application/json");
             var operation = request.SendWebRequest();
             while(!operation.isDone)
             {
                 await Task.Yield();
                 Debug.Log($"({request.downloadProgress}%)");
             }
             if(request.isHttpError || request.isNetworkError)
             {
                 Debug.Log("Request failed...");
                 return null;
             }
             if(request.result == UnityWebRequest.Result.Success)
                 return request.downloadHandler.text;
             return null;
         }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Yoconn · Oct 02, 2021 at 05:47 AM

hmm, my body was coming in as something like Text.File.Json or something similar. So my asp.net app was looking for a string

 PostFunction([FromBody]string data)

But Unity, or my code dunno, was sending it as the Text.File.Json or whichever it was. So I changed my code to

 PostFunction([FromBody]object data)

Which, when debugging it locally, caused it to actually hit my breakpoint and start the function.

Hope this helps anybody else trying to Post to an asp.net web api. Goodluck

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by Bunny83 · Sep 29, 2021 at 12:13 AM

Well, this is a common pitfall with Unity's Post method. For some reason they throught it's a great idea that by default any Post request will send url encoded data which is extremely unintuitive. See the exact implementation here.


If you want to post raw text / json / binary / whatever you have to provide your own UploadHandlerRaw and provide your data that way.


I quickly setup a php script like this:

 <?php
     $postData = file_get_contents("php://input");
     $request = json_decode($postData, true);
     $request["result"] = "FooBar";
     $result = json_encode($request, JSON_PRETTY_PRINT);
     header("Content-Type", "application/json");
     echo $result;
 ?>

and added this line before your SendRequest line:

 request.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(data));

This will replace the upload handler with our own and we simply perform an UTF8 encoding on the text.

I used my SimpleJSON (since I already had it in my project) just to run this example:

 async void Start()
 {
     JSONNode n = new JSONObject();
     n["test"] = 42;
     Debug.Log("Request: " + n.ToString(3));
     string res = await PostData("MyURL/php/JsonTest.php", n.ToString());
     var node = JSON.Parse(res);
     Debug.Log("Response: " + node.ToString(3));
 }

So the php script will parse the json into an object, add a new field called "result" and simply return whatever was send in to the client. The two log statements in Unity look like this:

 Request: {
    "test" : 42
 }
 
 Response: {
     "test" : 42,
     "result" : "FooBar"
 }

So this works as expected once you use a raw upload handler.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Yoconn · Sep 29, 2021 at 05:06 AM 0
Share

Hmm, i tried what you suggested and im getting this as an error now HTTP/1.1 400 Bad Request

Do you know if my web service only allowing https would cause an error?

avatar image Bunny83 Yoconn · Sep 29, 2021 at 08:57 AM 0
Share

My request was an https request onto my raspberry pi server which runs an apache server with a lets encrypt wildcard certificate on my own dyn dns domain. So, it does work with https ^^. When you get a 400 Bad Request the error may be on your server side. I don't know what you run as server or what that service may expect. Are you even sure that the json you post from Unity is valid json?


Since it's difficult to use WireShark when you use https, if you can temporarily switch to http, you could use it to inspect the packets that actually go out. Another option which is a bit simpler is to create a WebGL build and use the web developer tools in firefox or chrome to inspect the request there in the network tab. Though running a webgl build locally has lots of other issues. The most robust solution is when you can host it on an actual web server. You could use something like XAMPP or similar package. Or use something like github pages to host your build. Of course your API (which probably runs on a different server / domain) has to use CORS in order to allow cross domain access. Again we don't know anything about the service you're using. Is this your own server you have setup? Or is it some kind of backend you have no control over?

avatar image Yoconn Bunny83 · Sep 29, 2021 at 07:02 PM 0
Share

Hmm, I've tried running it locally as well and changing my IP to a localhost and setting a breakpoint on the function and it doesn't even hit it.

My service is a .net core web API running on a Linux server I pay for through DigitalOcean. So I pretty much control everything, I'm also using letsencrypt.

Its successful if I run my local build using swagger and it can pull/push data to the server. I can also post/get using postman. It all works except for inside Unity for whatever reason.

I'm still somewhat new to netcore web API, but I wonder if since it's expecting a string as the body and since Unity puts a byte[] in the body (or am I mistaken?) that I have to update the service to look for a byte[]. I didn't think it would skip over my breakpoint entirely but it might. (Once upon a time I tried PHP but it drove me mad and I hopped ship to netcore)

I'll have to look into this when I get home from work today.

I also deeply appreciate you having a back and forth with me. Normally I get an initial comment and no follow up ones. <3 Cheers

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

129 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Webrequest Post SetRequestHeader Problem 0 Answers

Posting JSON-RPC with WebRequest 0 Answers

Can't Send a form to a server(POST) due to CORS error in a WEBGL build 1 Answer

How do I parse JSON from an API and import the variables into a gameobject component during runtime? 0 Answers

Pass Headers and Arguments in UnityWebRequest POST Method Object 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges