imagehandler.ashx image doesn't display in chrome - c#

imagehandler.ashx image doesn't display in Chrome browser. How can I fix it..?
My Codes (imagehandler.ashx):
public void ProcessRequest(HttpContext context)
{
if (context.Request.QueryString["YazarID"] != null)
{
string YazarID = context.Request.QueryString["YazarID"];
DataTable dt = new DataTable();
string query = "select img from Register where YazarID='" + YazarID + "'";
dt = Database.GetData(query);
HttpResponse r = context.Response;
r.WriteFile("../Pictures/300/" + dt.Rows[0]["img"]);
HttpContext.Current.ApplicationInstance.CompleteRequest();
context.Response.Flush();
context.Response.Close();
context.Response.End();
}
}
images looking like this in Chrome browser;

You are not sending the content-Length. It could mess up the images (and other files) in Chrome. Assuming the file is correctly saved in the database of course.
public void ProcessRequest(HttpContext context)
{
//create a new byte array
byte[] bin = new byte[0];
//get the item from a datatable
bin = (byte[])dt.Rows[0]["img"];
//read the image in an `Image` and then get the bytes in a memorystream
Image img = Image.FromFile(context.Server.MapPath("test.jpg"));
using (var ms = new MemoryStream())
{
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
bin = ms.ToArray();
}
//or as one-liner
bin = File.ReadAllBytes(context.Server.MapPath("test.jpg"));
//clear the buffer stream
context.Response.ClearHeaders();
context.Response.Clear();
context.Response.Buffer = true;
//set the correct ContentType
context.Response.ContentType = "image/jpeg";
//set the filename for the image
context.Response.AddHeader("Content-Disposition", "attachment; filename=\"myImage.jpg\"");
//set the correct length of the string being send
context.Response.AddHeader("content-Length", bin.Length.ToString());
//send the byte array to the browser
context.Response.OutputStream.Write(bin, 0, bin.Length);
//cleanup
context.Response.Flush();
context.ApplicationInstance.CompleteRequest();
}

Related

ASP NET MVC download ZIP file

I'm trying to download a ZIP file in ASP NET MVC. I have done in ASP NET Webforms, and it works correcly, but I do the same in MVC and I don't get the same result, I tried the following:
public ActionResult Download()
{
using (ZipFile zip = new ZipFile())
{
zip.AddDirectory(Server.MapPath("~/Directories/hello"));
zip.Save(Server.MapPath("~/Directories/hello/sample.zip"));
return File(Server.MapPath("~/Directories/hello/sample.zip"),
"application/zip", "sample.zip");
}
}
But I get the binary data in screen, not the downloaded zip file why this is not working in MVC?
I have found that this does not work if I do it from a partial class, if I execute the download code from the Index and send the file if it works, why?
I use this to download files. In your view:
var ext = Path.GetExtension(path);
string contentType = GetMimeType(ext);
using (var stream = fileManager.GetStream(path))
{
var filename = fileManager.GetFileName(path);
var response = System.Web.HttpContext.Current.Response;
TransmitStream(stream, response, path, filename, contentType);
return new EmptyResult();
}
Where GetMimeType is a method that return known MIME types:
public static string GetMimeType(string extension, string defaultValue = "application/octet-stream")
{
if (extension == null)
{
throw new ArgumentNullException(nameof(extension));
}
if (!extension.StartsWith("."))
{
extension = "." + extension;
}
string mime;
return _mappings.TryGetValue(extension, out mime) ? mime : defaultValue;
}
With _mappings as:
private static readonly IDictionary<string, string> _mappings =
new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase) {
{".323", "text/h323"},
{".3g2", "video/3gpp2"},
{".3gp", "video/3gpp"},
{".3gp2", "video/3gpp2"},
{".3gpp", "video/3gpp"},
{".7z", "application/x-7z-compressed"},
// Other types...
{".xwd", "image/x-xwindowdump"},
{".z", "application/x-compress"},
{".zip", "application/x-zip-compressed"},
};
And the TransmitStream:
public static void TransmitStream(
Stream stream, HttpResponse response, string fullPath, string outFileName = null, string contentType = null)
{
contentType = contentType ?? MimeMapping.GetMimeMapping(fullPath);
byte[] buffer = new byte[10000];
try
{
var dataToRead = stream.Length;
response.Clear();
response.ContentType = contentType;
if (outFileName != null)
{
response.AddHeader("Content-Disposition", "attachment; filename=" + outFileName);
}
response.AddHeader("Content-Length", stream.Length.ToString());
while (dataToRead > 0)
{
// Verify that the client is connected.
if (response.IsClientConnected)
{
// Read the data in buffer.
var length = stream.Read(buffer, 0, 10000);
// Write the data to the current output stream.
response.OutputStream.Write(buffer, 0, length);
// Flush the data to the output.
response.Flush();
buffer = new byte[10000];
dataToRead = dataToRead - length;
}
else
{
// Prevent infinite loop if user disconnects
dataToRead = -1;
}
}
}
catch (Exception ex)
{
throw new ApplicationException(ex.Message);
}
finally
{
response.Close();
}
}
Usually, if you want to download something i suggest you to use ContentResult
,transforming the file you want to download into a Base64 String and transforming it on the frontend using javascript with a Blob
Action
public ContentResult Download()
{
MemoryStream memoryStream = new MemoryStream();
file.SaveAs(memoryStream);
byte[] buffer = memoryStream.ToArray();
string fileAsString = Convert.ToBase64String(buffer);
return Content(file, "application/zip");
}
front end
var blob = new Blob([Base64ToBytes(response)], { type: "application/zip" });
var link = document.createElement("a");
document.body.appendChild(link);
link.setAttribute("type", "hidden");
link.href = url.createObjectURL(blob);
link.download = fileName;
link.click();

How to download an image only if it's not existing already?

I am writing a program that displays usercontrols in a flowlayout panel. The user layout has images, which are downloaded by the program.
For speeding up, the program should check, if the image to download already exists at the download location. If it exists, it may not download it again.
I am using this code.
WebClient wcGreatest = new WebClient();
Uri url = client.GetImageUrl(client.Config.Images.PosterSizes.Last(), searchSerie.PosterPath);
byte[] imageData = wcGreatest.DownloadData(url);
MemoryStream stream = new MemoryStream(imageData);
seriePopular.btnSerie.Image = Image.FromStream(stream);
stream.Close();
if (File.Exists(pathPoster + fileName))
{
seriePopular.btnSerie.Image = Image.FromFile(pathPoster + fileName);
}
else
{
Uri url = client.GetImageUrl(client.Config.Images.PosterSizes.Last(), searchSerie.PosterPath);
byte[] imageData = wcGreatest.DownloadData(url);
File.WriteAllBytes(pathPoster + fileName, imageData);
seriePopular.btnSerie.Image = Image.FromFile(pathPoster + fileName);
}

C# No Data in Folder after Downloading ASP

Let me start off by saying I'm sure this is something that's quite simple, unfortunately I just can't seem to figure it out. So here's my problem, I query the database, return what I need, zip it all up, and prompt user to save. When You attempt to open this, there are no files inside the folder. Where has my data gone? I stepped through everything, and it appears to write everything properly. Any help would be greatly appreciated!!
if (e.CommandName == "DownloadAttachment")
{
e.Canceled = true;
// Create a zip and send it to the client.
//Response.Write(#"<script language='javascript'>alert('Details saved successfully')</script>");
var item = e.Item as GridEditableItem;
fileId = (int)item.GetDataKeyValue("Unique");
FileData[] allrecords = null;
using (
SqlConnection conn =
new SqlConnection(ConfigurationManager.ConnectionStrings["PtcDbModelEntities"].ConnectionString))
{
using (
SqlCommand comm = new SqlCommand("Select Unique1, BinaryData, FileName from PtcDbTracker.dbo.CafFileTable where Unique1=#fileId AND FileName IS NOT NULL", conn))
{
comm.Parameters.Add(new SqlParameter("#fileId", fileId));
conn.Open();
using (var reader = comm.ExecuteReader())
{
var list = new List<FileData>();
while (reader.Read())
{
list.Add(new FileData { Unique1 = reader.GetInt32(0) });
long len = reader.GetBytes(1, 0, null, 0, 0);
Byte[] buffer = new byte[len];
list.Add(new FileData { BinaryData = (byte)reader.GetBytes(1, 0, buffer, 0, (int)len), FileName = reader.GetString(2) });
allrecords = list.ToArray();
}
}
conn.Close();
}
}
using (var compressedFileStream = new MemoryStream())
{
//Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Update, false))
{
if (allrecords != null)
{
foreach (var record in allrecords)
{
//Create a zip entry for each attachment
if (record.FileName != null)
{
var zipEntry = zipArchive.CreateEntry(record.FileName);
//Get the stream of the attachment
using (var originalFileStream = new MemoryStream(record.BinaryData))
{
using (var zipEntryStream = zipEntry.Open())
{
//Copy the attachment stream to the zip entry stream
originalFileStream.CopyTo(zipEntryStream);
}
}
}
}
}
Response.ClearContent();
Response.ClearHeaders();
Response.BinaryWrite(compressedFileStream.ToArray());
Response.AppendHeader("Content-Disposition", "Attachment; filename=result.zip");
Response.Flush();
Response.Close();
zipArchive.Dispose();
//How Do I Prompt for open or save?
}
}
Are you sure the BinaryWrite is getting a valid ByteArray?
In any case here's a tested method to output a file to the Response with the typically needed headers for binary attachments:
public bool WriteFile(byte[] byteContent, DateTime dtTimeStamp, string urlFilename)
{
HttpContext context = HttpContext.Current;
HttpResponse response = context.Response;
response.Clear();
response.ClearHeaders();
response.ClearContent();
response.BufferOutput = true;
response.AppendHeader("Content-Length", byteContent.Length.ToString());
response.AppendHeader("Content-Type", "application/octet-stream");
response.AppendHeader("Last-Modified", dtTimeStamp.ToString("R"));//Last-Modified Wed, 28 Aug 2013 10:16:46 GMT
response.AppendHeader("Content-Disposition", "inline; filename=\"" + urlFilename + "\"");
response.BinaryWrite(byteContent);
response.Flush();
// Prevents any other content from being sent to the browser
response.SuppressContent = true;
context.ApplicationInstance.CompleteRequest();
return true;
}

Bytes[] to temporal PDF file to show in <object> html tag in ASP.NET

How do i generate a temporal PDF in my ASP.NET application so I get an temp URL for a generated PDF from an array of bytes ?
I use this but i think it could get simple:
//bytes[] arrayPDF exists before
string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".pdf";
File.WriteAllBytes(fileName, arrayPDF);
HtmlGenericControl obj = new HtmlGenericControl("embed");
obj.Attributes.Add("src", fileName);
obj.Attributes.Add("style","border-radius: 10px;position: relative;top:0;right:0;left:0;bottom:0;width:100%;height:620px;");
obj.Attributes.Add("height","600");
obj.Attributes.Add("type", "application/pdf");
form1.Controls.Add(obj);
My main problem is how to generate a temp file that i am sure that it would not stay in the server more than the request/show time
Use an ASP.NET ASHX Handler:
public class Handler : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
// relevant context.Response lines
}
public bool IsReusable
{
get { return false; }
}
}
Also check this answer:
context.Response.Clear();
context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.ContentType = "application/pdf";
Stream fileStream = publishBookManager.GetFile(documentId);
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
}
context.Response.BinaryWrite(data);
context.Response.Flush();

Show file in web browser

I got a response which contains a PDF file
HttpWebResponse res = (HttpWebResponse)HttpWRequest.GetResponse();
Stream pdf = res.GetResponseStream();
I want to show this PDF on web browser without save it in a file. How could I do that?
I'm using the following code and works fine.
public static void SendDataByteFileToClient(HttpContext context, byte[] data, string fileName, string contentType, bool clearHeaders = true)
{
if (clearHeaders)
{
context.Response.Clear();
context.Response.ClearHeaders();
}
context.Response.BufferOutput = true;
context.Response.ContentType = contentType;
context.Response.AddHeader("Content-Disposition", "inline; filename=" + fileName);
context.Response.AddHeader("Content-Length", data.Length.ToString());
if (BrowserHelper.IsOfType(BrowserTypeEnum.IE) && BrowserHelper.Version < 9)
{
context.Response.Cache.SetCacheability(HttpCacheability.Private);
context.Response.Cache.SetMaxAge(TimeSpan.FromMilliseconds(1));
}
else
{
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);//IE set to not cache
context.Response.Cache.SetNoStore();//Firefox/Chrome not to cache
context.Response.Cache.SetExpires(DateTime.UtcNow); //for safe measure expire it immediately
}
if (data.Length > 0)
{
context.Response.BinaryWrite(data);
}
context.Response.End();
}
HttpWebResponse res = (HttpWebResponse)HttpWRequest.GetResponse();
Stream pdfdata = res.GetResponseStream();
string path = pdfdata.ToString();
WebClient client = new WebClient();
Byte[] buffer = client.DownloadData(path);
if (buffer != null)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-length", buffer.Length.ToString());
Response.BinaryWrite(buffer);
Response.End();
}

Categories

Resources