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

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?

Related

UnityWebRequest(path, UnityWebRequest.kHttpVerbGET): how add a variable to the request to retrieve a specific mysql row?

I currently retrieve all data from db with my sql query below by sending request to server's php file.
I need to post to the php file a variable as criteria for this mysql request, e.g WHERE carName="Somecar" AND slice=3. How can I add the criteria to my request and can I continue to still use the UnityWebRequest.kHttpVerbGET and the ToFileDownloadHandler below?
Current Unity request:
Debug.Log("Retrieving existing data from server.");
UnityWebRequest myWebRequest = new UnityWebRequest(path, UnityWebRequest.kHttpVerbGET);
myWebRequest.downloadHandler = new ToFileDownloadHandler(new byte[64 * 1024], savePathWithFileName);
yield return myWebRequest.SendWebRequest();
And php:
$stmt = $conn->prepare("SELECT id, carName, thisCarImg, i_width, i_heigth, i_depth, b_width, b_heigth, b_depth, f_depth, m_width, m_heigth, i_date, slope, slice, slopeName, sliceName FROM $myTable")
$stmt->execute();
The best I could think is adding php as an additional tag although the question is how to add a form to Unity's query - using the form received in php is a different matter.
you have to add the parameters in path
eg. sample.php?Somecar=122&slice=1
This way you can achieve this unity input in API call to PHP on GET request, if you are using POST then you can use WWWForm class.

German characters sending data using POST method from ASP page to PHP page

I have a problem with sending data from ASP with the POST Method to a PHP page.
I would like to send mail with names. And since I live in Austria the names are in German and we have some Special characters. These characters don't arrive write.
I'm still pretty new to programming with C# btw. I had the Website before in Java-Script but I had to connect it with a database and therefore I switched to C# and now I'm like a "babe in the woods".
this.hdnDaten.Value = "ÄÖÜ|äöü|ß|é|#";
// mit POST versuchen
using (var client = new WebClient())
{
var postData = new System.Collections.Specialized.NameValueCollection();
postData.Add("von", this.hdnVon.Value);
postData.Add("an", this.hdnAn.Value);
postData.Add("betreff", this.hdnBetreff.Value);
postData.Add("daten", this.hdnDaten.Value);
byte[] response = client.UploadValues("http://xxxxxx.php", "POST", postData);
var responsebody = Encoding.UTF8.GetString(response);
}
And this is how the characters (in this.hdnDaten.Value) from above arrive in the mail-body:
ÄÖÜ|äöü|ß|é|#
Does anybody know what I can do to get the same characters in the end?
Edit 20143013: I think I have a clue: I have to encode the postData into ANSI (Codepage 1252). I tried do do this, but it doesn't work. Does anybody have an Idea how I could do this?
Edit 20140320: I don't even dare to give you the answer: I was looking all the time in the wrong place (somewhat like MH370): The problem was with the receiving side of the mail (I was using a POP3-Viewer for testing); when I downloaded the mail to Outlook everything was OK. The funny thing was that this didn't happen in the original (Javascript) Version that's why I was looking at the wrong place.
Thanks
Eddie
Try setting client.Encoding to UTF-8 before calling UploadValues. Also ensure that you read the text as UTF-8 on the server.
Try this.hdnDaten.Value = HttpUtility.UrlEncode("ÄÖÜ|äöü|ß|é|#"); on your post parameters.
on PHP you'll need to decode the parameters via html_entity_decode

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

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);
?>

Using WHMCS API with a C# .NET Application

I just started taking a class on C# .NET and have found it really fascinating how simple it is. I have been using C++ for years, so the simplistic nature is actually hitting me as somewhat confusing.
I would like to do something along these lines...
http://wiki.whmcs.com/API:Example_Usage
Would it be easy to do this from a C# .NET application, or would I still be in about the same boat as C++ (build libcurl, grab a bunch of other libs, etc)?
You could create and instance of WebClient thus:
// Instantiate the WebClient object
WebClient WHMCSclient = new WebClient();
// Prepare a Name/Value collection to hold the post values
NameValueCollection form = new NameValueCollection();
form.Add("username", username);
form.Add("password", password); // the password will still need encoding is MD5 is a requirement
form.Add("action", "addinvoicepayment"); // action performed by the API:Functions
form.Add("invoiceid", "1");
form.Add("transid", "TEST");
form.Add("gateway", "mailin");
// Post the data and read the response
Byte[] responseData = WHMCSclient.UploadValues("http://www.yourdomain.com/whmcs/includes/api.php", form);
// Decode and display the response.
Console.WriteLine("\nResponse received was \n{0}",Encoding.ASCII.GetString(responseData));
I've not had a chance to test that but this snippet should at least have you working along the right lines.

Server side include external HTML?

In my asp.net-mvc application I need to include a page that shows a legacy page.
The body of this page is created by calling an existing Perl script.
This Perl script is externally hosted.
Is there a way to do something like this:
<!-- #Include virtual="http://www.example.com/theScript.plx"-->
Not as a direct include, because ASP.NET server-side-includes require the page to be compiled at the server.
You could use jQuery to download the HTML from that URL when the page loads, though I appreciate that's not perfect.
Alternatively (and I have no idea whether this will work) you could perform a WebRequest to the perl webpage from your ASP.NET MVC controller, and put the resulting HTML in the view as text. That way you could make use of things like output caching to limit the hits to the perl page if it doesn't change often.
If you wanted to do it all in one go, you could do an HTTP Request from the server and write the contents to the page?
Something like this:
Response.Write(GetHtmlPage("http://www.example.com/theScript.plx"));
Calling this method:
public String GetHtmlPage(string strURL)
{
// the html retrieved from the page
String strResult;
WebResponse objResponse;
WebRequest objRequest = System.Net.HttpWebRequest.Create(strURL);
objResponse = objRequest.GetResponse();
// the using keyword will automatically dispose the object
// once complete
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
strResult = sr.ReadToEnd();
// Close and clean up the StreamReader
sr.Close();
}
return strResult;
}
(Most code ripped blatantly from here and therefore not checked)
You could implement this in a low-key fashion by simply using a frame and setting the frame source to the url that needs to be included. This is quite simple and can be down without any server or client side scripting, so that'd be my preferred approach, if possible.
If you want the html to appear to come from your server, however, you'll need to manually include it - typically by using WebRequest as Neil says. You may wish to cache the remote page for performance, though, since it's a perl script, I'll assume the page is dynamic, so this might not be a great idea.

Categories