.NET SAMPLES

This section is riddled with code examples and usages for extending the functionality of Umbraco. The examples include the following:

image Remember to check out the download section of the Wrox website for all these code samples.

  • Recreating an XSLT template in .NET to see how the languages compare (pros and cons of each)
  • Rendering a node in a GridView and other standard .NET controls
  • Creating an Umbraco document programmatically
  • Creating a custom data type
  • A simple contact form
  • Hooking up a login form for use with Umbraco members

Clearly you can do a lot more in terms of making Umbraco a fully fledged custom application, but these samples should get you going.

image The downloadable Visual Studio project accompanying this book named UmbUsersGuide.Samples is a solid representation of what your project template should look like. It includes the standard folder structure, all required references to Umbraco libraries, and sample build events to automatically deploy the project DLLs and other files to your website installation.

List Subpages from Current Page

The List Subpages from Current Page macro recreates the same output as one of the existing XSLT templates that you looked at in Chapter 5. See Figure 12-1 for a view of the expected output.

FIGURE 12-1

image

To create your new user control, simply follow these steps:

  1. Right-click the usercontrols folder in your project, as shown in Figure 12-2.

    FIGURE 12-2

    image

  2. Click New Item in the Add submenu, as shown in Figure 12-3.
  3. Select Web User Control, and name your new control ListSubPagesFromCurrentPage.ascx. Then click the Add button, as shown in Figure 12-4.
  4. Add the code from Listing 12-1 to your newly created user control code-behind file.

    FIGURE 12-3

    image

    image The code in Listing 12-1 uses the Umbraco NodeFactory. This class allows you to programmatically query the XML cache, just like discussed in Chapter 11 using XSLT. It's fast, read-only, doesn't make any trips to the database, is ideal for this example, and should always be used when presenting data from the content tree in your .NET code. Later, this chapter covers the Document API, which allows for CRUD operations and interaction with the underlying database.

    FIGURE 12-4

    image

    LISTING 12-1: ListSubPagesFromCurrentPage.ascx.cs

    image
    using System;
    using System.Text;
    using umbraco;
    using umbraco.presentation.nodeFactory;
    
    namespace UmbUsersGuide.Samples.UserControls
    {
        public partial class ListSubPagesFromCurrentPage :
    System.Web.UI.UserControl
        {
            protected void Page_Load(object sender, EventArgs e)
            {
    
                // Get the current node that we are on
                // reflects the node where this control is currently
                // included.
                var n = Node.GetCurrent();
    
                // start html string for output
                var htmlOut = new StringBuilder();
                htmlOut.Append(“<ul>”);
    
                // Loop over the nodes children and generate
                // some HTML to present to the view
                var childNodes = n.Children;
                foreach (Node childNode in  childNodes)
                {
                    htmlOut.Append(“<li>”);
                        htmlOut.AppendFormat(“<a href=”{0}”>{1}</a>”,
                            library.NiceUrl(childNode.Id),
                            childNode.Name);
                    htmlOut.Append(“</li>”);
                }
    
                // finish the html string builder
                htmlOut.Append(“</ul>”);
    
                // Render the HTML in our output panel.
                _outputPanel.Text = htmlOut.ToString();
            }
        }
    }
  5. Add the code from Listing 12-2 to the ListSubPagesFromCurrentPage.ascx file.
  6. Navigate to the macro that you created in the Creating a Macro section and select the newly added .ascx file as the macro file. For a refresher on working with macros see Chapter 5.

LISTING 12-2: ListSubPagesFromCurrentPage.ascx

image
<%@ Control Language=“C#” AutoEventWireup=“true”
CodeBehind=“ListSubPagesFromCurrentPage.ascx.cs”
Inherits=“UmbUsersGuide.Samples.UserControls.ListSubPagesFromCurrentPage” %>
<asp:Literal ID=“_outputPanel” runat=“server”></asp:Literal>

Insert the macro in the Runway master template, and you should see a standard unordered HTML list with the children of the current page nicely linked using the SEO-friendly URLs generated by the Umbraco library NiceUrl method.

Rendering Nodes in a Grid Control

So, you have created some document types that allow your users to work with products in the content tree. One of the requirements for displaying the products is to output all the products and their properties in a sortable table. If you have ever worked with a .NET GridView control you already know that it allows for automatic sorting and paging as long as you provide the data in one of the following ADO.NET formats:

  • DataTable
  • DataSet
  • DataView

Umbraco allows you to render the nodes as a DataTable very easily. See Listing 12-3 for an example of returning nodes in a DataTable type. The corresponding view is shown in Listing 12-4.

LISTING 12-3: ListPagesAsGridView.ascx.cs

image
using System;
using umbraco.presentation.nodeFactory;

namespace UmbUsersGuide.Samples.UserControls
{
    public partial class ListPagesAsGridView : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Get the current node that we are on
            // reflects the node where this control is currently
            // included.
            var n = Node.GetCurrent();

            // Simply set the data source for the GridView
            // and data bind it.
            _nodeGrid.DataSource = n.ChildrenAsTable();
            _nodeGrid.DataBind();
        }
    }
}

LISTING 12-4: ListPagesAsGridView.ascx

image
<%@ Control Language=“C#” AutoEventWireup=“true”
CodeBehind=“ListPagesAsGridView.ascx.cs”
Inherits=“UmbUsersGuide.Samples.UserControls.ListPagesAsGridView” %>
<asp:GridView ID=“_nodeGrid” runat=“server”>
</asp:GridView>

image If you receive a system exception (System.Web.HttpException) when running your newly created macro, the reason is most likely because you are missing the <form id=“1” runat=“server” /> tag in your master page, or you have placed the macro outside of the existing form tag.

Running this code renders all the properties of the returned nodes. You can, of course, further refine this output by working with all the features of the .NET GridView control (such as sorting, paging, DataColumns, and so on).

Creating a Page Programmatically

Programmatically adding content to the tree from user input will sometimes be necessary. A great example of this is if your site supports a knowledgebase or frequently asked questions (FAQ). So, you need to add a form to one of your pages that takes the user's input, maps the various fields to predefined document type properties, and saves the document. You build on this example over the next few sections.

You must first create a new document type (discussed in Chapter 3) so that you have something to work with, as shown in Figure 12-5 and in the following steps.

FIGURE 12-5

image

  1. Right-click Document Types in the Settings section and then click the Create menu item.
  2. In the dialog that appears, name your new document type FAQ, and deselect the Create matching template check box.
  3. Add a new tab called FAQ.
  4. Add the following properties to the new tab:
    • Author {type: Textstring}
    • Category {type: Textstring}
    • Question {type: Richtext Editor}
    • Answer {type: Richtext Editor, mandatory: true}
  5. Save the document type.
  6. Add another document type for the container of the submitted FAQs called FAQ Area with a Richtext Editor property named bodyText and no matching template, allowing FAQ as an allowed child nodetype on this document type.
  7. Choose the Runway Textpage as an allowed template and set it as the default.
  8. In the Structure tab add FAQ Area as an allowed child nodetype on the Runway Homepage document type.
  9. Add FAQ Area as a content node in the content tree. Choose the Content Section and right-click Runway Homepage. Click the Create menu item and choose FAQ Area as the Document Type, as shown in Figure 12-6.

    FIGURE 12-6

    image

  10. Publish the FAQ Area node by clicking the Save & Publish button in the toolbar in the top left-hand corner of the pane.
  11. With that out of the way, create a new user control in the Visual Studio project called CreateFAQ.ascx, as shown in Listings 12-5 and 12-6. Basically, here's what's going on in the code:
    • You set the Umbraco user object that will be the creator of the document. You must reference the umbraco.BusinessLogic assembly to get the user object.
    • You create and save a new Umbraco node using the document API. You must reference the umbraco.cms.businesslogic.web assembly for this.
    • You set some of the FAQ document type properties for this new node based on user input.
    • You redirect user to a Thank You page that you created.

    LISTING 12-5: CreateFAQ.ascx.cs

    image
    using System;
    using umbraco.BusinessLogic;
    using umbraco.cms.businesslogic.web;
    
    namespace UmbUsersGuide.Samples.UserControls
    {
        public partial class CreateFAQ : System.Web.UI.UserControl
        {
            protected void Page_Load(object sender, EventArgs e)
            {
            }
    
            protected void _save_Click(object sender, EventArgs e)
            {
                // need to register a user to associate the newly created
                // document with. Since this is an anonymous user, we'll
                // use the admin account which always has an ID of 0
                User adminUser = new User(0);
    
                // create a new document using the Umbraco Document API
                Document faq = Document.MakeNew(
                    _questionTitle.Text, // this will be the nodeName
                    DocumentType.GetByAlias(“faq”), // get the document
                                        type ID by the alias we created
                    adminUser,
                    1055); // the parent ID where this new page
                              should live (the FAQ Area)
    
                // inject the user input into the document type properties
                // of the FAQ node that was just created above
                faq.getProperty(“question”).Value = _question.Text;
                faq.getProperty(“author”).Value = _yourName.Text;
    
                // We could optionally choose to publish the node here
                // In this case we're not going to as we don't want
                // unreviewd questions to appear on the site.
                //faq.Publish(adminUser);
    
                // This adds the created and published document to
                // the xml cache
                //umbraco.library.UpdateDocumentCache(faq.Id);
    
                // Redirect the user to a Thank You page that we created
                // in the content tree. We use Umbraco's NiceUrl helper
                // method to generate the URL by node id
                Response.Redirect(umbraco.library.NiceUrl(1056), true);
            }
        }
    }

    LISTING 12-6: CreateFAQ.ascx

    image
    <%@ Control Language=“C#” AutoEventWireup=“true”
    CodeBehind=“CreateFAQ.ascx.cs”
    Inherits=“UmbUsersGuide.Samples.UserControls.CreateFAQ” %>
    <fieldset>
        <label>Your Name</label>
        <asp:TextBox ID=“_yourName” runat=“server” />
        <br />
        <label>Question Title</label>
        <asp:TextBox ID=“_questionTitle” runat=“server” />
        <br />
        <label>Question</label>
        <asp:TextBox ID=“_question” TextMode=“MultiLine” Columns=“30”
              Rows=“10” runat=“server” />
        <br />
        <asp:Button ID=“_save” Text=“Submit Question” runat=“server”
            onclick=“_save_Click” />
    </fieldset>

    image In Listing 12-5 you may notice some hardcoded IDs for the parent page as well as the redirect page. This is not ideal as you must recompile the code if any of the nodes change. The section “Passing Data to .NET Through Macro Parameters” details how to add public properties and pass in data as macro parameters to .NET controls.

  12. Create a macro called FAQ Form and point it to the newly created .NET user control. This time, remember to select the Use in editor check box, as shown in Figure 12-7.
  13. In the FAQ Area node's Richtext Editor, add the FAQ From macro and publish the page. The page should render something similar to the top image in Figure 12-8.
  14. Fill out the form and submit it. The Thank You page appears.
  15. To verify that the question was added, simply reload the FAQ Area node and you should see an unpublished node with the title that you added in the form, as shown in Figure 12-9.

image Notice here that you have, by not publishing the programmatically created node, added a small workflow. An editor or administrator will have to review the question, provide an answer, and then publish the FAQ entry to make it public.

FIGURE 12-7

image

FIGURE 12-8

image

FIGURE 12-9

image

Creating a Custom Data Type

Umbraco ships with a lot of different data types and in most cases they are sufficient for standard content management fields. However, in some cases, like the FAQ example that you have been working with, a custom field may be required. Take for instance the category field that you added to the FAQ document type. As it stands now, the editor is forced to type in a value. That is not ideal because typos can be made and typically you want categories to remain standard across all the entries. A better solution might be to query for a set of categories that are stored in a custom table and outside of the Umbraco framework.

This next example shows you just how to do that. Here's the gist of what will go down:

  • You set a manual list of categories in a DataTable and use it as data source for a standard <asp:DropDownList /> control. Of course, in a real-world example you would probably be querying a database or get your data from some live source.
  • You implement the IUsercontrolDataEditor interface to save the selected item as an Umbraco value. To implement this interface you must reference the umbraco.editorControls.userControlGrapper assembly. This interface only has a single member and you need only have a public object type called value with the associated getter and setter methods specified.
  • You use a public class property to pass the selected value to the interface.

To set a manual list of categories, follow these steps.

  1. Create a new user control in your project called CategoriesDT.ascx.
  2. Add the code from Listings 12-7 and 12-8 to your new user control.

LISTING 12-7: CategoriesDT.ascx.cs

image
using System;
using System.Data;
using umbraco.editorControls.userControlGrapper;

namespace UmbUsersGuide.Samples.UserControls
{
    public partial class CategoriesDT : System.Web.UI.UserControl,
                                        IUsercontrolDataEditor
    {
        public string UmbracoValue = “”;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                // Wire up the dropdownlist and load the
                // data items
                _categories.DataSource = GetCategories();
                _categories.DataTextField = “Name”;
                _categories.DataValueField = “ProductID”;
                _categories.DataBind();
            }
            // if this is a postback, set the UmbracoValue
            // public property so we can reference the value
            // in the implemented interface below
            else if (Page.IsPostBack)
            {
                UmbracoValue = _categories.SelectedValue;
            }

            // If there is a saved value, always set it as the
            // [selected] value of the control
            if (!UmbracoValue.Equals(“”))
            {
                _categories.Items.FindByValue(UmbracoValue).Selected = true;
            }
        }

        private DataTable GetCategories()
        {
            // Setup the data table columns so tha we can
            // populate them below.
            DataTable dt = new DataTable();
            dt.Columns.Add(“ProductID”, Type.GetType(“System.Int32”));
            dt.Columns.Add(“Name”, Type.GetType(“System.String”));

            // populate with static data
            DataRow dr = dt.NewRow();
            dr[“ProductID”] = 1;
            dr[“Name”] = “Technical Questions”;
            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr[“ProductID”] = 2;
            dr[“Name”] = “Backoffice Interface”;
            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr[“ProductID”] = 3;
            dr[“Name”] = “Permissions”;
            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr[“ProductID”] = 4;
            dr[“Name”] = “Custom Functionality”;
            dt.Rows.Add(dr);

            return dt;
        }

        #region IUsercontrolDataEditor Members

        public object value
        {
            get
            {
                // if there is no value, set the value to null
                // otherwise use the selected value
                return UmbracoValue;
            }
            set
            {
                // When the control is loaded in the backoffice,
                // check if there is a saved value. If so, set the
                // matching item in the dropdownlist to selected.
                if (value != null &&
                      !String.IsNullOrEmpty(value.ToString()))
                {
                    UmbracoValue = value.ToString();
                }
            }
        }

        #endregion
    }
}

LISTING 12-8: CategoriesDT.ascx

image
<%@ Control Language=“C#” AutoEventWireup=“true”
CodeBehind=“CategoriesDT.ascx.cs”
Inherits=“UmbUsersGuide.Samples.UserControls.CategoriesDT” %>
<asp:DropDownList ID=“_categories” runat=“server”>
</asp:DropDownList>

image All that is happening in Listing 12-7 is that the public object is getting the value and performing a save to the document type property (in this case, category). Then upon loading of this custom data type, the public object value is returned and matched to an existing item in the dropdown (the list of items from the database).

The only thing left to do is add the CategoriesDT user control as a data type in the backoffice and switch out the document type control with the new data type.

  1. Navigate to the Developer section.
  2. Right-click the Data Types node and click the Create menu item.
  3. In the dialog that appears, name your new data type FAQ Categories and click the Create button.
  4. In the resulting right-hand pane, select umbraco user control wrapper as the Render Control and click the Save button.
  5. Leave the Database data type as Ntext and choose the new user control from the dropdown, as shown in Figure 12-10.
  6. Save the data type again.

    image If you change the Database data type after values have already been saved using the data type, you will lose all the saved data. So, choose carefully when creating your new data types.

  7. Navigate to the FAQ document type in the Settings section.
  8. In the Generic Settings tab, change the Type of the Category property to FAQ Categories, and click Save.
  9. Navigate to the Content section and open the submitted question; notice that you now have a handy drop-down control listing the categories.

As always with Umbraco multiple solutions exist. Other options to make this data type even more flexible in terms of data source would be:

  • Populate the drop-down control with a set of nodes of a specific type. For example, you could create a document type for FAQ Categories that would have the Name and Id properties, then iterate over the nodes of that document type.
  • For the FAQ Categories example, you could just as well have created a new data type based on the Dropdown List data type and hard-coded the prevalues.

In fact if you ask ten Umbraco developers how they would go about solving this problem, you would probably end up with at least eight different answers.

FIGURE 12-10

image

Sending Email with a Contact Form

This section's example is a very popular feature on most websites. It's a simple contact form that allows you to send an email to a specified email address with the contents of the form. As usual, Umbraco leverages the standard .NET mail classes and settings to accomplish this. It even comes with a handy library method called SendMail that you can use to send simple emails (as shown by the bolded code in Listing 12-9). All you need to do is set up an email server in the Web.config. The default installation is configured for localhost, as shown in the following.

<system.net>
    <mailSettings>
        <smtp>
            <network host=“127.0.0.1” userName=“username” password=“password” />
        </smtp>
    </mailSettings>
</system.net>

To configure Umbraco to use your own SMTP (simple mail transport protocol) server, follow these steps:

  1. Open up the web.config file located in <install root>web.config.
  2. Find the settings for the SMTP server by searching for <system.net />.
  3. Change the host, username, and password attributes to values matching your server and user (set by your hosting provider or network administrator).

image For testing purposes in your development environment, you can configure the SMTP service with the following settings. This will simply write the results to a local file as specified in the pickupDirectoryLocation path.

<system.net>
  <mailSettings>
    <smtp deliveryMethod=“SpecifiedPickupDirectory” >
      <specifiedPickupDirectory
         pickupDirectoryLocation=“C:	estdropfolder”/>
    </smtp>
  </mailSettings>
</system.net>

All you have to do is set it to an SMTP server that you have access to and authority to relay through. Without further ado, see Listings 12-9 and 12-10 for this example.

LISTING 12-9: ContactForm.ascx.cs

image
using System;

namespace UmbUsersGuide.Samples.UserControls
{
    public partial class ContactForm : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Page.IsPostBack)
            {
                // hide the form
                _formView.Visible = false;

                // Show the Thank You Message
                _messageView.Visible = true;
            }
        }

        protected void _sendEmail_Click(object sender, EventArgs e)

        {
            // send an email using the Umbraco libray SendMail method
            umbraco.library.SendMail(_emailAddress.Text,
                   [email protected]”,
                   “Someone filled out the contact form!”,
                    _message.Text, true);
        }
    }
}

LISTING 12-10: ContactForm.ascx

image
<%@ Control Language=“C#” AutoEventWireup=“true”
CodeBehind=“ContactForm.ascx.cs”
Inherits=“UmbUsersGuide.Samples.UserControls.ContactForm” %>
<asp:Panel ID=“_formView” runat=“server”>
    <fieldset>
        <label>Your Name</label>
        <asp:TextBox ID=“_yourName” runat=“server” />
        <br />
        <label>Your Email Address</label>
        <asp:TextBox ID=“_emailAddress” runat=“server” />
        <br />
        <label>Your Phone Number</label>
        <asp:TextBox ID=“_phone” runat=“server” />
        <br />
        <label>Message</label>
        <asp:TextBox ID=“_message” TextMode=“MultiLine”
               Columns=“30” Rows=“10” runat=“server” />
        <br />
        <asp:Button ID=“_sendEmail” Text=“Send Email” runat=“server”
            onclick=“_sendEmail_Click” />
    </fieldset>
</asp:Panel>
<asp:Panel ID=“_messageView” Visible=“false” runat=“server”>
</asp:Panel>

Passing Data to .NET Through Macro Parameters

Throughout all the examples so far you have probably noticed that a lot of hard-coding values have taken place. For example, when creating a document, wouldn't it be nice to pass in the ParentId of the node where you want to create the FAQs? Or, in the contact form, wouldn't it be great if the To Email address could be set dynamically, allowing you to reuse the form in multiple places for multiple reasons?

Chapter 5 discusses macro parameters and how to use them. Well, you can use these macro parameters to pass data to your .NET user controls via public properties.

To demonstrate, let's modify the preceding example where the FAQ question was created, and pass in the ParentId and the ThankYouId using macro parameters. The bolded code in Listing 12-11 shows the added or changed code.

LISTING 12-11: CreateFAQ.ascx.cs

using System;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;

namespace UmbUsersGuide.Samples.UserControls
{
    public partial class CreateFAQ : System.Web.UI.UserControl
    {
        public int ParentId { get; set; }
        public int ThankYouId { get; set; }
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void _save_Click(object sender, EventArgs e)
        {
            // need to register a user to associate the newly created
            // document with. Since this is an anonymous user, we'll
            // use the admin account which always has an ID of 0
            User adminUser = new User(0);

            // create a new document using the Umbraco Document API
            Document faq = Document.MakeNew(
                _questionTitle.Text, // this will be the nodeName
                DocumentType.GetByAlias(“faq”), // get the document type ID
                                                   by the alias we created
                adminUser,
                ParentId); // the parent ID where this new
                              page should live (the FAQ Area)

            // inject the user input into the document type properties
            // of the FAQ node that was just created above
            faq.getProperty(“question”).Value = _question.Text;
            faq.getProperty(“author”).Value = _yourName.Text;

            // We could optionally choose to publish the node here
            // In this case we're not going to as we don't want
            // unreviewed questions to appear on the site.
            //faq.Publish(adminUser);

            // This adds the created and published document to
            // the xml cache
            //umbraco.library.UpdateDocumentCache(faq.Id);

            // Redirect the user to a Thank You page that we created

            // in the content tree. We use Umbraco's NiceUrl helper
            // method to generate the URL by node id
            Response.Redirect(umbraco.library.NiceUrl(ThankYouId), true);
        }
    }
}

When you have built the altered user control and deployed it to your Umbraco installation, adding these public properties as Umbraco macro parameters is a breeze:

  1. Navigate to the Developers section and select the FAQ Form macro.
  2. As shown in Figure 12-11, click the Browse properties button.

    FIGURE 12-11

    image

  3. In the resulting dialog, you will see the two properties that you added—ParentId and ThankYouId—already preselected for your convenience. Simply click Save Properties and Umbraco will turn them into macro parameters automatically.
  4. There's one more thing that you want to do before re-adding this macro to your page. Navigate to the Parameters tab and set the Type of the two parameters to contentPicker, as shown in Figure 12-12. This allows you to choose the nodes from the content tree instead of typing in the node Id of the page.

Now, when you go to re-add the FAQ form to the FAQ Area page, you will be prompted to select the corresponding Parent and Thank You pages, as shown in Figure 12-13.

image You may also want to change the Name attribute of the parameter to be more user friendly, but this is completely optional from a functional standpoint.

The most obvious benefit of working with public properties and macro parameters is that you have now removed the requirements of code changes if you need to update where the submitted FAQs should be saved or what page to redirect the user to upon submission.

FIGURE 12-12

image

FIGURE 12-13

image

Creating a Login Macro

If you must deal with personalized or restricted content in your website, you need the ability to have users log in by providing member account credentials. As mentioned earlier in this book, Umbraco implements the standard .NET Membership Provider model. This means that you can pretty much just drag and drop the various login controls onto your user controls and be done! Well, at least theoretically. You need to perform a few configurations to get this working.

Chapter 2 provides details on how to work with members—adding member types, member groups, and the member details. To get the standard Umbraco Membership Provider to work, only two things need to happen:

  1. Add at least one Member Type to the Members section.
  2. Configure the UmbracoMembershipProvider key in Web.config to have the defaultMemberTypeAlias attribute match one of your configured Member Types.

image You can find the membership providers configuration in the <system.web><membership /></system.web> node in Web.config.

That's it! Now, all you need to do is add an <asp:Login /> control to a user control and create a macro for it. See Listings 12-12 and 12-13 for an example (be aware that it is alarmingly simple).

LISTING 12-12: Login.ascx.cs

image
using System;

namespace UmbUsersGuide.Samples.UserControls
{
    public partial class Login : System.Web.UI.UserControl
    {
        // The default redirect page after logging in
        public int LoginRedirectPage { get; set; }
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            _loginForm.LoggedIn += LoginUser_LoggedIn;
        }

        // When the user has successfully authenticated
        // redirect them to the specified page
        void LoginUser_LoggedIn(object sender, EventArgs e)
        {
            // Redirect the user to a specified page
            Response.Redirect(umbraco.library.NiceUrl(LoginRedirectPage));
        }

        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}

image The OnInit override is not even needed here. It's simply there to provide an example of how to redirect users to a specific page upon login as a configurable item.

LISTING 12-13: Login.ascx

image
<%@ Control Language=“C#” AutoEventWireup=“true” CodeBehind=“Login.ascx.cs”
 Inherits=“UmbUsersGuide.Samples.UserControls.Login” %>
<asp:Login ID=“_loginForm” runat=“server”>
</asp:Login>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset