views:

957

answers:

5

In my web project's business object editor page, I'm sending a notification email to the administrator after an object insert or update. But instead of sending a plain text mail, i want to send the html output of another aspx page(Notification.aspx) i simply prepared for this purpose.

First i thought, I can create an instance of Notification.aspx then use it's RenderControl method for getting the output.

However, in the codebehind of Editor.aspx page, i can't even reach the Notification's reference to create a new instance.

I wonder what is the best practice for loading and rendering a page in another one...

Thanks.

A: 

See this question/answer: Can I set up HTML/Email Templates in C# on ASP.NET?. Mark Brackett has what you're looking for, though there's a lot of other helpful advice there as well.

John Rudy
A: 

The page class is instantiated by the ASP.NET runtime when a request is made. So you can make a request and get the capture the response:

using (WebClient client = new WebClient())
using (Stream stream = client.OpenRead("http://mysite.com/notification.aspx"))
using (StreamReader reader = new StreamReader(stream))
{
    var contents = reader.ReadToEnd();
}
Darin Dimitrov
A: 

Sounds tricky. Keep in mind the page will need an appropriate HttpContext as well, in order to render correctly.

I would consider using a UserControl instead. These can be simply loaded and rendered with the Page.LoadControl() method. With a bit of jiggery-pokery, you can keep it from rendering in the page while extracting it's HTML.

Tor Haugen
+4  A: 

You can render a page by doing this:

StringWriter _writer = new StringWriter();
HttpContext.Current.Server.Execute("MyPage.aspx" _writer);

string html = _writer.ToString();
MartinHN
I never knew about that overload. Turns out there's another one that takes a IHttpHandler - which would allow you to subscribe to Page events and modify the output before rendering. Very nice, and significantly simplifies my EmailPageHandler code below. +1
Mark Brackett
thanks. that made the trick in simplest way :)now i also wonder can i make this process asynchronously? because it takes some time to generate the mail body's html
koraytaylan
I would do that by creating a new Thread, put the render code in a method. And execute the method in the new Thread.
MartinHN
A: 

RenderControl won't work, because the Page won't go through it's lifecycle. I've used an HttpHandler and a Response.Filter to capture the stream in the past for a similar purpose. I've posted code over at the ASP.NET forums previously.

Edit: If you need to modify page output, you should combine this with the Server.Execute overload pointed out by MartinNH. That would simplify the code, removing the Response.Filter and such. If you just want the page output directly, MartinNH's method is very clean.

Mark Brackett