创建独立于asp.net webforms中的源代码的网站模板

时间:2012-05-21 16:39:23

标签: asp.net templates user-controls

我正在开发一个支持不同域上多个商店的电子商务平台。后端已经完成(现在),我现在正在开始前端部分。由于该平台支持多个商店,我需要某种模板系统,我还没有弄清楚最好的方法是什么。

这是我的要求:

  • 我不想重建我的解决方案来添加新模板
  • 模板存储在/ Templates / TemplateDirectoryName
  • 我希望能够在模板中使用(预定义的)用户控件。
  • 我使用URL路由,只有1个Default.aspx页面,用于控制需要加载哪个页面模板和附加代码。

这是我到目前为止所提出的:

  • 在我的模板目录中,我有使用母版页创建的模板(主页主文件,默认主文件和引用默认主文件的子主文件...用于产品详细信息,浏览,搜索等)
  • 我的Default.aspx页面根据路由值选择正确的模板

虽然这种方式有效,但我认为它不太实用,但我想的越多,我就越能得出结论,没有太多其他选择可以解决这个问题。我想这就是我想问的问题:有没有办法在模板中使用usercontrol并让模板与应用程序完全分离,以便用户可以创建模板而不必担心网站的命名空间和结构?

亲切的问候, 标记

3 个答案:

答案 0 :(得分:2)

由于您正在引用模板的文件夹,是不是可以只更改文件夹中的.aspx文件,asp.net将根据您提到的URL路径选择模板?我认为在asp.net中这是可能的 此外,像DotNetNuke,Sharepoint,Joomla等框架也有类似的概念。你可以利用他们的功能。

答案 1 :(得分:1)

我建议的解决方案如下。它有一些约束,就像所有母版页需要实现相同的占位符控件集(这并不奇怪)。看看,让我知道你的想法。

我设置了这样的文件夹结构:

网站 - >模板 - > TemplateFolder(与模板命名相同)
网站 - >模板 - > UserControls(用户控件存储在非模板特定文件夹中)

我定义了一个简单的模板配置类,我们可以存储/保存/加载基本模板deffinition:

public class Template
{
    public string TemplateName { get; set; }
    public string UserControlName { get; set; }
    public string MasterPageName { get; set; }

    public string TemplateFolder
    {
        get
        {
            return GetTemplateFolder(TemplateName);
        }
    }

    public string TemplateConfigFile { get { return GetTemplateConfigFile(TemplateName); } }

    private static string GetTemplateFolder(string name)
    {
        return HttpContext.Current.Server.MapPath("~/Templates/" + name + "/");
    }

    private static string GetTemplateConfigFile(string name)
    {
        return GetTemplateFolder(name) + "/" + name + ".config";
    }

    public Template()
    {

    }

    public void Save()
    {
        XmlSerializer xs = new XmlSerializer(typeof(Template));

        if (!Directory.Exists(TemplateFolder)) Directory.CreateDirectory(TemplateFolder);

        using (FileStream fs = File.OpenWrite(TemplateConfigFile))
        {
            xs.Serialize(fs, this);
        }
    }

    public static Template Load(string name)
    {
        if(!File.Exists(GetTemplateConfigFile(name))) return null;

        XmlSerializer xs = new XmlSerializer(typeof(Template));

        using (FileStream fs = File.OpenRead(GetTemplateConfigFile(name)))
        {
            Template t = (Template)xs.Deserialize(fs);

            return t;
        }
    }
}

您可以通过运行以下代码来构建一些裸xml代码:

    Template t1 = new Template() { TemplateName = "Template1", MasterPageName = "Child1.master", UserControlName = "uc1.ascx" };
    Template t2 = new Template() { TemplateName = "Template2", MasterPageName = "Child2.master", UserControlName = "uc2.ascx" };

    t1.Save();
    t2.Save();

我创建了一个基本母版页。除非为您的默认页面提供基本占位符,否则可能永远不会使用此页面。您的所有母版页应该与基本版本具有相同的占位符集,以便您的页面可以互换使用它们。请注意,我为用户控件留下了占位符。

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="BaseMaster.master.cs" Inherits="Templates_Masters_BaseMaster" %>

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

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <asp:ContentPlaceHolder id="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder id="cphHeader" runat="server">

        </asp:ContentPlaceHolder>
        <asp:ContentPlaceHolder id="cpUserControl" runat="server">

        </asp:ContentPlaceHolder>
        <asp:ContentPlaceHolder id="cphFooter" runat="server">

        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>

现在我创建一个使用上述母版页的基本aspx网页。

<%@ Page Title="" Language="C#" MasterPageFile="~/Templates/Masters/BaseMaster.master" AutoEventWireup="true" CodeFile="DefaultTemplated.aspx.cs" Inherits="DefaultTemplated" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="cphHeader" Runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="cpUserControl" Runat="Server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="cphFooter" Runat="Server">
</asp:Content>

在代码隐藏中,我们将设置基本的模板。这将设置母版页并将预定义的用户控件添加到用户控件的内容占位符。如果你想要你可以制作一个面板或其他东西并将其添加到该固定控件,但我想你可能会欣赏如何使它与主页一起使用。

public partial class DefaultTemplated : System.Web.UI.Page
{
    private Template PageTemplate
    {
        get
        {
            if (_tLoaded == null)
            {
                string template = Request.QueryString["template"];
                if (string.IsNullOrEmpty(template)) return null;

                Template t = Template.Load(template);
                _tLoaded = t;
            }

            return _tLoaded;
        }
    }

    private Template _tLoaded = null;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (PageTemplate != null)
        {
            //cpUserControl is the name of my usercontrol placeholder
            ((ContentPlaceHolder)Page.Form.FindControl("cpUserControl")).Controls.Add(
                    Page.LoadControl("~/Templates/UserControls/" + PageTemplate.UserControlName));
        }
    }

    protected void Page_PreInit(object sender, EventArgs e)
    {
        if (PageTemplate == null) return;

        this.MasterPageFile = "~/Templates/" + PageTemplate.TemplateName + "/" + PageTemplate.MasterPageName;
    }
}

如果你有一个名为“Template1”的模板,可以通过调用“Default.aspx?template = Template1”来使用它。由于您使用的是URL重写,因此您可以使用重写将模板名称作为参数传递给页面。

可以与上述结合使用的另一个选项是使用Page.ParseControl。使用它,您可以将原始asp.net设计器代码(仅限设计者)存储在数据库或原始文本文件中。然后你可以实例化它加载它:

//where pnl1 is a Panel on the page.  Page.ParseControl just returns a control object, so use it anywhere.
pnl1.Controls.Add(Page.ParseControl("raw asp.net designer code here."));

关于这一点的一个好处是嵌套控件也能很好地工作。

答案 2 :(得分:0)

我不知道我是否理解正确:

如果您不想重建,那么我可以告诉CMS概念最适合您。

  • 您可以将模板存储为数据库中的HTML,也可以从DB中将其恢复,
  • 您可以使用编辑器提供管理功能,以便在线编辑您的模板。