C# - WebClient.UploadFile isn't receiving POST data - c#

I'm trying to write a tool to batch upload images to my website, but I'm having trouble receiving (or sending) the actual data to the server.
I'll start with some C# code as it should explain what I'm trying to do better that I can articulate:
private bool Upload( string LocalFile, int ItemID, string Description, DateTime Date, string Photographer )
{
WebClient oWeb = new System.Net.WebClient();
NameValueCollection parameters = new NameValueCollection();
parameters.Add( "Type", "1" );
parameters.Add( "ID", ItemID.ToString() );
parameters.Add( "Desc", Description );
parameters.Add( "Date", Date.ToString( "yyyy-MM-dd" ) );
parameters.Add( "Photographer", Photographer );
oWeb.QueryString = parameters;
var responseBytes = oWeb.UploadFile( "http://www.teamdefiant.co.uk/moveuploadedfile.php", LocalFile );
string response = Encoding.ASCII.GetString(responseBytes);
MessageBox.Show( "Response: \n\n" + response + "\n\nPost Data: \n\n" + LocalFile + "\n" + ItemID.ToString() + "\n" + Description + "\n" + Date.ToString("yyyy-MM-dd") + "\n" + Photographer );
Clipboard.SetText( "Response: \n\n" + response + "\n\nPost Data: \n\n" + LocalFile + "\n" + ItemID.ToString() + "\n" + Description + "\n" + Date.ToString("yyyy-MM-dd") + "\n" + Photographer );
return true;
}
When I receive the response, (as displayed in the MessageBox, and Clipboard.SetText) I get the following data:
Response:
Upload:
Type:
Size: 0kb
Stored in:
Post Data:
C:\Users\<MyFolder>\Pictures\Website\ExampleImage.png
4
Picture Description
2014-12-10
Photographer
And for completeness, here's the php code:
<?PHP
if ($_FILES["myfile"]["error"] > 0)
{
echo "Error: " . $_FILES["myfile"]["error"] . "\n";
}
else
{
echo "Upload: " . $_FILES["myfile"]["name"] . "\n";
echo "Type: " . $_FILES["myfile"]["type"] . "\n";
echo "Size: " . ($_FILES["myfile"]["size"] / 1024) . " Kb\n";
echo "Stored in: " . $_FILES["myfile"]["tmp_name"] . " \n";
echo $_POST["Type"] . " \n";
echo $_POST["ID"] . " \n";
echo $_POST["Desc"] . " \n";
echo $_POST["Date"] . " \n";
echo $_POST["Photographer"] . " \n";
}
?>
I've tried searching for answers but haven't been able to find a working solution that I can understand. (I'm still just learning C#.)
I don't get any code errors in Visual Studio, not do I get any POST errors server side, so I'm stumped.
Any and all help is appreciated!
EDIT
I tried visiting the webpage directly and get the same response, so it looks like no data is being sent to the server?? :(

your c# front-end code doesn't have few things
you need to define a content type octet stream
Client.Headers.Add("Content-Type","binary/octet-stream");
you also need to specify POST in your UploadFile
oWeb.UploadFile ("http://www.teamdefiant.co.uk/moveuploadedfile.php","POST", LocalFile);
try this simple code I found on the internet, create a different work branch and give it a try, this is a lot more basic and in a working condition:
the php script:
<?php
$uploaddir = 'upload/'; // Relative Upload Location of data file
if (is_uploaded_file($_FILES['file']['tmp_name'])) {
$uploadfile = $uploaddir . basename($_FILES['file']['name']);
echo "File ". $_FILES['file']['name'] ." uploaded successfully. ";
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully moved. ";
}
else
print_r($_FILES);
}
else {
echo "Upload Failed!!!";
print_r($_FILES);
}
?>
and this is the C# code:
System.Net.WebClient Client = new System.Net.WebClient ();
Client.Headers.Add("Content-Type","binary/octet-stream");
byte[] result = Client.UploadFile ("http://your_server/upload.php","POST","C:\test.jpg");
string s = System.Text.Encoding .UTF8 .GetString (result,0,result.Length );

Related

Using apostrophe in email subject while sent email via gmail api creating an issue

While sent email using below subject which apostrophe replacing with another characters
Actual Subject : We’ll make 100,800 cold calls for you
Mail Shows Subject : We’ll make 100,800 cold calls for you
Issue happens when I'm sent email via api , when sent email from SMTP it's working fine
Please check my api code below
string msg = "From: " + FromName + "<" + From + ">" + " \r\n" +
"To: " + ToName + "<" + To + ">" + " \r\n" +
"BCC: " + BCCEmail + " \r\n" +
"Subject: " + Subject + " \r\n" +
"Message-ID: mID_" + messageID + "\r\n" +
"References: "+encryptMessageID + "\r\n" +
"In-Reply-To: " + encryptMessageID + "\r\n" +
"Content-Type: " + contentType + "; charset=us-ascii\r\n\r\n" + Body;
dynamic objSendMsg = new { raw = commonFunction.Base64UrlEncode(msg) };
if (!string.IsNullOrEmpty(messageThreadID))
objSendMsg = new { raw = commonFunction.Base64UrlEncode(msg), threadId = messageThreadID };
var _objSendMsg = JsonConvert.SerializeObject(objSendMsg);
var strSendMsg = new StringContent(_objSendMsg, UnicodeEncoding.UTF8, "application/json");
When same content i'm applying in body with apostrophe working fine for body
Please check attached screenshot
Email copy
You need to base64_encode of the subject header your sending it as plain text. the API is getting confused.
Subject: " + Convert.ToBase64String(Subject) + " \r\n" +

Value assigned more than once in single assignment

I made script task that's downloading and saving on disk two spreadsheets from Google Drive using file ID and prepared URL address.
This is main() from my C# code, there are no things outside of it:
public void Main()
{
string m_FileId = Dts.Variables["User::varFileId"].Value.ToString();
string m_RemoteUrl = "https://docs.google.com/spreadsheets/d/" + m_FileId + "/export?format=xlsx";
string m_FilePath = null;
WebClient client = new WebClient();
try
{
m_FilePath = Dts.Variables["User::varFilePath"].Value.ToString() + Dts.Variables["User::varFileName"].Value.ToString();
client.DownloadFile(new System.Uri(m_RemoteUrl), m_FilePath);
m_FilePath = "";
m_FileId = Dts.Variables["User::varFileId2"].Value.ToString();
m_RemoteUrl = "https://docs.google.com/spreadsheets/d/" + m_FileId + "/export?format=xlsx";
m_FilePath = Dts.Variables["User::varFilePath"].Value.ToString() + Dts.Variables["User::varFileName2"].Value.ToString();
client.DownloadFile(new System.Uri(m_RemoteUrl), m_FilePath);
}
catch(Exception e)
{
Dts.Events.FireError(0, "FileDownload", e.Message
+ "\r" + e.StackTrace
+ " \rUrl: " + m_RemoteUrl
+ " \rFilePath: " + m_FilePath
+ " \rPath: " + Dts.Variables["User::varFilePath"].Value.ToString()
+ " \rFileName2: " + Dts.Variables["User::varFileName2"].Value.ToString()
, string.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
Dts.TaskResult = (int)ScriptResults.Success;
}
Problem occurs exactly on every second time I run this code and I don't know how to get rid of it. There's just exception in my script task. I'm printing all variables that are used in this code, and as you can see there's something wrong with m_FilePath, it's like multiplied despite of being printed just once.
[FileDownload] Error: An exception occurred during a WebClient request.
at System.Net.WebClient.DownloadFile(Uri address, String fileName)
at ST_84b63d1593dd449886eb2b32dff40b2d.ScriptMain.Main()
Url: https://docs.google.com/spreadsheets/d/----------/export?format=xlsx
FilePath: C:\Google Drive extract\ga_manual_cost_file.xlsxC:\Google Drive extract\ga_manual_cost_file.xlsx
Path: C:\Google Drive extract\ga_manual_cost_file.xlsx
FileName2: ga_manual_cost_file.xlsx
SSIS variables that I'm using are ReadOnly, and are used only in this script task(I tried running only this part of control flow), and their values are as follows:

PHP script not creating and writing a JSON file

I have a PHP script which get it's post data from my C# code. My C# code sends POST data to my PHP script including a base64 string and a filename. With these two pieces of data it should create a JSON file in the folder JSON with the filename and then it should write the decoded base64 string to the file it just created. After this it should save the JSON data to a database. But there's one problem, It doesn't create the JSON file and it saves blank data to my database. Here is what I have so far:
PHP:
<?php
$link = new mysqli($host, $user, $pass, $db);
if($link ->connect_errno)
{
echo 'Database connection wrong<br/>';
}
else
{
if(isset($_POST['filename']) && isset($_POST['b64string']))
{
$jsonstring = base64_decode($_POST['b64string']);
$filename = $_POST['filename'] . '.json';
$create = fopen(__DIR__. "/json/" . $filename, "W+");
fwrite($create, $jsonstring);
$json = fread($create, filesize(__DIR__. "/json/" . $filename));
fclose($create);
$obj = json_decode($json);
$query_opslaan = "INSERT INTO SalesKicker (BedrijfsNaam, ContPers, TelNr, Email, Land, Plaats, POC) VALUES ('". $obj->bedrijfsNaam ."' , '". $obj->ContPers ."', '". $obj->TelNum ."', '". $obj->email ."', '". $obj->Land ."', '". $obj->Plaats ."', '". $obj->PostCode ."')";
mysqli_query($link, $query_opslaan) or die(mysqli_error($query_opslaan));
}
else
{
echo 'ERROR: no data!';
}
}
?>
It get's the data from the following C# script:
if (reqCat == "bvg")
{
json = "{\"bedrijfsNaam\":\"" + bedrijfsNaam + "\"," +
"\"ContPers\":\"" + ContPers + "\"," +
"\"TelNum\":\"" + TelNum + "\"," +
"\"email\":\"" + email + "\"," +
"\"Land\":\"" + Land + "\"," +
"\"Plaats\":\"" + Plaats + "\"," +
"\"PostCode\":\"" + PostCode + "\"}";
var b64bytes = System.Text.Encoding.UTF8.GetBytes(json);
b64encode = System.Convert.ToBase64String(b64bytes);
using (WebClient client = new WebClient())
{
byte[] sendB64 = client.UploadData("http://" + ConfigurationManager.AppSettings["scripturi"].ToString() + "SalesKicker.php", "POST",
System.Text.Encoding.ASCII.GetBytes("b64string=" + b64encode + "&filename=" + dt.bedrijfsNaam));
}
}
This is my folder structure:
public_html (this is where all the PHP stuff is located) -> json (the folder where it should be saved)
I don't really know what to do at the moment so I came here to post my problem. Can someone please help me out and tell me what I'm doing wrong here?
Got it!
You sending 'filename' param in the POST body, but checking it in the GET array. So you don't even go into the your if(){} statement.
You need either change
if(isset($_GET['filename']) && isset($_POST['b64string']))
to
if(isset($_POST['filename']) && isset($_POST['b64string']))
either change in C#
byte[] sendB64 = client.UploadData("http://" + ConfigurationManager.AppSettings["scripturi"].ToString() + "SalesKicker.php", "POST",
System.Text.Encoding.ASCII.GetBytes("b64string=" + b64encode + "&filename=" + dt.bedrijfsNaam));
to
byte[] sendB64 = client.UploadData("http://" + ConfigurationManager.AppSettings["scripturi"].ToString() + "SalesKicker.php?filename=" + dt.bedrijfsNaam, "POST",
System.Text.Encoding.ASCII.GetBytes("b64string=" + b64encode));
I wasn't sure at first but after testing here the solution:
wrong:
$create = fopen(__DIR__. "/json/" . $filename, "W+");
correct:
$create = fopen(__DIR__. "/json/" . $filename, "w+");
It's kind of stupid but capital letters in the mode are not valid. Hope this solves the issue :)
That moment when a C# programmer forgets about the caches. I was a bit clumsy but after searching for the method how to clear a cache in PHP I found it. Behold, the legendary clearstatcache() method. My final working PHP code looks like this:
if(isset($_POST['filename']) && isset($_POST['b64string']))
{
clearstatcache();//the solution to my problem
$jsonstring = base64_decode($_POST['b64string']);
$filename = $_POST['filename'] . '.json';
$create = fopen(__DIR__. "/json/" . $filename, "w+");
fwrite($create, $jsonstring);
$json = fread($create, filesize(__DIR__. "/json/" . $filename));
fclose($create);
$obj = json_decode($json);
$query_opslaan = "INSERT INTO SalesKicker (BedrijfsNaam, ContPers, TelNr, Email, Land, Plaats, POC) VALUES ('". $obj->bedrijfsNaam ."' , '". $obj->ContPers ."', '". $obj->TelNum ."', '". $obj->email ."', '". $obj->Land ."', '". $obj->Plaats ."', '". $obj->PostCode ."')";
mysqli_query($link, $query_opslaan) or die(mysqli_error($query_opslaan));
}

Remove file present on Linux server

Trying to run sudo command with user who has all the priviledges, but something is wrong in my code .
I am trying to remove a file present on the remote server via C# code. It says : The name 'pass' does not exist in the current context.:
My Code :
SshExec sshExec = new SshExec("sj1slm612", "karansha");
sshExec.Password = "pass";
sshExec.Connect();
//Removing config files from sj1slm612 server
string remove_config_file_express = "echo " + "'" + pass + "'" + "| sudo -S -u wtsnqa rm " + "/apps/instances/express_13000/configuration/standalone-full.xml";
string output_express = sshExec.RunCommand(remove_config_file_express);
Console.WriteLine("All config files removed");
Console.ReadLine();
the compiler is indeed correct. you reference a variable called pass which you probably meant to be the string "pass"
string remove_config_file_express = "echo " + "'" + pass + "'" + "| sudo -S -u wtsnqa rm " + "/apps/instances/express_13000/configuration/standalone-full.xml";
Use tamir Library next code.
public static bool BorrarArchivo(string rutaRemota)
{
try
{
SshExec comando = new SshExec(Servidor, Usuario);
comando.Password = Password;
comando.Connect();
string paso = comando.RunCommand("rm " + rutaRemota);
comando.Close();
return true;
}
catch (Exception ex)
{
mErrorSFTP = ex.Message;
return false;
}
}

Output from an Exception class in App_Code

I am trying to see what exception is happening on my dev clients devserver (our servers are fine) and I have an TestException.cs class that handles the most of my exceptions from my sql statement class.
I have a method like so:
StringBuilder errorMessages = new StringBuilder();
for (int i = 0; i < innerException.Errors.Count; i++)
{
errorMessages.Append("Index #" + i + "\n" +
"Message: " + innerException.Errors[i].Message + "\n" +
"LineNumber: " + innerException.Errors[i].LineNumber + "\n" +
"Source: " + innerException.Errors[i].Source + "\n" +
"Procedure: " + innerException.Errors[i].Procedure + "\n");
}
//Console.WriteLine(errorMessages.ToString());
Response.Clear();
Response.Write("FAILURE");
Response.End();
But the Response.XX won't compile and if I use console.writeline when it hits it on the client server, the browser gets a connection lost webpage.
Is there a better way to do this?
You could try using the Trace class. If you link with a tracewriter in web.config pointing to a text file you can generate logging with Trace.WriteLine. Then you would just need the file uploaded to your network for reviewing.

Categories