C# - Safe a Base64 as Gif, when the webRequest sends XML? - c#

I sended a WebRequest, and got as Response a String with XML Code within my content.
WebRequest request = WebRequest.Create("...");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
byte[] bytes = Convert.FromBase64String(responseFromServer);
Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
}
image.Save("File", System.Drawing.Imaging.ImageFormat.Gif);
The Problem is that "Convert.FromBase64String(responseFromServer)" cant convert to base 64, because the response is:
"<string xmlns="*LINK*"> 'content' </string>"
Can I remove these Tags, or copy out the content?
I hope you got my problem:) Thanks for help and sorry for the bad english x)

you can use XmlDocument..
WebRequest request = WebRequest.Create("...");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
XmlDocument doc = new XmlDocument();
doc.Load(reader);
byte[] bytes = Convert.FromBase64String(doc.GetElementsByTagName("string")[0].InnerText);
System.Drawing.Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = System.Drawing.Image.FromStream(ms);
}

I'd recommend using XmlReader for this.
WebRequest request = WebRequest.Create("...");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream dataStream = response.GetResponseStream();
//StreamReader reader = new StreamReader(dataStream);
//string responseFromServer = reader.ReadToEnd();
//byte[] bytes = Convert.FromBase64String(responseFromServer);
using (var reader = XmlReader.Create(dataStream))
{
reader.Read();
reader.Read();
string base64 = reader.Value;
byte[] bytes = Convert.FromBase64String(base64);
Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
image.Save("File", System.Drawing.Imaging.ImageFormat.Gif);
}
}
There is a method for converting from Base64 in the element value directly, but you'd need to know things that more or less require you to read your whole stream anyway to do that (you can look at the edit history to see me working through that ;).

Related

Problems uploading a binary serialized file

The idea of my program is to allow the user to save his data in a cloud. The data is stored in binary serialized files.
Serialization Code looks like so:
FileStream Stream = new FileStream(..., FileMode.Create); // create stream
BinaryFormatter Formatter = new BinaryFormatter(); // create formatter
Formatter.Serialize(Stream, ObjectToSerialize); // serialize
Stream.Close();
The Problem is that when I upload the serialized file, with the following code:
FtpWebRequest Request = (FtpWebRequest)WebRequest.Create(new Uri(...));
Request.Method = WebRequestMethods.Ftp.UploadFile;
Request.Credentials = new NetworkCredential(..., ...);
string Path = System.IO.Path.GetDirectoryName(...;
StreamReader SourceStream = new StreamReader(Path);
Request.UseBinary = true;
byte[] FileContents = Encoding.Default.GetBytes(SourceStream.ReadToEnd());
SourceStream.Close();
Request.ContentLength = FileContents.Length;
Stream RequestStream = Request.GetRequestStream();
RequestStream.Write(FileContents, 0, FileContents.Length);
RequestStream.Close();
FtpWebResponse Response = (FtpWebResponse)Request.GetResponse();
Response.Close();
the file encoding changes (I am not sure about that.. if the encoding is the problem but I think so) and I am not able to deserialize the file anymore, exceptions occure. Do you have a idea how to do not damage the file?
Best Regards!
Encoding only applies to text, and you're dealing with a binary file here. You should not attempt to read it as a string. The "encoding changed" because you are using Encoding.Default which depends on the current configuration of your operating system.
Just change the code to:
string Path = System.IO.Path.GetDirectoryName(...);
// StreamReader SourceStream = new StreamReader(Path);
// Request.UseBinary = true;
byte[] FileContents = File.ReadAllBytes(Path);
// SourceStream.Close();
if you want to read an entire binary file in memory.

Uploading files in dedicated server with asp.net

I upload files and convert it into bytes and saved it in Database. It works correctly in my local system. but I hosted it in dedicated server, it cannot convert path into bytes. It shows an error
'Could not find a part of the path 'C:\fakepath\1003.pdf'.
Code:
//byte[] bContent = myWebClient.DownloadData(#strFileUploadSubSplit[3]);
byte[] bContent = null;
// Open file for reading
System.IO.FileStream _FileStream = new System.IO.FileStream(strFileUploadSubSplit[3].ToString(), System.IO.FileMode.Open, System.IO.FileAccess.Read);
// attach filestream to binary reader
System.IO.BinaryReader _BinaryReader = new System.IO.BinaryReader(_FileStream);
// get total byte length of the file
long _TotalBytes = new System.IO.FileInfo(strFileUploadSubSplit[3].ToString()).Length;
// read entire file into buffer
bContent = _BinaryReader.ReadBytes((Int32)_TotalBytes);
// close file reader
_FileStream.Close();
_FileStream.Dispose();
_BinaryReader.Close();
string base64String = System.Convert.ToBase64String(bContent, 0, bContent.Length);
str = strFileUploadSubSplit[0] + "*" + strFileUploadSubSplit[1] + "*" + strFileUploadSubSplit[2] + "*" + base64String ;
string URL = "http://dev2.weicorp.com:81/IApp.svc/IApp/Doc";
string ret = string.Empty;
var webRequest = System.Net.WebRequest.Create(URL) as HttpWebRequest;
byte[] byteArray = Encoding.UTF8.GetBytes(str);
webRequest.Method = "POST";
webRequest.ContentType = "application/octet-stream";
webRequest.ContentLength = byteArray.Length;
Stream dataStream = webRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
HttpWebResponse resp = (HttpWebResponse)webRequest.GetResponse();
dataStream = resp.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
ret = reader.ReadToEnd();
string status = ret.ToString();
context.Response.Write(status);
You have to extract the filename only from the uploaded file:
string file = Path.GetFileName(uploadedFile.FileName);
The fakepath that you are seeing is because for security reasons web browsers do not send the actual path to the uploaded file on the client.

using http response how to save the pdf files

I've written following code to get the content from a web page and save to the system.
if the webpage is in html format i'm able to save it.
if the web page is in pdf format i'm unable to save it. After saving if i opend the file blank pages are coming.
I want to know How to save the pdf files from the response.
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Url);
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
webContent = reader.ReadToEnd();
StreamWriter sw = new StreamWriter(FileName);
sw.WriteLine(webContent);
sw.Close();
Please help me ASAP.
StreamReader.ReadToEnd() returns a string. PDF files are binary, and contain data that is not string-friendly. You need to read it into a byte array, and write the byte array to disk. Even better, use a smaller byte array as a buffer and read in small chunks.
You can also simplify the whole thing by just using webclient:
using (var wc = new System.Net.WebClient())
{
wc.DownloadFile(Url, FileName);
}
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Url);
WebResponse response = request.GetResponse();
using (Stream stream = response.GetResponseStream())
using (FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
stream.BlockCopy(fs);
}
...
public static class StreamHelper
{
public static void Copy(Stream source, Stream target, int blockSize)
{
int read;
byte[] buffer = new byte[blockSize];
while ((read = source.Read(buffer, 0, blockSize)) > 0)
{
target.Write(buffer, 0, read);
}
}
public static void BlockCopy(this Stream source, Stream target, int blockSize = 65536)
{
Copy(source, target, blockSize);
}
}

How to compress a HttpWebRequest POST

I am trying to post data to server that accepts compressed data. The code below works just fine, but it is uncompressed. I have not worked with compression or Gzip beofre, so any help is appriciated.
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
request.Timeout = 600000;
request.Method = verb; // POST
request.Accept = "text/xml";
if (!string.IsNullOrEmpty(data))
{
request.ContentType = "text/xml";
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data);
request.ContentLength = byteData.Length;
// Here is where I need to compress the above byte array using GZipStream
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
}
XmlDocument xmlDoc = new XmlDocument();
HttpWebResponse response = null;
StreamReader reader = null;
try
{
response = request.GetResponse() as HttpWebResponse;
reader = new StreamReader(response.GetResponseStream());
xmlDoc.LoadXml(reader.ReadToEnd());
}
Do I gzip the entire byte array? Do I need to add other headers or remove the one that is already there?
Thanks!
-Scott
To answer the question you asked, to POST compressed data, all you need to do is wrap the request stream with a gzip stream
using (Stream postStream = request.GetRequestStream())
{
using(var zipStream = new GZipStream(postStream, CompressionMode.Compress))
{
zipStream.Write(byteData, 0, byteData.Length);
}
}
This is completely different than requesting a gzip response, which is a much more common thing to do.
I also received the "Cannot close stream until all bytes are written" error using code similar to tnyfst's. The problem was that I had:
request.ContentLength = binData.Length;
where binData is my raw data before the compression. Obviously the length of the compressed content would be different, so I just removed this line and ended up with this code:
using (GZipStream zipStream = new GZipStream(request.GetRequestStream(), CompressionMode.Compress))
{
zipStream.Write(binData, 0, binData.Length);
}
In Page_Load event:
Response.AddHeader("Content-Encoding", "gzip");
And for making compressed requests:
HttpWebRequest and GZip Http Responses by Rick Strahl
Try this extension method.
The stream will be left open (see the GZipStream constructor).
The stream position is set to 0 after the compression is done.
public static void GZip(this Stream stream, byte[] data)
{
using (var zipStream = new GZipStream(stream, CompressionMode.Compress, true))
{
zipStream.Write(data, 0, data.Length);
}
stream.Position = 0;
}
You can use the following test:
[Test]
public void Test_gzip_data_is_restored_to_the_original_value()
{
var stream = new MemoryStream();
var data = new byte[]{1,2,3,4,5,6,7,8,9,10};
stream.GZip(data);
var decompressed = new GZipStream(stream, CompressionMode.Decompress);
var data2 = new byte[10];
decompressed.Read(data2,0,10);
Assert.That(data, Is.EqualTo(data2));
}
For more information see: http://msdn.microsoft.com/en-us/library/hh158301(v=vs.110).aspx

Convert to Stream from a Url

I was trying to convert an Url to Stream but I am not sure whether I am right or wrong.
protected Stream GetStream(String gazouUrl)
{
Stream rtn = null;
HttpWebRequest aRequest = (HttpWebRequest)WebRequest.Create(gazouUrl);
HttpWebResponse aResponse = (HttpWebResponse)aRequest.GetResponse();
using (StreamReader sReader = new StreamReader(aResponse.GetResponseStream(), System.Text.Encoding.Default))
{
rtn = sReader.BaseStream;
}
return rtn;
}
Am I on the right track?
I ended up doing a smaller version and using WebClient instead the old Http Request code:
private static Stream GetStreamFromUrl(string url)
{
byte[] imageData = null;
using (var wc = new System.Net.WebClient())
imageData = wc.DownloadData(url);
return new MemoryStream(imageData);
}
You don't need to create a StreamReader there. Just return aResponse.GetResponseStream();. The caller of that method will also need to call Dispose on the stream when it's done.
The current answer is missing an example in how to use GetResponseStream()
Here is an example
// Creates an HttpWebRequest with the specified URL.
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
// Sends the HttpWebRequest and waits for the response.
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
// Gets the stream associated with the response.
Stream receiveStream = myHttpWebResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader( receiveStream, encode );
Console.WriteLine("\r\nResponse stream received.");
Char[] read = new Char[256];
// Reads 256 characters at a time.
int count = readStream.Read( read, 0, 256 );
Console.WriteLine("HTML...\r\n");
while (count > 0)
{
// Dumps the 256 characters on a string and displays the string to the console.
String str = new String(read, 0, count);
Console.Write(str);
count = readStream.Read(read, 0, 256);
}
Console.WriteLine("");
// Releases the resources of the response.
myHttpWebResponse.Close();
// Releases the resources of the Stream.
readStream.Close();
For more details see - https://learn.microsoft.com/en-us/dotnet/api/system.net.httpwebresponse.getresponsestream?view=net-5.0

Categories