How do I code PDF download from external site on Image click? - asp.net-mvc

I have one "Download PDF" Image link, I am calling an action of a controller in order to allow users to download specific file from external site (so has given complete URL of PDF file link)
I have written following code, but its not working.
public virtual ActionLink OpenPDF()
{
string fileName = "http://mysite/filetodownload.pdf";
return File(fileName, "application/pdf", Server.UrlEncode(fileName);
}
This controller action gets called from an Image link.. and I can see this action gets called..
When I click on image, the code gets executed, and asks to Open/Save file, but when I say Save it says "This file cannot be downloaded"
what do you think can be wrong here.

Why don't you just point your link directly to the site
Download File
You don't need to go through a controller for this
As a side not, if you are returning a FileResult you need to pass it a stream, a byte array, or a path to a file on disk. You can't pass it a third party URL. It doesn't work like that. It is meant to work like this:
public virtual ActionLink OpenPDF()
{
string fileName = Server.MapPath("~/Download/filetodownload.pdf");
return File(fileName, "application/pdf");
}

I think
Show images in table from database in Asp.net-mvc3
Azure blobs and thumbnails
ASP.NET MVC - user managment of folder with pictures (FTP?)
links as you meet the answer.

Related

How do you get the full URL of a file uploaded using an Upload object in Java Play?

I'm writing an image uploader in Java Play! in the style of
https://gist.github.com/1256286#file-picture-java-L3
This is great. The image is rendered using this function in the Controller object (here, Picture is a Model implementation that has metadata about an image file:
public static void show(Long id) {
Logger.info("loading id=%s", id);
Picture picture = Picture.findByKey(id);
response.setContentTypeIfNotSet(picture.contentType);
renderBinary(new ByteArrayInputStream(picture.file), picture.file.length);
}
I want to add a url member to Picture that contains the absolute URL to this function for a given picture. How can I populate this member in a way that works irrespective of where the Java Play! application is hosted?
Although I didn't try it in version 1.x I suggest to check the Router API, there are some methods which indicates, that they can optionally create an absolute route (I'm Play 2 user and have no experience with them).
There are also methods like ie. getBaseUrl() or getFullUrl(String action, Map<String,Object> args) so I just guess that they probably will help you to resolve the problem.

Work flow for creating and returning PDF in MVC

I'm using microsoft's MVC platform to create a web application. In this application, users will fill out a HTML form, click submit, get redirected to a successful message page and receive a printout in pdf form of the form. In addition, I also want to save their entries in the form in a database. I'm using iTextSharp to create and edit the PDF.
I'm looking for advice on managing the workflow in MVC. Specifically, I have a controller method that would direct the workflow for :
saving the form entries to a database,
creating and editing the PDF,
directing the user to a success page,
returning the PDF for the user to download.
My major question is: how should I delegate the tasks of redirecting to the success page and returning the pdf? As of right now, my controller seems to be able to return only one or the other. Can I redirect to a View that "comes with" a PDF?
What I do in a case like this is create a controller action that returns the PDF associated with a given entry id in the database.
public FileResult DownloadPdf(int id)
{
byte[] data;
// ... Generate PDF
return File(data, "application/pdf");
}
Then the controller action which handles the form POST does the following:
Saving the entry values to the database.
Retrieving the primary key of the saved form entry set.
Redirecting to the success view and passing the primary key to it.
Then the success view can use the id it has been given to either link to the PDF (as a download link) or can embed it in an iframe (yuck!).
Note that this only works because you are saving the values in a database. If don't use a database, you have to either:
Encode all the form data in the query string (which has a limited size)
Store the form data in the Session (which is not recommended)
Hope that helps.

How to get ASP.NET MVC to open a new window?

I’m trying to put together a MVC app that isn’t a typical create a record and present the record to the user.
I’m finding some things that aren’t friendly in MVC as they are in Web Forms. My view has two dropdowns, a textbox, and a submit button. In one of the dropdowns I have to prepopulate it with codes and description. That part is done.
Next, I have the user enter text into the textbox. They click on a Find button. Find will populate the 2nd dropdown. Without viewstate, the code is a bit different but possible. Next, the user clicks on the submit button. Here is the tricky part. I need input from the view to generate a PDF file, then open a new browser window or tab to display the PDF.
I also want to delete the PDF from the server before presenting it. I can delete the PDF before presenting it in web forms. I found Actionlink can open a new window, but Actionlink doesn’t push the input on the view to the controller. A standard form submit button does, but a submit button doesn’t open a new window. A controller cannot open a view in a new window either.
How do I get the users input and push that input to the controller, and then display the PDF generated into a new browser window? On top of that, I need to delete the PDF off the server.
Simple create an Action that returns your Pdf stream as a FileResult
If you are generating your pdf to a memory stream: (I recommend this):
public ActionResult DownloadPdf()
{
// you need some code here to generate the pdf to the memory stream.
return File(stream, "application/pdf", "DownloadName.pdf");
}
Or if you prefer, use the filepath directly :
public ActionResult DownloadPdf()
{
// get pdf filepath
var path = "Chap0101.pdf";
return File(path, "application/pdf");
}
Then in your html code you can use something like this to open in a new window.
#Html.ActionLink("Download pdf in new window", "DownloadPdf", "ControllerName", null, new { target = "_blank" })
You might return a view with some javascript that first opens a new window and then refreshes to another view. If no javascript is active, the view wouldn't reload and a link would be there to open manually. If you create the PDF in memory, there is nothing you need to delete, just stream the in memory PDF to the client. I'm new to MVC myself, this is just an idea.

ASP.NET MVC and linked photos on shared folder

I'm writing asp.net mvc web application that uses a large number of .jpg files that are on a share folder outside the web server and not accessible via http protocol. How can I place image path inside img tag?
Do not put the image path inside your image tag as a parameter to a script. This is called a direct object reference and is a bad thing. Consider a naive implementation of such a script/page/controller which serves up as /image/?resource=\server\path\img.jpg.
Now what happens if someone loads /image/resource/?resource=c:\windows\system32\config\SAM? Your password database gets sent.
You do not want to use fully qualified paths at all, ideally you want to either serve all images from that directory and just accept a file name, stripping any path information from it by doing something like
string filename = Path.GetFileName(userInputtedFilename);
FileInfo file = new FileInfo(Server.Path.Combine("\\Server\share\", filename)));
That at least is safe, but of course users could browse through all the images if they're suitably named. Safer yet is to have an indirect object reference, a mapping table somewhere which maps something like a GUID to the actual filename and use that as the parameter to your serving script.
To serve a file you return a FileContentResult from your controller,
public FileContentResult GetFile(Guid indirectReference)
{
byte[] fileContents = // Resolve the file and read it from the indirect reference
mimeType = // Suitable MIME type
return File(fileContent, mimeType, fileName);
}
If the web server has regular network access to that share and can read the image files, you can create a new MVC controller Image with default action Index that takes one string parameter called fn. The action would create a new FileResult from the parameter. Then, when you generate the <img> tag, set the url to something like /image/?fn=\\share\image.png. (Don't forget to add the proper route for it, of course)
If the web server has no access to that share, but the page user has access, you can try setting the <img> tag to the file:// URL for the image. However, this is going to be fragile and might or might not work, depending on the user's OS and browser configuration.
Update: Do read the security implications #blowdart mentioned in his answer.

ASP.net MVC - Display series of images based on byte[]

I want to display a list of images and a description on a webpage using ASP.net MVC. The images are stored in a SQL Server DB and i'm getting them back as a byte[].
However, I don't understand how I can display a series of images on a page. I want to do something like this:
<% foreach(Product p in Model.Products)
Response.Write(p.Description)
Response.Write(html.Image(p.ImageArray)
%>
But the only code I've saw has been displaying a single image...
Thank you
Ben
Rather than creating a new HttpHandler you can just write a controller action that returns the contents of the image file. Then add images to the page with their src attribute set to the action you created.
EDIT: Note that streaming images as byte[] from a database is inefficient compared to serving static files.
You will need to create a custom IHttpHandler that will serve the images something like this:
public class AlbumArt : IHttpHandler
{
public void ProcessRequest(HttpContext Context)
{
byte [] b = your image...;
Context.Response.ContentType = "image/jpeg";
Context.Response.BinaryWrite(b);
}
}
And then you would need to retrieve each image from there by using image tags in your html, something like
<img src="AlbumArt.ashx?imageId=1" />
Images in HTML are external links, not embedded in the HTML itself. So you do need two requests. However you can optimize this a bit. In the first request, don't retrieve the image data itself, just the meta-data. Then in your HttpHandler, actually retrieve the binary image data.
Each image will have to be sent separately (which means creating an IMG request from the browser for each) or you will have to join them into a single image before sending back. If you run the code above it is likely you will see the first image only.

Resources