I'm not so experienced with C#, anyway I'm using the following function to post data to my own API:
public static JSONNode SaveObject(List<String> parameters){
var request = (HttpWebRequest)WebRequest.Create("http://example.com/query.php?");
var data = Encoding.ASCII.GetBytes(String.Join("",parameters));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream()){ stream.Write(data, 0, data.Length); }
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
// Debug.Log("RESPONSE: " + responseString);
// JSONNode object
var obj = JSON.Parse(responseString);
return obj;
}
Here's how I call it:
List<String> parameters = new List<String>();
parameters.Add("tableName=Posts"));
parameters.Add("&text=Text & more"));
parameters.Add("&number=123"));
// Save
var result = SaveObject(parameters);
Debug.Log("OBJECT SAVED: " + result.ToString());
I was fine with my SaveObject()
function until I've found out that the Text & more
String gets truncated to Text
in my JSON file to the "text" key (my API simply edits JSON files).
I know why that happens, it's because the String.Join("",parameters) generates a URL string that looks like "tableName=Posts&text=Text & more&number=123"
, so the & character between Text
and more
gets invalidated because my PHP code thinks it's a separator like the other & 's
So I can't figure out how to transform my SaveObject()
function to use a Dictionary of parameters instead of a String. If I'll use something like a <string, string>
dictionary, I think I'll solve my & character issue, nice Iìm using a Dictionary for the iOS code that calls my API
You should rather use a UnityWebRequest.Post
the 4th overload is
public static Networking.UnityWebRequest Post(string uri, Dictionary<string,string> formFields);
and does exactly what you are trying I guess.
The Content-Type header will be set to application/x-www-form-urlencoded.
So you don't even have to do that manually.
You would need a reference to a MonoBehaviour
though in order to run a Coroutine and wait for the result as otherwise you would block the Unity main thread:
public static void SaveObject(MonoBehaviour behaviour, Dictionary<string, string> parameters, Action<JSONNode> resultHandler)
{
behaviour.StartCoroutine(SendSaveRequest(parameters, resultHandler));
}
private static IEnumerator SendSaveRequest(Dictionary<string, string> parameters, Action<JSONNode> resultHandler)
{
using(var uwr = UnityWebRequest.Post("http://example.com/query.php?", parameters)
{
yield return uwr.SendWebRequest();
if (uwr.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Form upload complete!");
var responseString = uwr.downloadHandler.text;
// Debug.Log("RESPONSE: " + responseString);
// JSONNode object
var obj = JSON.Parse(responseString);
resultHandler?.Invoke(obj);
}
}
}
So you would call it like (assuming this code is in a MonoBehaviour
script)
var parameters = new Dictioary<string,string>
{
{"tableName","Posts"},
{"text","Text & more"},
{"number","123"}
};
// Save
var result = SaveObject(this, parameters, OnSaveDone);
...
private void OnSaveDone(JSONNode result)
{
Debug.Log("OBJECT SAVED: " + result.ToString());
}
Alternatively you could of course simply do something like
var data = Encoding.ASCII.GetBytes(String.Join("",parameters));
data = data.Replace(" ", "_SPACE_").Replace("&", "_AND_");
an then on the PHP receiver side replace the other way round before handling the parameters (of course more error prone)
$search = array("_SPACE_","_AND_");
$replace = array(" ", "&");
$escapedValue = $_POST["parameter"];
$value = str_replace($search, $replace, $escapedValue);
Note: Typed on smartphone but I hope the idea gets clear
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.