Best way to inject ASP.NET into pages?

Nov 20, 2010 at 11:15 AM

 I am just wondering if anyone knew of a way to inject ASP.NET into any of the pages in the site? I could upload an aspx file to the directory and just link to it but this isn't ideal as I want to retain the look and feel of the site template on every page i.e. navigation etc and all this seems to be managed in the .view files with macros pulling out posts etc. It would be ideal to have a dynamic link between the content managed stuff and the ASP.NET pages so they all have the same theme with up to date content managed navigation links and other bits and pieces. 

I am building an e-commerce site on top of Graffiti which is why I require the ASP.NET functionality for tasks such as adding products to basket, basket management and checkout procedure.

Thanks, James.

Coordinator
Nov 20, 2010 at 2:18 PM

What exactly are you trying to do on these pages where you want to use standard Asp.Net files? For the most part, the only way to do what you want is to create plugins that either generate macros or widgets that you then put on the pages where you need them. I haven't built an eCommerce system for Graffiti yet, but I'm pretty sure between those two features, you should be able to do most things.

Nov 20, 2010 at 2:39 PM

Thanks for the speedy reply!

The main things I would be utilising the ASP.NET pages for are the basket and checkout so it would consist mainly of connecting to a SQL database and displaying content appropriately, as well as calculations and other bits and pieces that will be required for an e-commerce site. 

Adding records to the database shouldn't be an issue, one way I guess it could be done is to create a link from the submit button to an existing aspx page to submit the data then automatically link back to the page the user was on currently, the main problem I can think of is actually displaying the contents of a dynamic page which will contain ASP.NET such as interactive basket with totals that are automatically calculated etc. 

Coordinator
Nov 20, 2010 at 3:31 PM

I have needed to do this on a couple of sites. Instead of trying to get ASP.NET into Graffiti the route I took was to get my Graffiti theme into an ASP.NET page. To do this, I created a simple library that pulls a Graffiti page and then I can use it as my HTML. I have provided the code below.

[GraffitiMasterpage.cs from my C# library]

using System;
using System.Net;
using System.Text;

namespace AspxIntegrator
{
    public class GraffitiMasterpage
    {
        public GraffitiMasterpage() { }
        public string TemplatePageUrl { get; set; }
        public string Delimiter { get; set; }
        public string PageSection { get; set; }
        public bool Secure { get; set; }
        public string FullyQualifiedDomain { get; set; }

        public string GetPageSection(string pageSection)
        {
            string pageSectionInEnglish = pageSection.ToLower().Trim();
            
            if (pageSectionInEnglish == "first" || pageSectionInEnglish == "top" || pageSectionInEnglish == "header")
                return GetPageSection(0);
            else if (pageSectionInEnglish == "last" || pageSectionInEnglish == "bottom" || pageSectionInEnglish == "footer")
                return GetPageSection(1);
            else
                return "Page section not found.";
        }
        
        public string GetPageSection(int pageSection)
        {
            string pageBody = GetTemplatePage(TemplatePageUrl);
            string[] pageSections = pageBody.Split(new string[] { Delimiter }, StringSplitOptions.RemoveEmptyEntries);
            string sectionHtml;

            try {
                sectionHtml = pageSections[pageSection];
            }
            catch {
                sectionHtml = "Page section not found.";
            }

            string protocol = Secure ? "https://" : "http://";
            string domain = FullyQualifiedDomain.TrimEnd('/');

            return sectionHtml.Replace("http://", protocol)
                .Replace("/files", string.Format("{0}{1}/files", protocol, domain))
                .Replace("href=\"/", string.Format("href=\"{0}{1}/", protocol, domain))
                .Replace("/__utility", string.Format("{0}{1}/__utility", protocol, domain));
        }

        private string GetTemplatePage(string url)
        {
            WebClient wc = new WebClient();
            UTF8Encoding encoder = new UTF8Encoding();

            byte[] requestHtml = wc.DownloadData(url);
            string html = encoder.GetString(requestHtml);

            return html;
        }
    }
}

And then my end ASP.NET page I override the Render like so (while the above is C# the programmer I was working with on the ASP.NET pages used VB.NET below):

    Protected Overloads Overrides Sub Render(ByVal writer As HtmlTextWriter)
        Dim domain As String = "www.domain.com"
        Dim pageTitle As String = "This is a Test Page Title"

        Dim masterpage As New GraffitiMasterpage()
        masterpage.Delimiter = "[GraffitiMasterPage]"
        masterpage.TemplatePageUrl = "https://" & domain & "/masterpage/"
        masterpage.Secure = True
        masterpage.FullyQualifiedDomain = domain

        writer.Write(masterpage.GetPageSection("header").Replace("[MasterpageTitle]", pageTitle))
        MyBase.Render(writer)
        writer.Write(masterpage.GetPageSection("footer"))
    End Sub
Within Graffiti I then have a uncategorized post with a name of 'masterpage' and a title of '[MasterpageTitle]' and the body just has '[GraffitiMasterPage]'.

Hope this is helpful.

Coordinator
Nov 20, 2010 at 3:52 PM

One of the requirements we had for the above was to be able to utilize our approach on a separate website. I had a thought, and just tested to confirm it works, but if you just need ASP.NET pages side-by-side with your Graffiti website you can just override the Render on your ASP.NET site with something like (this assumes you are using the header.view and footer.view files to build out your theme):

    protected override void Render(HtmlTextWriter writer)
    {
        string pageTitle = "My Test Page";
        
        Macros m = new Macros();
        writer.Write(m.LoadThemeView("header.view").Replace("$title", pageTitle));
        base.Render(writer);
        writer.Write(m.LoadThemeView("footer.view"));
    }

Coordinator
Nov 20, 2010 at 4:52 PM

I have an example Graffiti e-commerce-like site that I posted a while back with some examples of a couple of different styles of shopping carts and detailed explanation of how it was done:
http://ecommerce.danhounshell.com/

This example shows using a third-party shopping cart system like google or paypal, but there is no reason you couldn't use your own.

If you want to focus solely on Graffiti then I think building your own chalk extensions would be the best way to go, however ajax-enabling your shopping cart might be an option too. I think you'd probably have to still end up building some custom chalk extensions for things like checkout page, maybe even showing items in your basket, etc.

Also, here's another example for using an Amazon A-store inside a Graffiti site: http://netbookroundup.com/store/ (I think I posted an article on my blog about how to do this, I can dig up the link if anyone finds it useful)

 

Nov 21, 2010 at 5:12 PM
Edited Nov 21, 2010 at 6:56 PM

Brilliant, thanks for all of your replies. Madkidd I have just quickly tried your second example and seems to work really well except it renders "$childContent" in the middle of the page (being pulled from layout.view which I changed as the default theme is using that rather than headers and footers). Is there a way to replace the $childContent with content generated in the ASP.NET page? Obviously you can replace it with a string using the .Replace method but the page is going to need to consist of a lot more..

This is the div being displayed from layout.view:

<div id="content" class="default"> $childContent </div>

Thanks again.

Coordinator
Nov 22, 2010 at 1:14 PM
Edited Nov 22, 2010 at 1:23 PM

Sure, it would just be something like this (did not test to verify working code):

    protected override void Render(HtmlTextWriter writer)
    {
        string pageTitle = "My Test Page";

        Macros m = new Macros();
        string pageLayout = m.LoadThemeview("layout.view");
        string[] pageSections = pageLayout.Split(new string[] { "$childContent" }, StringSplitOptions.RemoveEmptyEntries);
        
        writer.Write(pageSections[0].Replace("$title", pageTitle));
        base.Render(writer);
        writer.Write(pageSections[1]);
    }

Or you can just modify the theme moving all content before $childContent to a header.view all content after to a footer.view and then your layout view would look like this:

    $header
        $childContent
    $footer

 

Nov 24, 2010 at 11:30 AM

Excellent, worked really well. Thanks!

Coordinator
Apr 5, 2011 at 1:52 AM

madkidd -

Just wanted to tell you that I needed to do something like this and both methods worked great. Needed to modify your first code example because I wanted to keep my application separate from the Graffiti site (and I'm using MVC3), but I tried both versions and they worked great. I'll post my MVC3 version here once I have cleaned it up.

Coordinator
Apr 5, 2011 at 3:38 PM
charlesboyung wrote:

madkidd -

Just wanted to tell you that I needed to do something like this and both methods worked great. Needed to modify your first code example because I wanted to keep my application separate from the Graffiti site (and I'm using MVC3), but I tried both versions and they worked great. I'll post my MVC3 version here once I have cleaned it up.

Great! Glad to hear it Charles. I look forward to seeing th MVC version, I am sure that will come in handy.