Serve up file from outside web application directory

B

Brian Simmons

I come from a ColdFusion background, and CF has the ability (via something
called CFCONTENT) which allows you to serve up a file which resides outside
your web root directory.

How do I accomplish a similar thing using ASP.net 2 (C#)?

Basically, my web app is creating a PDF document and storing it in C:\PDFS

In my app, I want to have a LinkButton which will serve up the PDF (located
in C:\PDFS) to the user.
I DO NOT want to have the PDFs in the web app's directory structure because
you have to log into the app to use it. And I don't want just anyone to be
able to link to the PDF.

Thanks in advance for any advice,
Brian
 
M

Mike

Cold Fusion, ha good times there.

In C# you would use something like

DirectoryInfo dir = new DirectoryInfo("c:\\pdfFiles);
FileInfo[] pdfFiles= dir.GetFiles("*.pdf");
foreach(FileInfo f in pdfFiles)
{
Response.Write("<br><a href=" + f.Name + ">" + f.Name + "</a>");
}
 
A

Aidy

Also ignore the "Add the PDF File to the Project" section :) As you want
the file outside your web space
 
S

Steven Cheng[MSFT]

Hi Brian,

This is a piece of cake in ASP.NET since you can utlize the powerful
functionality of .net framework components. As other members have
suggested, you can use the System.IO classes to get binary data from the
external file system (even on remote share folder) and write it out to
page's response stream. e.g.

======================
protected void Page_Load(object sender, EventArgs e)
{
byte[] bytes = null;
string path = @"d:\filestore\pdf_files\test.pdf";

bytes = File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType= "application\pdf";
Response.AddHeader("Content-disposition", "attachment;
filename=test.pdf");

Response.Write(bytes);
Response.End();
}
===========

Here is a web article also mentioned this:

#Secure File Download Page
http://www.codeproject.com/aspnet/SecureFileDownload.asp

In addition, you can even get the file content from other storage such as
database, webservice ..... It's quite flexible when you use the .net
frameowork classes to deal with the things:)

Hope this also helps.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
S

Steven Cheng[MSFT]

Hi Brain,

Any further questions on this? If so, please feel free to post here.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
B

Brian Simmons

Hi Steven (and others),

I'm sure I'm doing something simple wrong.

As a test in my application, I decided to use a simple text file.
so
string path = "C:\sometext.txt" // which exists, and has some text in it,
just a few characters

and I changed the ContentType to:
Response.ContentType = "text/plain";

and I adjusted the filename to sometext.txt instead of test.pdf

When I run it, I'm presented with a text file that says:
System.Byte[]

When I debug it, I can see that bytes[] contains the correct ASCII code for
the simple text I have in there.

Why does the text file presented to me have:
System.Byte[]
in it rather than the simple text which is in the sometext.txt?

Thanks,
Brian
 
S

Steven Cheng[MSFT]

Thanks for your followup Brian,

for the text file with "System.Byte[]" problem you mentioned, do you mean
the file download dialog display the filename as "System.Byte[]"?

If this is the case, I suggest you check the code to see whether you have
add the "Content-Disposition" header and supply the filename. Because when
you stream out a file(or other binary content), the ASP.Net won't care
what's their original filename, you need to explicitly supply them.e.g.

======================
protected void Page_Load(object sender, EventArgs e)
{
byte[] bytes = null;
string path = @"d:\filestore\pdf_files\test.pdf";

bytes = File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType= "text/plain";

//here put the filename
Response.AddHeader("Content-disposition", "attachment;
filename=test.txt");

Response.Write(bytes);
Response.End();
}
===========

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
B

Brian Simmons

Hi Steven,

Here is my exact code from the Page_Load event (sometext.aspx):
byte[] bytes = null;
string path = "C:\\sometext.txt"; // This file exists and has one
sentence in it: The quick brown fox...etc.

bytes = File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/plain";
Response.AddHeader("Content-disposition", "attachment;
filename=sometext.txt");

Response.Write(bytes);
Response.End();

How I'm Calling that sometext.aspx page:
<a href='sometext.aspx' target='_blank'>Some Text</a>

What happens when that link is clicked:
A new browser window is spawned. IE7 displays a dialog:
Do you want to open or save this file?

If you click open, Notepad displays and the text inside Notepad is:
System.Byte[]

If you click save (to your Desktop let's say), the file saves, and it's
contents are:
System.Byte[]

Any ideas?

Thanks,
Brian
 
S

Steven Cheng[MSFT]

Hi Brian,

Thanks for your followup.

I've rechecked the code and it does be a mistake in my code as I used
"Response.Write" to write out the byte[](binary data), this is incorrect. I
should use the "BinaryWrite" method for binary data(byte[] array).
"Response.Write" should be used for string text data.

Here I've pasted two methods both of which can do the work(one write out
binary data and another write out string data), you can have a look and
choose either one as you want:

protected void BinaryWriteMethod()
{
byte[] bytes = null;
string path = "e:\\temp\\temp.txt"; // This file exists and has
one sentence in it: The quick brown fox...etc.

bytes = System.IO.File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/plain";
Response.ContentEncoding = Encoding.UTF8;
Response.AddHeader("Content-disposition", "attachment;
filename=sometext.txt");

Response.BinaryWrite(bytes);
Response.End();

}

protected void StringWriteMethod()
{

string path = "e:\\temp\\temp.txt"; // This file exists and
has one sentence in it: The quick brown fox...etc.

StreamReader sr = new StreamReader(path, Encoding.UTF8);

string data = sr.ReadToEnd();

sr.Close();

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/plain";
Response.ContentEncoding = Encoding.UTF8;
Response.AddHeader("Content-disposition", "attachment;
filename=sometext.txt");

Response.Write(data);
Response.End();
}
BTW, for string text approach, you need to make sure the text
encoding(specified in code) matches the text file's text encoding.

Hope this helps. If there is still anything unclear, please don't hesitate
to let me know.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



This posting is provided "AS IS" with no warranties, and confers no rights.














--------------------
From: "Brian Simmons" <[email protected]>
References: <#c5n#[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
Subject: Re: Serve up file from outside web application directory
Date: Fri, 24 Aug 2007 09:48:41 -0400
Lines: 84
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.3138
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3138
X-RFC2646: Format=Flowed; Original
Message-ID: <#[email protected]>
Newsgroups: microsoft.public.dotnet.framework.aspnet
NNTP-Posting-Host: 65.124.198.22
Path: TK2MSFTNGHUB02.phx.gbl!TK2MSFTNGP01.phx.gbl!TK2MSFTNGP05.phx.gbl
Xref: TK2MSFTNGHUB02.phx.gbl microsoft.public.dotnet.framework.aspnet:39662
X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet

Hi Steven,

Here is my exact code from the Page_Load event (sometext.aspx):
byte[] bytes = null;
string path = "C:\\sometext.txt"; // This file exists and has one
sentence in it: The quick brown fox...etc.

bytes = File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/plain";
Response.AddHeader("Content-disposition", "attachment;
filename=sometext.txt");

Response.Write(bytes);
Response.End();

How I'm Calling that sometext.aspx page:
<a href='sometext.aspx' target='_blank'>Some Text</a>

What happens when that link is clicked:
A new browser window is spawned. IE7 displays a dialog:
Do you want to open or save this file?

If you click open, Notepad displays and the text inside Notepad is:
System.Byte[]

If you click save (to your Desktop let's say), the file saves, and it's
contents are:
System.Byte[]

Any ideas?

Thanks,
Brian


Steven Cheng said:
Thanks for your followup Brian,

for the text file with "System.Byte[]" problem you mentioned, do you mean
the file download dialog display the filename as "System.Byte[]"?

If this is the case, I suggest you check the code to see whether you have
add the "Content-Disposition" header and supply the filename. Because when
you stream out a file(or other binary content), the ASP.Net won't care
what's their original filename, you need to explicitly supply them.e.g.

======================
protected void Page_Load(object sender, EventArgs e)
{
byte[] bytes = null;
string path = @"d:\filestore\pdf_files\test.pdf";

bytes = File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType= "text/plain";

//here put the filename
Response.AddHeader("Content-disposition", "attachment;
filename=test.txt");

Response.Write(bytes);
Response.End();
}
===========

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no
rights.
 
S

Steven Cheng[MSFT]

Hi Brian,

Any progress on this or does the further info in my last reply still helps
some? If you have any further questions on this, please don't hesitate to
let me know.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead

This posting is provided "AS IS" with no warranties, and confers no rights.


--------------------
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
Hi Brian,

Thanks for your followup.

I've rechecked the code and it does be a mistake in my code as I used
"Response.Write" to write out the byte[](binary data), this is incorrect. I
should use the "BinaryWrite" method for binary data(byte[] array).
"Response.Write" should be used for string text data.

Here I've pasted two methods both of which can do the work(one write out
binary data and another write out string data), you can have a look and
choose either one as you want:

protected void BinaryWriteMethod()
{
byte[] bytes = null;
string path = "e:\\temp\\temp.txt"; // This file exists and has
one sentence in it: The quick brown fox...etc.

bytes = System.IO.File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/plain";
Response.ContentEncoding = Encoding.UTF8;
Response.AddHeader("Content-disposition", "attachment;
filename=sometext.txt");

Response.BinaryWrite(bytes);
Response.End();

}

protected void StringWriteMethod()
{

string path = "e:\\temp\\temp.txt"; // This file exists and
has one sentence in it: The quick brown fox...etc.

StreamReader sr = new StreamReader(path, Encoding.UTF8);

string data = sr.ReadToEnd();

sr.Close();

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/plain";
Response.ContentEncoding = Encoding.UTF8;
Response.AddHeader("Content-disposition", "attachment;
filename=sometext.txt");

Response.Write(data);
Response.End();
}
BTW, for string text approach, you need to make sure the text
encoding(specified in code) matches the text file's text encoding.

Hope this helps. If there is still anything unclear, please don't hesitate
to let me know.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



This posting is provided "AS IS" with no warranties, and confers no rights.














--------------------
From: "Brian Simmons" <[email protected]>
References: <#c5n#[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
Subject: Re: Serve up file from outside web application directory
Date: Fri, 24 Aug 2007 09:48:41 -0400
Lines: 84
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.3138
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3138
X-RFC2646: Format=Flowed; Original
Message-ID: <#[email protected]>
Newsgroups: microsoft.public.dotnet.framework.aspnet
NNTP-Posting-Host: 65.124.198.22
Path: TK2MSFTNGHUB02.phx.gbl!TK2MSFTNGP01.phx.gbl!TK2MSFTNGP05.phx.gbl
Xref: TK2MSFTNGHUB02.phx.gbl microsoft.public.dotnet.framework.aspnet:39662
X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet

Hi Steven,

Here is my exact code from the Page_Load event (sometext.aspx):
byte[] bytes = null;
string path = "C:\\sometext.txt"; // This file exists and has one
sentence in it: The quick brown fox...etc.

bytes = File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/plain";
Response.AddHeader("Content-disposition", "attachment;
filename=sometext.txt");

Response.Write(bytes);
Response.End();

How I'm Calling that sometext.aspx page:
<a href='sometext.aspx' target='_blank'>Some Text</a>

What happens when that link is clicked:
A new browser window is spawned. IE7 displays a dialog:
Do you want to open or save this file?

If you click open, Notepad displays and the text inside Notepad is:
System.Byte[]

If you click save (to your Desktop let's say), the file saves, and it's
contents are:
System.Byte[]

Any ideas?

Thanks,
Brian


Steven Cheng said:
Thanks for your followup Brian,

for the text file with "System.Byte[]" problem you mentioned, do you mean
the file download dialog display the filename as "System.Byte[]"?

If this is the case, I suggest you check the code to see whether you have
add the "Content-Disposition" header and supply the filename. Because when
you stream out a file(or other binary content), the ASP.Net won't care
what's their original filename, you need to explicitly supply them.e.g.

======================
protected void Page_Load(object sender, EventArgs e)
{
byte[] bytes = null;
string path = @"d:\filestore\pdf_files\test.pdf";

bytes = File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType= "text/plain";

//here put the filename
Response.AddHeader("Content-disposition", "attachment;
filename=test.txt");

Response.Write(bytes);
Response.End();
}
===========

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no
rights.
 
B

Brian Simmons

Yes, thanks for the follow-up, your corrections solved the issue. Works
like a charm now.

Steven Cheng said:
Hi Brian,

Any progress on this or does the further info in my last reply still helps
some? If you have any further questions on this, please don't hesitate to
let me know.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead

This posting is provided "AS IS" with no warranties, and confers no
rights.


--------------------
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
Hi Brian,

Thanks for your followup.

I've rechecked the code and it does be a mistake in my code as I used
"Response.Write" to write out the byte[](binary data), this is incorrect. I
should use the "BinaryWrite" method for binary data(byte[] array).
"Response.Write" should be used for string text data.

Here I've pasted two methods both of which can do the work(one write out
binary data and another write out string data), you can have a look and
choose either one as you want:

binary approach>>>>>>>>>
protected void BinaryWriteMethod()
{
byte[] bytes = null;
string path = "e:\\temp\\temp.txt"; // This file exists and has
one sentence in it: The quick brown fox...etc.

bytes = System.IO.File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/plain";
Response.ContentEncoding = Encoding.UTF8;
Response.AddHeader("Content-disposition", "attachment;
filename=sometext.txt");

Response.BinaryWrite(bytes);
Response.End();

}
text string approach>>>>>>>>

protected void StringWriteMethod()
{

string path = "e:\\temp\\temp.txt"; // This file exists and
has one sentence in it: The quick brown fox...etc.

StreamReader sr = new StreamReader(path, Encoding.UTF8);

string data = sr.ReadToEnd();

sr.Close();

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/plain";
Response.ContentEncoding = Encoding.UTF8;
Response.AddHeader("Content-disposition", "attachment;
filename=sometext.txt");

Response.Write(data);
Response.End();
}
BTW, for string text approach, you need to make sure the text
encoding(specified in code) matches the text file's text encoding.

Hope this helps. If there is still anything unclear, please don't hesitate
to let me know.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



This posting is provided "AS IS" with no warranties, and confers no
rights.














--------------------
From: "Brian Simmons" <[email protected]>
References: <#c5n#[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
Subject: Re: Serve up file from outside web application directory
Date: Fri, 24 Aug 2007 09:48:41 -0400
Lines: 84
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.3138
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3138
X-RFC2646: Format=Flowed; Original
Message-ID: <#[email protected]>
Newsgroups: microsoft.public.dotnet.framework.aspnet
NNTP-Posting-Host: 65.124.198.22
Path: TK2MSFTNGHUB02.phx.gbl!TK2MSFTNGP01.phx.gbl!TK2MSFTNGP05.phx.gbl
Xref: TK2MSFTNGHUB02.phx.gbl microsoft.public.dotnet.framework.aspnet:39662
X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet

Hi Steven,

Here is my exact code from the Page_Load event (sometext.aspx):
byte[] bytes = null;
string path = "C:\\sometext.txt"; // This file exists and has one
sentence in it: The quick brown fox...etc.

bytes = File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/plain";
Response.AddHeader("Content-disposition", "attachment;
filename=sometext.txt");

Response.Write(bytes);
Response.End();

How I'm Calling that sometext.aspx page:
<a href='sometext.aspx' target='_blank'>Some Text</a>

What happens when that link is clicked:
A new browser window is spawned. IE7 displays a dialog:
Do you want to open or save this file?

If you click open, Notepad displays and the text inside Notepad is:
System.Byte[]

If you click save (to your Desktop let's say), the file saves, and it's
contents are:
System.Byte[]

Any ideas?

Thanks,
Brian


Thanks for your followup Brian,

for the text file with "System.Byte[]" problem you mentioned, do you mean
the file download dialog display the filename as "System.Byte[]"?

If this is the case, I suggest you check the code to see whether you have
add the "Content-Disposition" header and supply the filename. Because when
you stream out a file(or other binary content), the ASP.Net won't care
what's their original filename, you need to explicitly supply them.e.g.

======================
protected void Page_Load(object sender, EventArgs e)
{
byte[] bytes = null;
string path = @"d:\filestore\pdf_files\test.pdf";

bytes = File.ReadAllBytes(path);

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType= "text/plain";

//here put the filename
Response.AddHeader("Content-disposition", "attachment;
filename=test.txt");

Response.Write(bytes);
Response.End();
}
===========

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no
rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top