upload image and save file stream in View State - c#

protected void upload_Click(object sender, EventArgs e)
{
if (Upload.Value !="")
{
System.IO.Stream fs = Upload.PostedFile.InputStream;
img_uploadStream = Upload.PostedFile.InputStream;
System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
Byte[] bytes = CreateThumbnail(br.ReadBytes((Int32)fs.Length),150);
string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
imageField.Src = String.Format("data:{0};base64,{1}", "image/jpeg", base64String);
}
}
After upload the image , Upload.PostedFile.InputStream has set to null value .
I want to save this Input Stream to asp.net View State to reuse .

You can use this code
public Byte[] YourImage
{
get
{
if(ViewState["Key"] != null)
{
return (Byte[]) ViewState["Key"];
}
return null;
}
set
{
ViewState["Key"] = value;
}
}

Set ViewState inside upload_Click:
ViewState["ImageStream"]=Upload.PostedFile.InputStream;
Then you can get your viewstate anywhere within the page where you want to use:
System.IO.Stream fstream=(System.IO.Stream)ViewState["ImageStream"];

Related

Issue in disposing Stream objects for asp.net mvc application?

I have asp.net mvc application which has file upload functionality. While uploading the file, I am performing few validations on the uploaded content before moving it to database and file system location.
Here goes my code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddImage([Bind(Include = "image,ImageName,ImageType,CountryId,Keyword,Source,Copyright,Description")] CreateImageViewModel model)
{
if (!this.ModelState.IsValid)
{
return View("Images");
}
if (model != null && model.image.ContentType.Contains(Constants.Image) && !ValidateUploadedImageContent(model.image, model.image.FileName))
{
var dto = new ImageDTO();
model.FilePath = model.image.FileName;
dto.ImageFile = model.image;
dto.Name = model.ImageName;
dto.FilePath = model.image.FileName;
dto.FileType = Path.GetExtension(model.FilePath);
dto.ImageType = model.ImageType;
dto.CountryId = model.CountryId;
dto.Keyword = model.Keyword;
dto.Source = model.Source;
dto.Copyright = model.Copyright;
dto.Description = model.Description;
dto.CreatedBy = UserDto.emailId;
try
{
_imageService.SaveImage(dto);
}
catch (Exception ex)
{
if (ex.Message.Equals(Constants.InvalidImageType))
return GetSafeRedirect(Url.Action("AddImage", model) + "#onload-errors");
throw ex;
}
return RedirectToAction(Constants.Actions.Images.ToString());
}
else
{
return GetSafeRedirect(Url.Action("AddImage", model) + "#onload-errors");
}
}
private bool ValidateUploadedImageContent(HttpPostedFileBase uploadedFile, string imageFileName)
{
if (Path.GetExtension(imageFileName).Equals(".svg", StringComparison.OrdinalIgnoreCase))
{
if (uploadedFile.ContentLength > 0)
{
byte[] data;
//using (Stream inputStream = uploadedFile.InputStream)
//{
Stream inputStream = uploadedFile.InputStream;
var memoryStream = inputStream as MemoryStream;
if (memoryStream == null)
{
memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
}
data = memoryStream.ToArray();
//}
var parsedData = Encoding.UTF8.GetString(data, 0, data.Length).TrimEnd('\0');
var result = parsedData.ContainsAny(Constants.InsecureStrings, StringComparison.CurrentCultureIgnoreCase);
return result;
}
}
return false;
}
Here in the above method: ValidateUploadedImageContent(), I tried to dispose the stream object with the help of using statement but I found that if I keep the below code in the method: ValidateUploadedImageContent(), then in that case post validation process, I found on debugging that the ContentLength property is set with 0 value and finally corrupted image gets saved in the file system location.
Updated :
private bool ValidateUploadedImageContent(HttpPostedFileBase uploadedFile, string imageFileName)
{
if (Path.GetExtension(imageFileName).Equals(".svg", StringComparison.OrdinalIgnoreCase))
{
if (uploadedFile.ContentLength > 0)
{
byte[] data;
using (Stream inputStream = uploadedFile.InputStream)
{
Stream inputStream = uploadedFile.InputStream;
var memoryStream = inputStream as MemoryStream;
if (memoryStream == null)
{
memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
}
data = memoryStream.ToArray();
}
var parsedData = Encoding.UTF8.GetString(data, 0, data.Length).TrimEnd('\0');
var result = parsedData.ContainsAny(Constants.InsecureStrings, StringComparison.CurrentCultureIgnoreCase);
return result;
}
}
return false;
}
Can anyone help me to know how to fix this issue?
First to address your issue, which I now understand is that after the call to ValidateUploadedImageContent the image stream is invalid.
That is because the stream gained from the HttpPostedFileBase is "read-only sequential (non-seekable)" as detailed in this SO answer. This explains why the stream's ContentLength is 0 - the stream has been consumed by the validation call.
If you have flexibility with the ImageDTO class, modifying the validation method such that it returns the image bytes would be a workaround.
For example,
// on success, buffer contains the image data. Otherwise it is null.
private bool ValidateUploadedImageContent(
out byte[] buffer,
HttpPostedFileBase uploadedFile,
string imageFileName)
{
buffer = null;
if (Path.GetExtension(imageFileName).Equals(".svg", StringComparison.OrdinalIgnoreCase))
{
if (uploadedFile.ContentLength > 0)
{
var reader = new BinaryReader(inputStream);
buffer = reader.ReadBytes((int)uploadedFile.ContentLength);
var parsedData = Encoding.UTF8.GetString(buffer, 0, buffer.Length).TrimEnd('\0');
return parsedData.ContainsAny(Constants.InsecureStrings, StringComparison.CurrentCultureIgnoreCase);
}
}
return false;
}
I've used BinaryReader to simplify the code.
Then back to the calling method,
byte[] imageBuffer = null;
if (model != null && model.image.ContentType.Contains(Constants.Image)
&& !ValidateUploadedImageContent(out imageBuffer, model.image, model.image.FileName)) {
var dto = new ImageDTO();
using(var imageStream = new MemoryStream(imageBuffer)) {
// pass along imageStream to your ImageDTO and save.
}
}
Again, hopefully you have some flexibility with the ImageDTO class.

WP8 take picture with Nokia Imaging API (real time filter) and save to IsolatedStorage

I followed the examples here: http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj662940%28v=vs.105%29.aspx
I made the live preview and stuff work, but how can I take a picture? This is what i tried:
private PhotoCaptureDevice _photoCaptureDevice = null;
string strImageName = "IG_Temp";
private NokiaImagingSDKEffects _cameraEffect = null;
private MediaElement _mediaElement = null;
private CameraStreamSource _cameraStreamSource = null;
private Semaphore _cameraSemaphore = new Semaphore(1, 1);
MediaLibrary library = new MediaLibrary();
private async void ShutterButton_Click(object sender, RoutedEventArgs e)
{
if (_cameraSemaphore.WaitOne(100))
{
await _photoCaptureDevice.FocusAsync();
_cameraSemaphore.Release();
CameraCaptureSequence seq = _photoCaptureDevice.CreateCaptureSequence(1);
await seq.StartCaptureAsync();
MemoryStream captureStream1 = new MemoryStream();
// Assign the capture stream.
seq.Frames[0].CaptureStream = captureStream1.AsOutputStream();
try
{
// Set the position of the stream back to start
captureStream1.Seek(0, SeekOrigin.Begin);
// Save photo as JPEG to the local folder.
using (IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream targetStream = isStore.OpenFile(strImageName, FileMode.Create, FileAccess.Write))
{
// Initialize the buffer for 4KB disk pages.
byte[] readBuffer = new byte[4096];
int bytesRead = -1;
// Copy the image to the local folder.
while ((bytesRead = captureStream1.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
targetStream.Write(readBuffer, 0, bytesRead);
}
}
}
}
finally
{
// Close image stream
captureStream1.Close();
}
// Navigate to the next page
Dispatcher.BeginInvoke(() =>
{
NavigationService.Navigate(new Uri("/Edit.xaml?name=" + strImageName, UriKind.Relative));
});
}
}
But I will get an error:
System.InvalidOperationException
in line: await seq.StartCaptureAsync();
What am I doing wrong?

Accessing the header in OpenReadCompleted Method on windows phone 8

I have an app that downloads an image to the phone and depending on the image category it will assign it to a news feed. I am using this function:
private static void DownloadImage(string furl, string ids)
{
// Connect Again to the API
WebClient client = new WebClient();
client.Headers["NewsID"] = ids;
string url = "www.xxx.com/image/xyz";
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.OpenReadAsync(new Uri(url));
}
private static void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (e.Error == null && !e.Cancelled)
{
Stream reply = null;
StreamReader s = null;
// i am not able to read the sender who is a webclient to retrieve the information it is always skipping it
WebClient wcd = sender as WebClient;
reply = (Stream)e.Result;
s = new StreamReader(reply);
//Console.WriteLine(s.ReadToEnd());
s.Close();
reply.Close();
if (!myIsolatedStorage.DirectoryExists("ImageCache"))
{
myIsolatedStorage.CreateDirectory("ImageCache");
}
//try
//{//((MS.Internal.InternalMemoryStream)(e.Result)).FinalUri.Segments[2]
var graphImage = e.Result;
Random rand = new Random();
string fileName = string.Format("ImageCache/{0}.jpg", rand.Next());
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(fileName);
BitmapImage image = new BitmapImage();
image.SetSource(e.Result);
WriteableBitmap wb = new WriteableBitmap(image);
// Encode WriteableBitmap object to a JPEG stream.
Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
fileStream.Close();
//}
//catch (IsolatedStorageException ex)
//{
//IsolatedStorageException
//Exception handle appropriately for your app
//}
}
}
}
In the OpenReadComplete function which I'm using to download the image, I want to get the newsID from the header, and then assign it to the image before saving it into the database. I can't seem to access the header. Is this possible?
I think you can read it with sender.
WebClient c = (WebClient)sender;
string id = c.Headers["NewsID"];

Forward posted image to WCF Rest Service

I have a webform application written in C# and what I want to do is after the user submits a HTML form with an image, I send that image to a WCF Rest service also written in C#.
The problem is when I get the image in the web service this is corrupted.
I guess that the problem is that I don't encode the file properly, but after days of reading on internet I haven't found a clue.
Webform code:
protected void Page_Load(object sender, EventArgs e)
{
HttpPostedFile image = Request.Files["imagen"];
string serverResponse = Send("mywebservice/postimage", "POST", Encoding.UTF8.GetBytes(StreamToString(image.InputStream)));
}
Edit (this way worked)
protected void Page_Load(object sender, EventArgs e)
{
HttpPostedFile image = Request.Files["imagen"];
MemoryStream ms = new MemoryStream();
image.InputStream.CopyTo(ms);
byte[] bytes = ms.ToArray();
string serverResponse = Send("mywebservice/postimage", "POST", bytes);
}
public int Send(string url, string method, byte[] data)
{
string serverResponse = "";
HttpWebRequest newRequest = (HttpWebRequest)WebRequest.Create(url);
newRequest.ContentType = "image/jpeg";
newRequest.Method = method;
newRequest.Timeout = 10000;
if (newRequest.Method == "POST" || newRequest.Method == "PUT")
{
Stream reqStream = newRequest.GetRequestStream();
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
WSMessageEnt wsMessageEnt = new WSMessageEnt();
try
{
HttpWebResponse webResponse;
webResponse = (HttpWebResponse)newRequest.GetResponse();
Stream dataStream = webResponse.GetResponseStream();
serverResponse = new StreamReader(dataStream).ReadToEnd();
}
catch (WebException we)
{
}
return serverResponse;
}
public static string StreamToString(Stream data)
{
StreamReader reader = new StreamReader(data);
string body = reader.ReadToEnd();
reader.Close();
reader.Dispose();
return body;
}
Webservice code:
[WebInvoke(UriTemplate = "upload-user-image", Method = "POST")]
public Stream UploadUserImage(Stream streamdata)
{
System.Drawing.Image img = System.Drawing.Image.FromStream(streamImagen, true);
// here I get a format error
}
Possibly one problem: you're converting a stream of bytes, into a string, then back to a stream of bytes. The image bytes are arbitrary bytes, which may or may not map to a string, and the encoding you're using in one conversion (Encoding.Default) may not be the same as the one used in the other (Encoding.UTF8).
Instead of doing this:
Encoding.UTF8.GetBytes(StreamToString(image.InputStream))
Try doing something like
MemoryStream ms = new MemoryStream();
image.InputStream.CopyTo(ms);
byte[] bytes = ms.ToArray();
Or just pass the stream to Send and copy it to the request stream.

Using Stream to display Image *.ico

I want to show image with extension *.ico and I use Stream to do it. But I have a problem that.
With Extension *.jpg, *.bmp... Image show ok but *.ico, it does not show
Here is my code:
private void OutputStream(string fileName)
{
try
{
Stream dataStream = null;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPFile spFile = web.GetFile(fileName);
dataStream = spFile.OpenBinaryStream();
this.HandleOutputStream(dataStream);
});
}
catch (System.Threading.ThreadAbortException exTemp)
{
logger.Error("KBStreamPicture::OutputStream", exTemp);
}
catch (Exception ex)
{
//System.Diagnostics.Debug.Write("OutputStream::" + ex);
logger.Error("KBStreamPicture::OutputStream", ex);
}
}
and
private void HandleOutputStream(Stream dataStream)
{
const int bufferSize = 16384; //16KB
using (Stream file = dataStream)
{
if (file != null)
{
this.Page.Response.Clear();
this.Page.Response.Cache.SetCacheability(System.Web.HttpCacheability.Private);
this.Page.Response.Cache.SetExpires(DateTime.Now.AddMinutes(20)); //only cache 20 minutes
byte[] buffer = new byte[bufferSize];
int count = file.Read(buffer, 0, bufferSize);
while (count > 0)
{
if (this.Page.Response.IsClientConnected)
{
this.Page.Response.OutputStream.Write(buffer, 0, count);
count = file.Read(buffer, 0, bufferSize);
}
else
{
count = -1;
}
}
this.Page.Response.End();
}
}
}
Please help me to resolve that problem.
You're not setting the ContentType property on the Response. Try setting the ContentType to image/x-icon (please note that the "correct" content type may be image/vnd.microsoft.icon, but this post seems to indicate you may run into problems with that type).
The code should look something like:
this.Page.Response.Clear();
this.Page.Response.Cache.SetCacheability(System.Web.HttpCacheability.Private);
this.Page.Response.Cache.SetExpires(DateTime.Now.AddMinutes(20));
this.Page.Response.ContentType = "image/x-icon";

Categories

Resources