ASP FileUpload InputStream and System.IO.File.OpenRead - c#

I have an ASP File upload, PostedFile.InputStream, it is giving us the System.IO.Stream. Is this file stream similar to that of getting
System.IO.File.OpenRead("filename");
I have a Rackspace file content saver that gets the input as Stream, it's not getting the correct image displayed when used PostedFile.InputStream.

Normally PostedFile.InputStream and System.IO.Stream are same.
So there is no need of any additional coding for Rackspace.
You can use file.InputStream as the Stream parameter to create the Object of Rackspace cloud files.
Another method which is not required but can test is
byte[] buffer = new byte[file.InputStream.Length];
file.InputStream.Seek(0, SeekOrigin.Begin);
file.InputStream.Read(buffer, 0, Convert.ToInt32(file.InputStream.Length));
Stream stream2 = new MemoryStream(buffer);
You can use this stream also as input for creating object.

This one worked with rackspace cloud , It can upload file from client side to rackspace cloud file. I also used file uploader.
protected void Button1_Click(object sender, EventArgs e)
{
var cloudIdentity = new CloudIdentity() { Username = "Rackspace_user_name", APIKey = "Rackspace_api" };
var cloudFilesProvider = new CloudFilesProvider(cloudIdentity);
byte[] buffer = new byte[FileUpload1.FileBytes.Length];
FileUpload1.FileContent.Seek(0, SeekOrigin.Begin);
FileUpload1.FileContent.Read(buffer, 0, Convert.ToInt32(FileUpload1.FileContent.Length));
Stream stream2 = new MemoryStream(buffer);
try
{
using (FileUpload1.PostedFile.InputStream)
{
cloudFilesProvider.CreateObject("Containers_name", stream2, FileUpload1.FileName); //blockBlob.UploadFromStream(fileASP.PostedFile.InputStream);
}
}
catch (Exception ex)
{
Label1.Text = ex.ToString();
}
}

Related

How to upload the Stream from an HttpContent result to Azure File Storage

I am attempting to download a list of files from urls stored in my database, and then upload them to my Azure FileStorage account. I am successfully downloading the files and can turn them into files on my local storage or convert them to text and upload them. However I lose data when converting something like a pdf to a text and I do not want to have to store the files on the Azure app that this endpoint is hosted on as I do not need to manipulate the files in any way.
I have attempted to upload the files from the Stream I get from the HttpContent object using the UploadFromStream method on the CloudFile. Whenever this command is run I get an InvalidOperationException with the message "Operation is not valid due to the current state of the object."
I've tried converting the original Stream to a MemoryStream as well but this just writes a blank file to the FileStorage account, even if I set the position to the beginning of the MemoryStream. My code is below and if anyone could point out what information I am missing to make this work I would appreciate it.
public DownloadFileResponse DownloadFile(FileLink fileLink)
{
string fileName = string.Format("{0}{1}{2}", fileLink.ExpectedFileName, ".", fileLink.ExpectedFileType);
HttpStatusCode status;
string hash = "";
using (var client = new HttpClient())
{
client.Timeout = TimeSpan.FromSeconds(10); // candidate for .config setting
client.DefaultRequestHeaders.Add("User-Agent", USER_AGENT);
var request = new HttpRequestMessage(HttpMethod.Get, fileLink.ExpectedURL);
var sendTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
var response = sendTask.Result; // not ensuring success here, going to handle error codes without exceptions
status = response.StatusCode;
if (status == HttpStatusCode.OK)
{
var httpStream = response.Content.ReadAsStreamAsync().Result;
fileStorage.WriteFile(fileLink.ExpectedFileType, fileName, httpStream);
hash = HashGenerator.GetMD5HashFromStream(httpStream);
}
}
return new DownloadFileResponse(status, fileName, hash);
}
public void WriteFile(string targetDirectory, string targetFilePath, Stream fileStream)
{
var options = SetOptions();
var newFile = GetTargetCloudFile(targetDirectory, targetFilePath);
newFile.UploadFromStream(fileStream, options: options);
}
public FileRequestOptions SetOptions()
{
FileRequestOptions options = new FileRequestOptions();
options.ServerTimeout = TimeSpan.FromSeconds(10);
options.RetryPolicy = new NoRetry();
return options;
}
public CloudFile GetTargetCloudFile(string targetDirectory, string targetFilePath)
{
if (!shareConnector.share.Exists())
{
throw new Exception("Cannot access Azure File Storage share");
}
CloudFileDirectory rootDirectory = shareConnector.share.GetRootDirectoryReference();
CloudFileDirectory directory = rootDirectory.GetDirectoryReference(targetDirectory);
if (!directory.Exists())
{
throw new Exception("Target Directory does not exist");
}
CloudFile newFile = directory.GetFileReference(targetFilePath);
return newFile;
}
Had the same problem, the only way it worked is by reading the coming stream (in your case it is httpStream in DownloadFile(FileLink fileLink) method) to a byte array and using UploadFromByteArray (byte[] buffer, int index, int count) instead of UploadFromStream
So your WriteFile(FileLink fileLink) method will look like:
public void WriteFile(string targetDirectory, string targetFilePath, Stream fileStream)
{
var options = SetOptions();
var newFile = GetTargetCloudFile(targetDirectory, targetFilePath);
const int bufferLength= 600;
byte[] buffer = new byte[bufferLength];
// Buffer to read from stram This size is just an example
List<byte> byteArrayFile = new List<byte>(); // all your file will be here
int count = 0;
try
{
while ((count = fileStream.Read(buffer, 0, bufferLength)) > 0)
{
byteArrayFile.AddRange(buffer);
}
fileStream.Close();
}
catch (Exception ex)
{
throw; // you need to change this
}
file.UploadFromByteArray(allFile.ToArray(), 0, byteArrayFile.Count);
// Not sure about byteArrayFile.Count.. it should work
}
According to your description and codes, I suggest you could use Steam.CopyTo to copy the stream to the local memoryStream firstly, then upload the MemoryStream to azure file storage.
More details, you could refer to below codes:
I just change the DownloadFile method to test it.
HttpStatusCode status;
using (var client = new HttpClient())
{
client.Timeout = TimeSpan.FromSeconds(10); // candidate for .config setting
// client.DefaultRequestHeaders.Add("User-Agent", USER_AGENT);
//here I use my blob file to test it
var request = new HttpRequestMessage(HttpMethod.Get, "https://xxxxxxxxxx.blob.core.windows.net/media/secondblobtest-eypt.txt");
var sendTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
var response = sendTask.Result; // not ensuring success here, going to handle error codes without exceptions
status = response.StatusCode;
if (status == HttpStatusCode.OK)
{
MemoryStream ms = new MemoryStream();
var httpStream = response.Content.ReadAsStreamAsync().Result;
httpStream.CopyTo(ms);
ms.Position = 0;
WriteFile("aaa", "testaa", ms);
// hash = HashGenerator.GetMD5HashFromStream(httpStream);
}
}
I had a similar problem and got to find out that the UploadFromStream method only works with buffered streams. Nevertheless I was able to successfully upload files to azure storage by using a MemoryStream. I don't think this to be a very good solution as you are using up your memory resources by copying the content of the file stream to memory before handing it to the azure stream. What I have come up with is a way of writing directly to an azure stream by using instead the OpenWriteAsync method to create the stream and then a simple CopyToAsync from the source stream.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse( "YourAzureStorageConnectionString" );
CloudFileClient fileClient = storageAccount.CreateCloudFileClient();
CloudFileShare share = fileClient.GetShareReference( "YourShareName" );
CloudFileDirectory root = share.GetRootDirectoryReference();
CloudFile file = root.GetFileReference( "TheFileName" );
using (CloudFileStream fileWriteStream = await file.OpenWriteAsync( fileMetadata.FileSize, new AccessCondition(),
new FileRequestOptions { StoreFileContentMD5 = true },
new OperationContext() ))
{
await fileContent.CopyToAsync( fileWriteStream, 128 * 1024 );
}

Saving compressed memory stream to filestream , endfile is corrupted

i am using seven.zip.sharp to compress a stream. I then want to after the compression is done, save the data in the memory stream to a filestream. The file being a ".7z" file.
Problem:
The output file is corrupted and i am unable to decompress it manually. Using notepad++ i am also unable to see the header that is normally found in a 7zip file.
Here is the code:
//Memory stream used to store compressed stream
public System.IO.Stream TheStream = new System.IO.MemoryStream();
//Start compress stream
private void button1_Click(object sender, EventArgs e)
{
Thread newThread1 = new Thread(this.COMP_STREAM);
newThread1.Start();
}
//See size of stream on demand
private void button2_Click(object sender, EventArgs e)
{
textBox1.Clear();
textBox1.Text += "-" + TheStream.Length;
}
//To Create file
private void button3_Click(object sender, EventArgs e)
{
byte[] buffer = new byte[1024]; // Change this to whatever you need
using (System.IO.FileStream output = new FileStream(#"F:\Pasta desktop\sss\TESTEmiau.7z", FileMode.Create))
{
int readBytes = 0;
while ((readBytes = TheStream.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, readBytes);
}
output.Close();
}
MessageBox.Show("DONE");
}
//To compress stream
public void COMP_STREAM()
{
SevenZip.SevenZipCompressor.SetLibraryPath(#"C:\Program Files\7-Zip\7z.dll");
var stream = System.IO.File.OpenRead(#"F:\Pasta desktop\sss\lel.exe");
SevenZip.SevenZipCompressor compressor = new SevenZip.SevenZipCompressor();
compressor.CompressionMethod = SevenZip.CompressionMethod.Lzma2;
compressor.CompressionLevel = SevenZip.CompressionLevel.Ultra;
compressor.CompressStream(stream, TheStream); //I know i can just use a FileStream here but i am doing this from testing only.
MessageBox.Show("Done");
}
Please someone alter the question to make it look better. And add better title to if u desire. Thank you.
So you planned to store the compressed stream in a temporary MemoryBuffer, and later write it out to a file. The problem is that the MemoryStream must be reset after the write, so the read operation reads from the beginning. If your output file is of size 0, then I'm pretty sure that this is the problem.
Here is a fix:
// Seek the beginning of the `MemoryStrem` before writing it to a file:
TheStream.Seek(0, SeekOrigin.Begin);
Or you can declare the stream to be a MemoryStream, and use the Position property:
TheStream.Position = 0;

Unable to download audio with MediaLibraryExtensions.SaveSong in windows phone 8

I am trying to download an audio and saving to isolated storage and saving to emulator.
I tried with the following code.
WebClient m_webClient = new WebClient();
m_webClient.OpenReadAsync(fileUri);
m_webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_ImageOpenReadCompleted);
m_webClient.AllowReadStreamBuffering = true;
private static void webClient_ImageOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
var isolatedfile = IsolatedStorageFile.GetUserStoreForApplication();
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(_fileName, System.IO.FileMode.Create, isolatedfile))
{
byte[] buffer = new byte[e.Result.Length];
while (e.Result.Read(buffer, 0, buffer.Length) > 0)
{
stream.Write(buffer, 0, buffer.Length);
}
}
SaveFileMP3(_fileName);
}
private static void SaveFileMP3(string _fileName)
{
MediaLibrary lib = new MediaLibrary();
Uri songUri = new Uri(_fileName, UriKind.RelativeOrAbsolute);
MediaLibraryExtensions.SaveSong(lib, songUri, null, SaveSongOperation.CopyToLibrary);
}
The problem I am facing is, the audio getting saved to the emulator but not with the extension. Suppose the file name "test.MP3", it is saved as "test" and the duration is always 0:0:00 irrespective to the original duration.
I have added Audio capability too in the manifest file.
Following is the screenshot while saving the song, which has many exceptions in it.
Please correct if something is wrong with code. Thanks in advance.
By adding the line of lib.savesong worked perfectly instead of using mediaLibraryExtensions.
private static void SaveFileMP3(string _fileName)
{
MediaLibrary lib = new MediaLibrary();
Uri songUri = new Uri(_fileName, UriKind.RelativeOrAbsolute);
lib.SaveSong(songUri, null, SaveSongOperation.CopyToLibrary);
//MediaLibraryExtensions.SaveSong(lib, songUri, null, SaveSongOperation.CopyToLibrary);
}

uploading a file using WCF in ASP.NET

I have created one WCF service that will upload the file. and after using that service I am trying to upload the file I am able to successfully upload the file but there is some issue with the FILESTREAM class.
The moment i clicked the button to upload the file when i checked by debugging the application i get to know that stream object is null.
I am passing the object of stream class to the WCF method.
But due to some issue that stream object is getting null.
due to that null object of stream class, image which is uploded getting empty in my folder
This is my code that I am using to upload the file
if (FileUpload1.HasFile)
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(FileUpload1.PostedFile.FileName);
FileTransferServiceReference.ITransferService clientUpload = new FileTransferServiceReference.TransferServiceClient("BasicHttpBinding_ITransferService");
FileTransferServiceReference.RemoteFileInfo uploadRequestInfo = new RemoteFileInfo();
string Path = System.IO.Path.GetDirectoryName(FileUpload1.FileName);
using (System.IO.FileStream stream = new System.IO.FileStream(FileUpload1.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
uploadRequestInfo.FileName = FileUpload1.FileName;
uploadRequestInfo.Length = fileInfo.Length;
uploadRequestInfo.FileByteStream = stream;
clientUpload.UploadFile(uploadRequestInfo);
}
}
Code for WCF Service
public RemoteFileInfo DownloadFile(DownloadRequest request)
{
RemoteFileInfo result = new RemoteFileInfo();
try
{
// get some info about the input file
string filePath = System.IO.Path.Combine(#"c:\Uploadfiles", request.FileName);
System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);
// check if exists
if (!fileInfo.Exists) throw new System.IO.FileNotFoundException("File not found", request.FileName);
// open stream
System.IO.FileStream stream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
// return result
result.FileName = request.FileName;
result.Length = fileInfo.Length;
result.FileByteStream = stream;
}
catch (Exception ex)
{
}
return result;
}
public void UploadFile(RemoteFileInfo request)
{
FileStream targetStream = null;
Stream sourceStream = request.FileByteStream;
string uploadFolder = #"C:\upload\";
if (!Directory.Exists(uploadFolder))
{
Directory.CreateDirectory(uploadFolder);
}
string filePath = Path.Combine(uploadFolder, request.FileName);
using (targetStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
const int bufferLen = 65000;
byte[] buffer = new byte[bufferLen];
int count = 0;
while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0)
{
targetStream.Write(buffer, 0, count);
}
targetStream.Close();
sourceStream.Close();
}
}
}
Spot the difference:
string uploadFolder = #"C:\upload\";
...
string filePath = System.IO.Path.Combine(#"c:\Uploadfiles", request.FileName);
As a general tip you might put your upload file path into an external configuration file, so that you can change it when you move your application onto a server where you need to store the data on a different drive or in a specific location.
Also that way you are always calling the same configuration entry so your upload path name is definitely going to be the same everywhere.

Using Dumpyourphoto photo hosting via C#

I am currently trying to make a simple photo upload function that will upload a screenshot that I took. I found this website dumpyourphoto.com but I don't really understand how to do it in C#. Can anyone guide me through this?
Basically all I need is to upload a screenshot photo up to the server and hopefully it will return me a url to that photo. From there on, I will upload this URL up to a OpenShift database that I already set up and upload it as a text and store the link in the database.
Right. Thanks Simon for the question. I realised I didn't put much details up.
So basically I took a screenshot using kinect and this is the function that I am using.
private void btn_ss_Click(object sender, RoutedEventArgs e)
{
// create a png bitmap encoder which knows how to save a .png file
BitmapEncoder encoder = new PngBitmapEncoder();
// create frame from the writable bitmap and add to encoder
encoder.Frames.Add(BitmapFrame.Create(this.colorBitmap));
string time = System.DateTime.Now.ToString("hh'-'mm'-'ss", CultureInfo.CurrentUICulture.DateTimeFormat);
string myPhotos = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string path = System.IO.Path.Combine(myPhotos, "KinectSnapshot-" + time + ".png");
// write the new file to disk
try
{
using (FileStream fs = new FileStream(path, FileMode.Create))
{
encoder.Save(fs);
}
this.ss_dis.Text = string.Format("{0} {1}", "Screenshot has been taken.", path);
}
catch (IOException)
{
this.ss_dis.Text = string.Format("{0} {1}", "Failed to take Screenshot.", path);
}
}
The part that I am struggling is that I have never really dealt with web activities such as HttpWebRequest functions before and the website shows xml and json. I have a slight idea of how to do it but I am not too sure.
This is the link to the developer api.
http://www.dumpyourphoto.com/information/api
Update: I tried to work things out myself but I am stuck at this last part. I don't know how to attach the bytearray and key to the HttpWebRequest.
private byte[] imgToByteArray(string _FileName)
{
byte[] _buffer = null;
try
{
System.IO.FileStream _FileStream = new System.IO.FileStream(_FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
System.IO.BinaryReader _BinaryReader = new System.IO.BinaryReader(_FileStream);
long _TotalByte = new System.IO.FileInfo(_FileName).Length;
_buffer = _BinaryReader.ReadBytes((Int32)_TotalByte);
_FileStream.Close();
_FileStream.Dispose();
_BinaryReader.Close();
}
catch(Exception _Exception)
{
Console.WriteLine("Exception caught in process: {0}", _Exception.ToString());
}
return _buffer;
}
This is the Image to ByteArray function.
private void button1_Click(object sender, RoutedEventArgs e)
{
string imgPath = "C:\\KinectSnapshot-04-46-14.png";
string key = "1d533e9033f9d5b9b509055d8a00932aaf1ace7f";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.dumpyourphoto.com/api/upload_photo/xml");
string path = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "KinectSnapshot-" + "03-38-28" + ".png");
byte[] img = imgToByteArray(path);
request.Method = "POST";
request.Credentials = CredentialCache.DefaultCredentials;
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = img.Length;
using(Stream dataStream = request.GetRequestStream())
dataStream.Write(img, 0, img.Length);
using (WebResponse response = request.GetResponse())
using(Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
string responseResults = reader.ReadToEnd();
Console.WriteLine(responseResults);
}
}
Update: This is where I am currently. I have 2 problems left. I don't know where to attach the key file and the title of the uploaded picture. Can anyone enlighten me on this?
I would really appreciate any help I can get!
You would use HttpWebRequest to make a POST request using the methods listed in their API. Is there something specific you're struggling with?

Categories