how c# application can retrieve data from php in an efficient manner - c#

Below is my php code which works fine:
<?php
//This script checks the id and code of the already registered user from the database. If correct it returns the other details otherwise the respective error
//starting session
session_start();
//catching data from client
$id=$_POST['id'];
$code=$_POST['code'];
if($id&&$code)//checking if the data is not empty
{
//Connecting to server
($connect=mysqli_connect('localhost','root','','ohhell')) or exit("Connection Failed");
//Selecting user for given id
$result=mysqli_query($connect,"SELECT * FROM users WHERE id='$id'");
//Counting number of rows
$numrows=mysqli_num_rows($result);
if($numrows!=0)
{
//Creating associative array
$row=mysqli_fetch_assoc($result);
//freeing result set
mysqli_free_result($result);
//fetching code from database
$db_code=$row['code'];
$code=md5($code);
//checking if the codes match
if($code==$db_code)
{
//change status
mysqli_query($connect,"UPDATE users SET status='yellow' WHERE id='$id'");
$_SESSION['id']=$row['id'];
$_SESSION['name']=$row['name'];
$_SESSION['location']=$row['location'];
$name=$row['name'];
$location=$row['location'];
//closing connection
mysqli_close($connect);
//returning values to client
exit("$name\n$location");//Successful Login. Client can now create an object and switch the screen
}
else
{
exit("Invalid Player Code");//Unsuccessful Login
}
}
else
exit("Invalid Player ID");//Unsuccessful Login
}
else
exit("Incomplete Details");//Unsuccessful Login
?>
It returns the respective error message or the corresponding details of the player to the c# client. Below is the client side code to receive the data:
WebRequest request = WebRequest.Create(URL);
Stream dataStream;
WebResponse response;
StreamReader reader;
response = request.GetResponse();
dataStream = response.GetResponseStream();
reader = new StreamReader(dataStream);
responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
After receiving the data successfully the c# client separates both the data with the help of "\n" and then makes an object of a class and fill the received data to the respective data members of that class.
Now here comes the problem, since I am testing now everything is working fine. But, my question is that, as the data being read is going to be in the form of string, how can I make sure at the client side that the data is actually received successfully and the string that is retrieved actually contains the data and not the error message.
I mean suppose if an internal error occurs while connecting to php or any other network error returns the corresponding error that too would be in the form of string, now how I am going to differentiate that whether the the client app should start separating the data from the string to make the object or it should terminate with an error.
For the errors that I have included in my php I can use respective if() conditions in the c# client but that's not a proper way as the errors are not guaranteed to be limited to the considered errors in the php script. There might be a numerous number of errors that can be returned so what approach should be taken in this case to actually differentiate between the error and real data.
On possible approach is to prepend a signal say "1" to the data before sending it and to test for the signal at the client's side whether the received string starts with a "1". If yes then going for the separation else displaying the corresponding error message. But this approach is also not optimal as in the case the if the error itself starts with 1, it will fail.
So what should be actually done to send data to c# in an optimal way through a php script?
Sorry for the long description! Waiting for assistance!!!
Thanks a million billion trillion...:)

You could use http status codes to indicate error conditions.
It seems currently you're only using 200 OK (by default), but e.g. Invalid Player Code could result in a 401 Unauthorized or 403 Forbidden (if that's meant for some kind of authorization).
On the c# side you'd get that status code via the HttpWebResponse.StatusCode property

You can use HTTP Status codes to determine weather or not an error occured.
You php could set the respective HTTP header if an error occurs during the run of said php script i.e. using http_response_code.
If the Startus code is okay, you can parse the response (as said in the comments, using json) and retrieve the results. In case an error occured in the network communication, you produce the respective error yourself in the client. If an error occured in PHP, you retrieve the error by also parsing the response, thereby retrieving the error message.
Simple Example in PHP
$response = array();
$responseCode = null;
try {
// some code is executed
$responseCode = 200;
}
catch (Exception $e) {
// an error occured and we have to add it to our response
$response['error'] = array('errorcode' => $e->getCode(), 'error' => $e->getMessage());
$responseCode = 500;
}
http_response_code($responseCode);
echo(json_encode($response ));
Now in your c#, simply check the header. If it is 500 (meaning an error occured), json_decode the result and get the error. If it is 200 (meaning OK), json_encode the result. If it is anything else, responde to it according to the linkes HTTP Error Code list.

I refer to the comment-question of Vikas Prasad: "#ReeCube can I achieve all my requirements for the program trying JSON or XML. If yes can you point me to specific tutorials. I have no idea about these two. Also which one to prefer among both?"
JSON or XML are just the way how you transfer the data and how you read them after, you need php and c# to use JSON or XML. I prefer JSON but im not sure how well it's working on C#, I've never tested it.
Here you can find an JSON API for C#.
But first you should add JSON for your PHP-server. On PHP, JSON is very easy to use, there is an json_encode and json_decode function. In your case, you just need the json_encode function, because on the server side, you just want to generate the JSON for the client. How to use json_encode is very well supported by Google and the PHP documentation, but if you have questions, just ask in a comment.
Here is a little example:
<?php
$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
echo json_encode($arr);
?>

Related

UnityWebRequest.Post to send a task to ClickUp's API, encoding JSON improperly

So I'm writing a program in Unity that sends tasks to a ClickUp list. I've been able to send the request through Postman for testing properly, but whenever I try to send that request through Unity I get an error with the Json encoding:
{"err":"Unexpected token % in JSON at position 0","ECODE":"JSON_001"}
The code for the method is as follows. It's just a very basic tester method, so I know it's a little messy as is, but once I'm able to actually send the requests properly I want I'll re-write it with the full functionality.
private void SendDemoTask()
{
string jsonString = "{\"name\": \"Unity send from postman\",\"description\": \"Sent on May 24 2022\"}";
UnityWebRequest demoTaskRequest =
UnityWebRequest.Post($"https://api.clickup.com/api/v2/list/{listID}/task",jsonString);
demoTaskRequest.SetRequestHeader("Authorization",accessToken);
demoTaskRequest.SetRequestHeader("Content-Type","application/json");
var operation = demoTaskRequest.SendWebRequest();
// Wait for request to return
while (!operation.isDone)
{
CheckWebRequestStatus("Task creation failed.", demoTaskRequest);
}
Debug.Log(demoTaskRequest.result);
Debug.Log(demoTaskRequest.downloadHandler.text);
}
It seems to be an issue with the JSON encoding. Unfortunately the POST method doesn't have an argument to take a byte array. The PUT method does, but ClickUp's API won't accept the same types of requests through Put.
Is there a way for me to send this request that will correct the encoding issue? Or is the problem somewhere else?
Apologies if any part of this isn't clear. I'm fairly new to using UnityWebRequest and a total noob to webdev in general.
Thank you for any help you all can offer, I very much appreciate it!

Autodesk Forge Error trying to access the API online

I have a problem loading a 3D model on an online server, the error shown is related to accessing the Forge API, locally works smoothly however when mounted on the server or a website is made marks the following error "Failed to load resource: the server responded with a status of 404 (Not Found)", then "onDocumentLoadFailure() - errorCode:7".
As I comment, what I find stranger is that, locally, it works. Attached the segment of the code where it displays the error.
function getAccessToken() {
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", '/api/forge/toke', false); //Address not found
xmlHttp.send(null);
return xmlHttp.responseText;
}
Thank you very much in advance.
Are you sure the code you're running locally and the code you've deployed are really the same?
The getAccessToken function doesn't seem to be correct, for several reasons:
First of all, there seems to be a typo in the URL - shouldn't it be /api/forge/token instead of /api/forge/toke?
More importantly, the HTTP request is asynchronous, meaning that it cannot return the response immediately after calling xmlHttp.send(). You can find more details about the usage of XMLHttpRequest in https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest.
And finally, assuming that the function is passed to Autodesk.Viewing.Initializer options, it should return the token using a callback parameter passed to it (as shown in https://forge.autodesk.com/en/docs/viewer/v7/developers_guide/viewer_basics/initialization/#example).
With that, your getAccessToken should probably look more like this (using the more modern fetch and async/await):
async function getAccessToken(callback) {
const resp = await fetch('/api/forge/token');
const json = await resp.json();
callback(json.access_token, json.expires_in);
}
I've already found the issue. When I make the deploy I have to change the url where the request is made for the public or the name of the domain. For example: mywebsite.com/aplication-name/api/forge/token.

Get XML body of a 400 or 500 HTTP XML response

Long story short, I am sending an XML HTTP post request to an application server, and I am getting back a response, also in the form of XML HTTP.
I have a test site available to me which allows me to see what the server's actual response is, visually, in the form of XML, but I cannot access this XML from my C# code the way it is.
The XML coming back from the application server in my test case looks like this:
<Error><Message>StringErrorMessage</Message></Error>
However, I have had no luck accessing this basic XML to retrieve the value of "StringErrorMessage" for the creation of a detailed error report.
... More code above, all wrapped in a try{}...
_response = Serializer.DeserializeObject<T>(ObjectRequest.GetResponse().GetResponseStream());
}
catch (System.Net.WebException exceptionParameter)
{
var response = (HttpWebResponse)exceptionParameter.Response;
string webExceptionStatus = exceptionParameter.Message;
_exception = exceptionParameter;
return false;
}
I have consulted
C# - Getting the response body from a 403 error
and
Get response body on 400 HTTP response in Android?
The first link's solution doesn't seem to give me access to the basic XML as part of any response object's properties. I am almost positive that there must be a byte[] in there somewhere (in the response, or in the exception object) that can be converted into a char[], which can be converted to a string, which can be converted to my XML body, but I have not been able to find it. The second link's solution is not exactly viable for me because I have to get the response body back in the form of XML, as it might not be an error, but an object that must be deserialized. This particular side of things, I cannot change.
Any advice would be very much appreciated.
- Eli
EDIT: Just wanted to clarify that my basic code is working okay for non-error situations, and is deserializing the XML just fine. It's when my code encounters a HTTP 400 or an HTTP 500 error, where accessing the XML from the catch statement becomes a problem, because my code immediately throws an exception.
The body of a HTTP message (the XML in your case) can be retrieved with the GetResponseStream method of the HttpWebResponse object you have. And, since it's a stream, you can for instance read it with a StreamReader, like so:
HttpWebResponse myWebResponse; // Get this from whereever you want
Stream responseStream = myWebResponse.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string niceStringForYou = reader.ReadToEnd();
...and from that point on, you can do whatever to it.
If you're absolutely sure it's always gonna be XML you get back from the service, you can probably even use an XmlReader to get XML directly from the stream:
XmlReader foo = XmlReader.Create(responseStream);
Comment to edit: As long as you have the HttpWebResponse object, reading it's response stream (GetResponseStream()) should work. And as you point out in your own code, you can get the HttpWebResponse by looking at (HttpWebResponse)exceptionParameter.Response.

How to read returned xml value from google maps

I am trying to call google maps geocode and am following the example on their webpage to try and apply it to mine
http://code.google.com/apis/maps/documentation/geocoding/index.html
in this example, the Geocoding API requests an xml response for the
identical query shown above for "1600 Amphitheatre Parkway, Mountain
View, CA":
http://maps.googleapis.com/maps/api/geocode/xml?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true_or_false
The XML returned by this request is shown below.
Now i am trying to run that url like this in my c# winforms application
string url = "http://maps.googleapis.com/maps/api/geocode/xml?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true_or_false";
WebRequest req = HttpWebRequest.Create(url);
WebResponse res = req.GetResponse();
StreamReader sr = new StreamReader(res.GetResponseStream());
try
{
Match coord = Regex.Match(sr.ReadToEnd(), "<coordinates>.*</coordinates>");
var b = coord.Value.Substring(13, coord.Length - 27);
}
finally
{
sr.Close();
}
However it doesnt seem to be returning anything and as such my var b line gives an index out of bounds error. Can anyone point me in the right direction for at least getting the example to work so i can apply the logic to my own application?
Thanks
If you visit your link "http://maps.googleapis.com/maps/api/geocode/xml?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true_or_false" directly in a browser you can see what it's returning. It's giving me a REQUEST DENIED error.
The problem is caused by the sensor=true_or_false parameter. You have to choose if you want it to be true or false. Google put it this way in their example so that you have to explicitly decide for yourself. This setting indicates if your application is using a location sensor or not. In your case, I'm guessing not, so set it to false.
If you change the link you're using to http://maps.googleapis.com/maps/api/geocode/xml?address=1600%20Amphitheatre%20Parkway,%20Mountain%20View,%20CA&sensor=false, I think you'll get the results you were expecting.

best practice for c# calling php which then queries the database

For some reason I have to have a windows client application (written in C#) which communicates with the PHP files that are on my server. Windows application can't be allowed to have SQL queries in the code because of the possible disassembling of the exe file. This is the main reason why this approach is used.
Basically it looks like this: from windows client i call getResult.php which then opens the connection to the database, queries the database, returns the result to the client and closes the database connection. Therefore windows client doesn't have any code for querying the database, it just has calls to the PHP file.
My several questions follow:
1. What is the best way to send request from c# code to the PHP file? (Cause I need to send this php file some parameters like ID, etc... -> I know I can do it with GET like this getResult.php?id=123456, but is this same possible with POST? And also, one question: how to do this in code? http requests or?)
2.Since every time I call the PHP file (there will be more files which I will call, like getResult.php, getStatus.php, etc...) I will somehow need to send login information to that PHP file with which that PHP will query the database. My question here is how to do this securely, and plus: is it maybe somehow possible to call something like doLogin.php and send the login username and password one time, and after that call this (and all other) php files without the need to send the login information as a parameter to the function. I know I can use PHP sessions when the whole application is on the server, but the main difference here is that I am only calling some files, executing them and closing the connection.
My main question is: is this ok from conceptual point of view or are there any commonly known concepts for this, for which I don't know about - please advise I'm willing to learn. I did some research and do believe this might have to be done with web services approach, but please do reply your thoughts on this.
Thank you for your help!
Your PHP code is effectively serving as a RESTful data-access API. Run your PHP on a webserver over SSL (HTTPS) so that all your comms are encrypted.
You could either use trusted certificates to authenticate the client, or if you require different access levels, submitting a username/password to get an authorisation token for the data-access requests is not a bad idea.
For a simple GET you can do:
var webClient = new WebClient();
webClient.DownloadString("http://someurl.com/somescript.php");
You could then return perhaps an XML or JSON formatted response from the PHP script?
You can use WebClient for POST too.
As for the login, you can do that too. I do a similar thing in one of my applications.
We send the login details to the script (ASP.NET not PHP) and the ASP page returns an XML response telling the C# app whether or not it was successful - the application can then decide whether it is allowed to continue or not.
What you're looking for is REST. Your PHP files are acting as a web service in this circumstance, and you can use RESTful guidelines to determine the best practices for your scenario.
You have to encrypt data between C# app and PHP. Why? For security. You can easly store encrypted data in MySQL.
Insert into table (myname, mysurename)
values
(AES_ENCRYPT('Voon',pass),AES_ENCRYPT('Voon',pass))
C# work.
HttpWebRequest myRequest =
(HttpWebRequest)WebRequest.Create(URL);
myRequest.Method = "GET";
WebResponse myResponse = myRequest.GetResponse();
StreamReader sr = new StreamReader(myResponse.GetResponseStream(),
System.Text.Encoding.UTF8);
string result = sr.ReadToEnd();
//Console.WriteLine(result);
result = result.Replace('\n', ' ');
sr.Close();
myResponse.Close();
Php code:
<?php
function connection() {
$mysql_server = "";
$mysql_admin = "";
$mysql_pass = "t";
$mysql_db = "";
#mysql_connect($mysql_server, $mysql_admin, $mysql_pass)
or die('Brak połączenia z serwerem MySQL.');
// łączymy się z bazą danych
#mysql_select_db($mysql_db)
or die('Błąd wyboru bazy danych.');
}
connection();
$data = mysql_query("SELECT QUERY")
or die(mysql_error());
mysql_query("TRUNCATE TABLE `table`") or die(mysql_error());
while($info = mysql_fetch_array( $data ))
{
$stringData = $info['columnname'] . ",";
$temp = $stringData;
$stringData =$info['columnname'];
$temp = "$temp" . "$stringData";
echo "$temp" . ".";
}
}
?>
This code. Calls php and getresult (column.column, next column.column) in C#. After sending data it recreate table.
Hope it works for you.
EDIT!
For calling link with parameters use this:
in PHP
$myname = $_REQUEST['myname'];
eg. http://mylink/setname.php?myname=VoonArt
PHP stored in variable VoonArt
2) Use https to send important data. Also encrypt it. Use same encryption in C# and PHP (triple-des)
C#-->Encode Pass-->Hey PHP can you get me some data my password is &283&(^#(08218--> Okay, C# I'll decode your password and send you result!-->PHP decode password --> PHP getdata -->php encode data with (eg. triple-des) --> Hey C# catch, you own me a beer huh?

Categories