I want to send data from c# to php - c#

I want to send a string (data) from C# to PHP but I am unable to receive data in PHP . Here is my C# code
string deviceUrl ="http://localhost/CBIRS/clusteringdata.php";
HttpWebRequest reqDevice = (HttpWebRequest)WebRequest.Create(deviceUrl);
reqDevice.Method = "POST";
string deviceData = "status="+ data;
byte[] postDeviceBytes = Encoding.ASCII.GetBytes(deviceData);
reqDevice.ContentType = "application/x-www-form-urlencoded";
reqDevice.ContentLength = postDeviceBytes.Length;
Stream requestDeviceStream = reqDevice.GetRequestStream();
requestDeviceStream.Write(postDeviceBytes, 0, postDeviceBytes.Length);
requestDeviceStream.Close();
and my PHP code is as follows.
if(isset($_POST['status']))
{
$tempdata=explode('$',$_POST['status']);
var_dump($tempdata);
}
else
{
echo "Data not recieved";
}
after running C# application when I run PHP file it always goes to else part. How can I correct it?

You aren't encoding the POST data. When you send POST data, the values must be URL encoded. I suspect there is a special character in data that is causing PHP to fail to parse the POST data.
To encode the value:
string deviceData = "status="+ HttpUtility.UrlEncode(data);

Note that the $tempdata variable is never used in your PHP.
Have you tried to display the response of your request in your C# program ? Add another echo "hello"; out of your condition to see if the connection works.

Related

reading a web api blob into a string that I can send as part of a json object to the server and turn back into a file

i'm trying to turn a wav file into a string I can send to the server as a part of a json object, so that on the server I can turn that string back into a file.
i have tried to use readAsBinaryString and read as text, can't get past error in reading the string into a byte array.
reader.onloadend = saveMedia;
reader.readAsText(Blob);
//reader.readAsBinaryString(Blob); also tried.
then the callback sends an ajax request with an object holding the string in "reader.result" and on the server i tried things like:
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] BinaryData = encoding.GetBytes(stringFromRequest);
the answers to this question below seem to be that this should not be done. but i really want to do it this way because of another tool I am using (breeze js). don't want to use a separate post action with a file data type.
releted:
File API - Blob to JSON
Found a way that works:
var reader = new FileReader();
reader.onloadend = afterRead;
reader.readAsBinaryString(blob);
function afterRead() {
// convert binary string to base64 for a safe transfer to the server.
entity.BinaryProp = window.btoa(reader.result);
}
on the server-side:
string BinaryString = (string)entityInfo.UnmappedValuesMap["BinaryProp"];
byte[] BinaryData = Convert.FromBase64String(BinaryString);
You can use fileReader.readAsDataURL(fileObject), this encode blob to base64, which can safely upload to server by API.
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
let thumbnail = reader.result;
console.log(thumbnail)
//send to API
};
The answer above is great, but there is a simpler way.
var reader = new FileReader();
reader.onloadend = afterRead;
reader.readAsDataURL(blob); // Use this function instead
function afterRead() {
entity.BinaryProp = reader.result; //result is already a base64 string!
}
See documentation here: FileReader.readAsDataURL()

How to read string from HttpRequest form data in correct encoding

Today I have done a service to receive emails from SendGrid and finally have sent an email with a text "At long last", first time in non-English language during testing. Unfortunately, the encoding has become a problem that I cannot fix.
In a ServiceStack service I have a string property (in an input object that is posted to the service from SendGrid) in an encoding that is different from UTF8 or Unicode (KOI8-R in my case).
public class SengGridEmail : IReturn<SengGridEmailResponse>
{
public string Text { get; set; }
}
When I try to convert this string to UTF8 I get ????s, probably because when I access the Text property it is already converted into Unicode (.NET's internal string representation). This question and answer illustrate the issue.
My question is how to get original KOI8-R bytes within ServiceStack service or ASP.NEt MVC controller, so that I could convert it to UTF8 text?
Update:
Accessing base.Request.FormData["text"] doesn't help
var originalEncoding = Encoding.GetEncoding("KOI8-R");
var originalBytes = originalEncoding.GetBytes(base.Request.FormData["text"]);
But if I take base64 string from the original sent mail and convert it to byte[], and then convert those bytes to UTF8 string - it works. Either base.Request.FormData["text"] is already in Unicode .NET string format, or (less likely) it is something on SendGrid side.
Update 2:
Here is a unit test that shows what is happening:
[Test]
public void EncodingTest()
{
const string originalString = "наконец-то\r\n";
const string base64Koi = "zsHLz87Fwy3Uzw0K";
const string charset = "KOI8-R";
var originalBytes = base64Koi.FromBase64String(); // KOI bytes
var originalEncoding = Encoding.GetEncoding(charset); // KOI Encoding
var originalText = originalEncoding.GetString(originalBytes); // this is initial string correctly converted to .NET representation
Assert.AreEqual(originalString, originalText);
var unicodeEncoding = Encoding.UTF8;
var originalWrongString = unicodeEncoding.GetString(originalBytes); // this is how the KOI string is represented in .NET, equals to base.Request.FormData["text"]
var originalWrongBytes = originalEncoding.GetBytes(originalWrongString);
var unicodeBytes = Encoding.Convert(originalEncoding, unicodeEncoding, originalBytes);
var result = unicodeEncoding.GetString(unicodeBytes);
var unicodeWrongBytes = Encoding.Convert(originalEncoding, unicodeEncoding, originalWrongBytes);
var wrongResult = unicodeEncoding.GetString(unicodeWrongBytes); // this is what I see in DB
Assert.AreEqual(originalString, result);
Assert.AreEqual(originalString, wrongResult); // I want this to pass!
}
Discovered two underlying problems for my problem.
The first is from SendGrid - they post multi-part data without specifying content-type for non-unicode elements.
The second is from ServiceStack - currently it doesn't support encoding other than utf-8 for multi-part data.
Update:
SendGrid helpdesk promised to look into the issue, ServiceStack now fully support custom charsets in multi-part data.
As for initial question itself, one could access buffered stream in ServiceStack as described here: Can ServiceStack Runner Get Request Body?.

Retrieve POST data sent from a C# application in PHP

Having stumbled upon a problem when doing this, I first searched SO to try and find if others were having similar problems, and found this question: POST data to a PHP page from C# WinForm
However, when I tried the code example given in the answer to this question, it does not work. The PHP script that I am making a request to responds with a message indicating that the POST variable that has to be set is not set. Here's my C# code:
HttpWebRequest POSTreq =
(HttpWebRequest)WebRequest.Create("http://82.41.255.140/api/post-ptr");
string POSTdata = "action=" + HttpUtility.UrlEncode("date");
byte[] data = Encoding.ASCII.GetBytes(POSTdata);
POSTreq.Method = "POST";
POSTreq.ContentType = "application/x-www-form-urlencoded";
POSTreq.ContentLength = data.LongLength;
POSTreq.GetRequestStream().Write(data, 0, data.Length);
HttpWebResponse POSTres = (HttpWebResponse)POSTreq.GetResponse();
Console.WriteLine("HTTP Status Code {0}", POSTres.StatusCode);
Console.WriteLine("Response Method: {0}", POSTres.Method);
Console.WriteLine("Response Text: {0}",
new StreamReader(POSTres.GetResponseStream()).ReadToEnd());
Console.ReadLine();
And this is the code inside the PHP script:
<?php
$A = strtolower($_POST["action"]);
if ($A == "date")
{
echo date("c");
}
else if ($A == "ip")
{
echo $_SERVER["REMOTE_ADDR"];
}
else if ($A == null || $A == "")
{
echo "bad_request:no_argument:POST_action";
}
else
{
echo "bad_request:invalid_argument:POST_action";
}
exit();
?>
When I make the POST request from my C# program, I see the following screen, indicating that the variable action has not been set. Am I missing the obvious in my code?
Thanks to those who reply.
You might need to flush the stream. I usually do it like this:
string POSTdata = "action=" + HttpUtility.UrlEncode("date");
byte[] data = Encoding.ASCII.GetBytes(POSTdata);
POSTreq.Method = "POST";
POSTreq.ContentType = "application/x-www-form-urlencoded";
POSTreq.ContentLength = data.LongLength;
using (Stream stream = POSTreq.GetRequestStream()) {
stream.Write(data, 0, data.Length);
stream.Flush();
}
You're not closing the request stream. See this example in the MSDN docs, which is very close to your code.
EDIT
Your PHP null check is incorrect also. See this article.
I've found the problem.
It turns out I'd left off the trailing / in the request, and the request was getting 301'd, which for whatever reason removed the post variables.
So http://82.41.255.140/api/post-ptr should have been http://82.41.255.140/api/post-ptr/.
Thanks to everyone who answered, I've +1'd you all.

Incorrect encoding and decoding in C#

I am trying to upload a base64 encoded string from my mobile phone app (which is written in C#). The string represents an image that needs to be uploaded to my server, which is also written in C#. My client-side code looks like the following:
Client Side Code
----------------
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("username", GetUserName());
parameters.Add("imageBytes", Convert.ToBase64String(this.ImageBytes));
string data = string.Empty;
foreach (string key in parameters.Keys)
{
data += key;
data += "=";
data += parameters[key];
data += "&";
}
data = data.Substring(0, data.Length - 1);
uploadWebRequest = (HttpWebRequest)(ar.AsyncState);
using (Stream postStream = uploadWebRequest.EndGetRequestStream(ar))
{
byte[] byteArray = Encoding.UTF8.GetBytes(data); // I believe this has something to do with it. But I believe this is correct. So I think something needs to be done on the server
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Flush();
postStream.Close();
}
uploadWebRequest.BeginGetResponse(new AsyncCallback(Upload_Completed), uploadWebRequest);
when I print out Convert.ToBase64String(this.ImageBytes) in the Watch Window, I receive the following:
Encoded Client String
---------------------
/9j/4AAQSkZJRgABAQEAYABgAAD/4QC4RXhpZgAATU0AKgAAAAgABAESAAMAAAABAAYAAAExAAIAAAAVAAAAPgE7AAIAAAATAAAAVIdpAAQAAAABAAAAaAAAAABXaW5kb3dzIHBob25lIE9TIDcuMAAASGVsbG8gZnJvbSBTZWF0dGxlAAAAApADAAIAAAAUAAAAhpAEAAIAAAAUAAAAmgAAAAAyMDEwOjAxOjAxIDAwOjAwOjAwADIwMTA6MDE6MDEgMDA6MDA6MDAAAAD/4QsnaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49J++7vycgaWQ9J1c1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCc/Pg0KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iSW1hZ2U6OkV4aWZUb29sIDguMDMiPg0KCTxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+DQoJCTxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4NCgkJCTxleGlmOkRhdGVUaW1lRGlnaXRpemVkPjIwMTAtMDEtMDFUMDA6MDA6MDA8L2V4aWY6RGF0ZVRpbWVEaWdpdGl6ZWQ+DQoJCTwvcmRmOkRlc2NyaXB0aW9uPg0KCTwvcmRmOlJERj4NCjwveDp4bXBtZXRhPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3hwYWNrZXQgZW5kPSd3Jz8+/9sAQwACAQECAQECAgICAgICAgMFAwMDAwMGBAQDBQcGBwcHBgcHCAkLCQgICggHBwoNCgoLDAwMDAcJDg8NDA4LDAwM/9sAQwECAgIDAwMGAwMGDAgHCAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM/8AAEQgJkAzAAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A/fyiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigA
On my server side, I have the following:
Server Side Code
----------------
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddPicture(string username, string imageBytes)
{
WriteToTempFileForDebugging(imageBytes);
byte[] tempBytes = Convert.FromBase64String(imageBytes);
using (MemoryStream memoryStream = new MemoryStream(tempBytes))
{
memoryStream.Position = 0;
System.Drawing.Image image = System.Drawing.Image.FromStream(memoryStream);
image.Save("C:\\inetpub\\wwwroot\\MySite\\Pictures\\myImage.png");
}
}
when this code executes, the Image.FromStream(...) line throws an exception. The error says: System.ArgumentException Parameter is not valid. Because of that, I print the 'imageBytes' string to a temporary file. The contents of that temporary file look exactly the same as the encoded string above, with one exception. All of the spaces (" ") in the encoded string have been replaced with plus signs ("+"). I'm guessing this is some encoding issue. However, I'm not sure how to fix it. I don't want to do a find and replace.
How do I resolve this in the proper manner?
Thank you!
You need to call Uri.EscapeDataString before appending each parameter to the POST string.

Using HttpWebRequest with dynamic URI causes "parameter is not valid" in Image.FromStream

I'm trying to obtain an image to encode to a WordML document. The original version of this function used files, but I needed to change it to get images created on the fly with an aspx page. I've adapted the code to use HttpWebRequest instead of a WebClient. The problem is that I don't think the page request is getting resolved and so the image stream is invalid, generating the error "parameter is not valid" when I invoke Image.FromStream.
public string RenderCitationTableImage(string citation_table_id)
{
string image_content = "";
string _strBaseURL = String.Format("http://{0}",
HttpContext.Current.Request.Url.GetComponents(UriComponents.HostAndPort, UriFormat.Unescaped));
string _strPageURL = String.Format("{0}{1}", _strBaseURL,
ResolveUrl("~/Publication/render_citation_chart.aspx"));
string _staticURL = String.Format("{0}{1}", _strBaseURL,
ResolveUrl("~/Images/table.gif"));
string _fullURL = String.Format("{0}?publication_id={1}&citation_table_layout_id={2}",
_strPageURL, publication_id, citation_table_id);
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_fullURL);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream image_stream = response.GetResponseStream();
// Read the image data
MemoryStream ms = new MemoryStream();
int num_read;
byte[] crlf = System.Text.Encoding.Default.GetBytes("\r\n");
byte[] buffer = new byte[1024];
for (num_read = image_stream.Read(buffer, 0, 1024); num_read > 0; num_read = image_stream.Read(buffer, 0, 1024))
{
ms.Write(buffer, 0, num_read);
}
// Base 64 Encode the image data
byte[] image_bytes = ms.ToArray();
string encodedImage = Convert.ToBase64String(image_bytes);
ms.Position = 0;
System.Drawing.Image image_original = System.Drawing.Image.FromStream(ms); // <---error here: parameter is not valid
image_stream.Close();
image_content = string.Format("<w:p>{4}<w:r><w:pict><w:binData w:name=\"wordml://{0}\">{1}</w:binData>" +
"<v:shape style=\"width:{2}px;height:{3}px\">" +
"<v:imagedata src=\"wordml://{0}\"/>" +
"</v:shape>" +
"</w:pict></w:r></w:p>", _word_image_id, encodedImage, 800, 400, alignment.center);
image_content = "<w:br w:type=\"text-wrapping\"/>" + image_content + "<w:br w:type=\"text-wrapping\"/>";
}
catch (Exception ex)
{
return ex.ToString();
}
return image_content;
Using a static URI it works fine. If I replace "staticURL" with "fullURL" in the WebRequest.Create method I get the error. Any ideas as to why the page request doesn't fully resolve?
And yes, the full URL resolves fine and shows an image if I post it in the address bar.
UPDATE:
Just read your updated question. Since you're running into login issues, try doing this before you execute the request:
request.Credentials = CredentialCache.DefaultCredentials
If this doesn't work, then perhaps the problem is that authentication is not being enforced on static files, but is being enforced on dynamic files. In this case, you'll need to log in first (using your client code) and retain the login cookie (using HttpWebRequest.CookieContainer on the login request as well as on the second request) or turn off authentication on the page you're trying to access.
ORIGINAL:
Since it works with one HTTP URL and doesn't work with another, the place to start diagnosing this is figuring out what's different between the two requests, at the HTTP level, which accounts for the difference in behavior in your code.
To figure out the difference, I'd use Fiddler (http://fiddlertool.com) to compare the two requests. Compare the HTTP headers. Are they the same? In particular, are they the same HTTP content type? If not, that's likely the source of your problem.
If headers are the same, make sure both the static and dynamic image are exactly the same content and file type on the server. (e.g. use File...Save As to save the image in a browser to your disk). Then use Fiddler's Hex View to compare the image content. Can you see any obvious differences?
Finally, I'm sure you've already checked this, but just making sure: /Publication/render_citation_chart.aspx refers to an actual image file, not an HTML wrapper around an IMG element, right? This would account for the behavior you're seeing, where a browser renders the image OK but your code doesn't.

Categories