ASP.NET / VB: Write output to both browser and file

Using ASP.NET and VB, how can I write a webpage to a file as well as send it to a browser? In the example below, a file is created but it only contains the word “True” instead of the content of the page.

<%@ Page Language="VB" AutoEventWireup="false" %>
<%
Response.BufferOutput = true
%>
Hello
<%
Response.write("Earth")
Dim outputData as String

IO.File.WriteAllText(Server.MapPath("output.txt"), buffer.ToString())

%>

I think I would create the webpage content in a StringBuilder and then display the page and output it to the text file as well. Does that make any sense?

What is your end goal? Are you trying to create a cache? Why do you need to write the output to a file?

If for caching, just enable Page Caching

If you are trying to generate static HTML files, then a stringbuilder approach “would” work, but it is ugly, and will give you a terrible code behind. A better approach in my opinion is to write another utility that invokes a WebRequest (pass the URL of the page you want to save), and write the Response to a file.

This requires two applications, one that handles the saving of the page to file and the application that generates the file output you want to save, but it is much cleaner and leans more towards SOA (Service Oriented Architecture)

cpradio, thank you for your thoughtful response. I want to do more than just caching. I want to use REGEX to modify the content of the page, as demonstrated in my code below.

Because I want to modify the HTML with REGEX, enabling Page Caching will not do the trick. A stringbuilder approach might be ugly but it is what I need.

This would be very easy to do with PHP:
$outputData = ob_get_contents();

Is there any way at all to do this with ASP.NET / VB?

Thanks for the help.

<%@ Page Language="VB" AutoEventWireup="false" %>
<%
Response.BufferOutput = true
%>
Hello
<%
Response.write("Earth")
Dim outputData as String

outputData = buffer.ToString() ' THIS LINE DOES NOT WORK!  IT IS THE LINE THAT NEEDS FIXING!!!!!!!!!!!

outputData = System.Text.RegularExpressions.Regex.Replace(outputData.Trim(), "(?=\\s\\s)\\s*?(\
)\\s*|(\\s)\\s+", "$1$2")

Response.Clear()

Response.write(outputData)

IO.File.WriteAllText(Server.MapPath("output.txt"), outputData)

%>

Why are you trying to modify the content with a regex? There are almost certainly better approaches here.

If you really need to do it that way, you should look at using the UrlRewriter – it has the capability to modify output in responses in some ways.

If you really need to do it internally, you will need to capture the output stream very late in the rendering cycle. Note that by pulling the whole string out to use a regex you will murder performance dead.

Still, is there any way to do this?

I agree with @wwb_99 ;

It looks like your regular expression is looking for newlines and spaces and trying to trim them down. There are far better approaches indeed, such as, performing that step in the code behind, or the original data that is driving those oddities.

However, to answer your question, it does not work because you are capturing the output in the wrong event (you are in the Render event). You really need to capture it in the Page.Unload event (most likely, but that may be too late, as the Response gets cleared in this event)

I strongly encourage that you read about the page life cycle of .NET so you get a better understanding of how it operates.

Could it be done? Yes. Is it completely pointless? Yes. Is it potentially harmful to your app’s performance? Yes. ASP.NET webforms does lots of tricks under the hood to stream the content down the wire very, very fast. Stopping that process to capture the results will get pretty ugly pretty fast.

The only reason I can think of this mattering for is for compression. If so there are better solutions, like gzip which is baked into IIS and is merely a checkbox to turn on. If you really feel the need to do this see this article – http://www.codeproject.com/Articles/9521/Removing-White-Chars-from-ASP-NET-Output-using-Res ; the short version is you want to use a response filter. This is not a problem for the Page instance to even be aware of.