I’m working on a site that I’ve inherited that’s built with ASP.Net, which I’m only slightly familiar with. One of the pages allows for a link to a document (word or pdf) that, when clicked on, prompts the user to save or open the file, but does not reveal the true path of the file. This way it prevents users from pasting a url to a file – the link is to an aspx file that checks for a valid session, and then retrieves the file.
Anyway, because there’s a lot of legacy code, I need to do this with a bunch of static htm files as well, however these files need to be displayed rather than prompting the user to save them, which is what happens now. I tried changing the content type to application/text, application/html, text/html, etc. and that didn’t work, then tried adding a response header of content-disposition inline. When I do that, build, and try linking to the file, I get a couple of runtime exceptions:
[FormatException: Input string was not in a correct format.]
Microsoft.VisualBasic.CompilerServices.Conversions.ParseDecimal(String Value, NumberFormatInfo NumberFormat) +206
Microsoft.VisualBasic.CompilerServices.Conversions.ToLong(String Value) +110
[InvalidCastException: Conversion from string "inline; filename=\" + myFile + " to type 'Long' is not valid.]
Microsoft.VisualBasic.CompilerServices.Conversions.ToLong(String Value) +428
cmswebasp.CMSModdoclinks.DownloadFile(String file) +1704
cmswebasp.CMSModdoclinks.Page_Load(Object sender, EventArgs e) +625
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +50
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627
Here’s a snippet of code from the page:
Response.AddHeader("Content-Disposition", "inline; filename=" & file)
Dim fi As New FileInfo(myFile)
Response.AddHeader("Content-Length", fi.Length)
Dim contentType As String = ""
Dim fileExt As String = file.Split(".")(1)
Select Case fileExt
Case "htm"
contentType = "application/text"
Case Else
contentType = "application/octet-stream"
End Select
Response.ContentType = contentType
Response.WriteFile(myFile)
Do I have to do something with an htmlwriter object or something? Can’t I just have it open a new browser window with the file displaying or does it have to prompt the user if used in this way??
Scrap the full page (.aspx) approach in place of using a generic handler (.ashx). An .aspx page is going to do a lot of built-in loading to initialize all the state that would normally be used in an ASP.NET web page, while the generic handler only initializes the bare minimum to send output back out to the client.
You will need to also implement
System.Web.SessionState.IRequiresSessionStateto get your session state when using a generic handler, as it does not load the session state by default.An example:
Note: If hosting on IIS 7, you will need to remove any
<httpHandler>registrations from<system.web>and register them instead as<handler>registrations in<system.webServer>.Such as (correct as necessary to use your namespace):
Another Note: If you are developing for a IIS 7 host using Integrated pipeline (default for IIS 7), then I would suggest using (and installing if necessary) the IIS Express option for your web project. This would be found going into Properties for your web project, the Web tab from left, then in the Servers section, select Use Local IIS Web Server radio button, and check Use IIS Express below.
This will put your development environment more in sync with how your production environment will behave.