views:

148

answers:

4

Hi,

I am building a website which allows people to send out emails to people with a choice of different templates. When they have set-up their email and chosen a template the user can preview it. At present this loads up the corresponding aspx page to the template selected.

I currently have 3 templates but expect this to grow substantially.

The aspx pages all have the same controls, with the same names and even the codebehind(cs) page is the same. So it would be far simpler and efficient if i could somehow tie this pages together and minimise repetition, perhaps even just using one page but loading up the HTML corresponding to the selected template.

I cant think of an appropriate way to do this, or even work out if its possible. Ive probably got to the point where i cant think straight on the matter since its giving me such a headache.

So.....

Please please please give me some solutions or even just suggestions. ;-)

Thanks.


ADDITIONAL INFO

As an additional problem, i have to recreate the templates programatically when the emails are created and sent out to recipients as HTML emails. This is done via a different page and thus results in more duplication that id like to minimise.

A: 

How about MasterPages for the templates? The select the appropriate master page at PageLoad.

If it's content then using CSS for the formatting (you can obviously change the CSS being loaded at Pageload) also Placeholders and populating them from your data store for the mails is another option.

It think there are probably as many solutions as there are users on StackOverflow ;)

Lazarus
CSS+Placeholders, not just CSS :)
Lazarus
Doesnt use CSS since we need the HTML emails to look fairly consistent across browsers. By all accounts this is not realistic using CSS and so tables are used for positioning.
Munklefish
+1  A: 

create a Page class, let say, TemplateViewerPage

TemplateViewerPage.cs

using System;
using System.Web.UI;

public partial class TemplateViewerPage : Page
{
    protected override void OnLoad(EventArgs e)
    {
        // load your properties
        _subject = "test";
        _messageBody = "body";

        base.OnLoad(e);
    }

    // your property
    private string _subject;
    public string Subject
    {
        get { return _subject; }
        set { _subject = value; }
    }

    private string _messageBody;
    public string MessageBody
    {
        get { return _messageBody; }
        set { _messageBody = value; }
    }
}

then you can create viewer for template A :

ViewerA.aspx

<%@ Page Language="C#" AutoEventWireup="false" Inherits="TemplateViewerPage" CodeFile="TemplateViewerPage.cs" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <table>
            <tr>
                <td>Subject</td>
                <td> <%= Subject %> </td>
            </tr>
            <tr>
                <td>Message</td>
                <td> <%= MessageBody %> </td>
            </tr>
        </table>
    </div>
    </form>
</body>
</html>

and ViewerB, with same code behind (codefile=TemplateViewerPage.cs)

ViewerB.aspx:

<%@ Page Language="C#" AutoEventWireup="false" Inherits="TemplateViewerPage" CodeFile="TemplateViewerPage.cs" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div class="subject">
           <%= Subject %>
        </div>
        <div class="message">
           <%= MessageBody %> </td>
        </div>
    </div>
    </form>
</body>
</html>
Anwar Chandra
But I would like to recommend you to use asp.net mvc framework.
Anwar Chandra
You dont have to make a viewer class for each template. I just edited my answer.
Anwar Chandra
Whats the difference between: <%= Subject %> and <%# Subject %> ?
Munklefish
If i use the above code in a DB then retreive it the codebehind as a string to be used in a MailMessage, will these variable still be filled or does this need to be adapted to work in this way?
Munklefish
What does this part of the code do? ITs placed at the end of the OnLoad method.base.OnLoad(e);
Munklefish
you should fill those variables on every page load. base.OnLoad(e) is the OnLoad method of base, in this case is System.Web.UI.Page. Don't delete that.
Anwar Chandra
Alternatively, you could replace 'protected override void OnLoad(EventArgs e)' with 'protected void Page_Load(object sender, EventArgs e)'. It is the other way to override OnLoad handler. Then you can replace base.OnLoad(e) line for a cleaner code.
Anwar Chandra
A: 

If all the controls and code behind are the same, couldn't you put all the controls into a masterpage and simply use content pages for the actual emails?

Ah I see. Although it changes is it always in a similar structure? Because you can have multiple content holders in a masterpage. So in the masterpage you would be able to have content wrapped around the controls as follows:

        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
    </asp:ContentPlaceHolder>
    <asp:Button ID="button1" runat="server" />
    <asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
    </asp:ContentPlaceHolder>
Fishcake
The controls are positioned using html rather than css. How would i wrap the html around the controls? Since the html is the only thing that changes.
Munklefish
Edited answer above.
Fishcake
Perhaps ive got a mental block and cant see what you are trying to explain. From my perspective this method doesnt help since the controls are placed in different positions, and orders with each differing template.
Munklefish
A: 

I haven't found that the asp.net web forms page, master pages, or mvc is a very good fit for this sort of thing. It's like using a sledgehammer to crack open a peanut.

It's very straightforward to create some custom xml tags and then merge them yourself. Save the template in the database and merge whenever you like, and without all the overhead of running asp.net. Use agile principles: create your tests first and work backwards and you'll have exactly what you need running in no time.

The most basic is straight string replacement. If you need more, which it doesn't sound like you do, you could use xslt or just walk the DOM (ie store your templates as xhtml and have your own custom tag support).

There's also an issue of deployment. It's a lot easier to update templates in a database than it is to upload files to a server. If you do go down the route of using web forms, make sure you understand the deployment scenario's before you .

Warning: html emails are tricky, and there's a lot of ugliness (from an html standpoint) to get them to render uniformly in email clients. Expect to code the html like it's 1999, and that's pretty much the state of html emails. Sad but true.

Robert Paulson