Search code examples
c#asp.netwebformsintegrationc1-cms

Integrating a Webforms Project with Composite C1


We have developed an ASP.Net Webforms Application, some sort of web shop. Some of the pages only have editorial content, news, articles etc. These contents come from the database right now and are hard to edit for the content writers.

My boss wants me to check if we can use Composite C1 as a CMS and integrate it with the Project.

I have looked into it now and played around with it for some days now, but I am still unsure if it is a good idea and how exactly I would integrate the two systems.

  • The navigation menu and some other permanent parts of the website are drawn from the database and have to be shown on the editorial pages as well.
  • We use SEO friendly URLs (Routing) and the URLs have to stay the same.

How complex will it be to merge the two projects? Will I have to give up the old ASP.Net Website Project and put all my sites into the Composite project? Or will it be possible to run both side by side, even though they have shared navigation menus etc?

Will Routing be a problem?

Has anyone done this kind of merge before? Any experience would be a great help.


Solution

  • C1 is using Webforms to host its content, so there is nothing you can't do which you're doing now within your webforms project. You can use Webforms Masterpages as templates for your content, and routing is fully supported, either through adding as many custom routes as you want or just overriding the default c1 page route. Or relying on the PathInfo Api, where unmatched parts of the url will be available to use on the page that matches the longest possible part of the url. You can also use Razor (.cshtml) in C1 if you like that new syntax from Microsoft.

    You can also turn things around, and choose to render content from C1 on your own existing pages. This code here shows how a standard WebForm .aspx page can be used to render content from a specific page in C1

    public class BaseContentTeaserPage : Page
    {
        private Guid _pageId;
    
        protected PlaceHolder plc;
    
        protected override void OnPreInit(EventArgs e)
        {
            _pageId = Guid.Parse(Request.QueryString["pageId"]);
    
            using (new DataScope(PublicationScope.Published, new CultureInfo("en-GB")))
            {
                using (var data = new DataConnection())
                {
                    PageRenderer.CurrentPage = data.Get<IPage>().Single(p => p.Id == _pageId);
    
                    var urlData = new PageUrlData(PageRenderer.CurrentPage);
                    urlData.PathInfo = Request.QueryString["pathInfo"];
    
                    Context.Items["C1_PageUrl"] = urlData;
                }
            }
    
            base.OnPreInit(e);
        }
    
        protected override void OnLoad(EventArgs e)
        {
            using (new DataScope(PublicationScope.Published, new CultureInfo("en-GB")))
            {
                var content = DataFacade.GetData<IPagePlaceholderContent>().Single(p => p.PageId == _pageId);
    
                var helper = new PageRendererHelper();
                var mapper = (IXElementToControlMapper)helper.FunctionContext.XEmbedableMapper;
                var doc = helper.RenderDocument(content);
                var body = PageRendererHelper.GetDocumentPart(doc, "body");
    
                addNodesAsControls(body.Nodes(), plc, mapper);
    
                if (Page.Header != null)
                {
                    var head = PageRendererHelper.GetDocumentPart(doc, "head");
                    if (head != null)
                    {
                        addNodesAsControls(head.Nodes(), Page.Header, mapper);
                    }
                }
            }
    
            base.OnLoad(e);
        }
    
        private static void addNodesAsControls(IEnumerable<XNode> nodes, Control parent, IXElementToControlMapper mapper)
        {
            foreach (var node in nodes)
            {
                var c = node.AsAspNetControl(mapper);
                parent.Controls.Add(c);
            }
        }
    
        protected override void Render(HtmlTextWriter writer)
        {
            var markupBuilder = new StringBuilder();
            using (var sw = new StringWriter(markupBuilder))
            {
                base.Render(new HtmlTextWriter(sw));
            }
    
            string xhtml = markupBuilder.ToString();
    
            using (Profiler.Measure("Changing 'internal' page urls to 'public'"))
            {
                xhtml = PageUrlHelper.ChangeRenderingPageUrlsToPublic(xhtml);
            }
    
            using (Profiler.Measure("Changing 'internal' media urls to 'public'"))
            {
                xhtml = MediaUrlHelper.ChangeInternalMediaUrlsToPublic(xhtml);
            }
    
            writer.Write(xhtml);
        }
    }