Click here to Skip to main content
Click here to Skip to main content

Integrating Visual Studio LightSwitch Application Into An Existing Website using IFrames

, 25 Oct 2011 Ms-PL
Rate this:
Please Sign up or sign in to vote.
An advanced LightSwitch tutorial covering PreProcess Queries, Email, PopUps, WCF RIA Services, and HTML pages

 

Live example:

http://lightswitchhelpwebsite.com/Demos/ThingsForSale.aspx

For an introductory article on LightSwitch, see:

http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/12/Online-Ordering-System-An-End-To-End-LightSwitch-Example.aspx

Note: You must have Visual Studio Professional, or higher, to perform all the steps in this tutorial

You can download Visual Studio LightSwitch from this link:

http://www.microsoft.com/visualstudio/en-us/lightswitch

Putting Multiple LightSwitch Applications Into Your Website

Microsoft Visual Studio LightSwitch suffers from what I call the "full screen limitation". LightSwitch wants to fill the entire screen, and it wants to manage the roles and users. This is fine if you only have one application, however in many situations, you want a LightSwitch application to be part of a group of applications in a single portal. You want all applications to share the same users, roles and database.

Unlike the article Online Ordering, that describes a normal "LightSwitch only" deployment, this article will explore the techniques used to deploy a LightSwitch application inside a ASP.NET application that contains other applications. In this article, DotNetNuke will be used, however, everything here can be used in any ASP.NET application.

The key to integrating LightSwitch into an ASP.NET application, is to use IFrames.

The Requirements

In this example, we will create an application that meets the following requirements:

  • Allow Registered Users (the Posters), the ability to create Posts of things they have for sale, without the need to post their email address
  • Allow Anonymous Users (the Buyers) the ability to see the Posts without requiring them to have the Silverlight plug-in installed
  • Allow the Buyers the ability to respond to a Post, and automatically email the Poster
  • Allow the Poster the ability to view and respond to all communications sorted by Post
  • Allow Administrators the ability to edit all data

This may not be considered a large application, but it would take a few days effort. With LightSwitch, you can create the entire application in about an hour.

Walk-Thru Of The 'Things For Sale' Application

 

You can try out the live Things For Sale application at this link: http://lightswitchhelpwebsite.com/Demos/ThingsForSale.aspx

When you are not logged-in, you will see a list of Posts that you can browse.

You can click on a Post to send the Poster a message.

When you log in, you will have the ability to create Posts, and to see any Messages related to a Post (you will be emailed when a new Message is created for one of your Posts).

Also note, that there are a lot of other features such as Concurrency Checking and Automatic Ellipses that LightSwitch implements automatically.

Creating The Application

You can download Visual Studio LightSwitch from this link:

http://www.microsoft.com/visualstudio/en-us/lightswitch

After installing it, use File, New Project to create a LightSwitch application.

Double-click on Properties in the Solution Explorer.

Set the application as a Web application.

Set it to use Forms Authentication.

Categories Table And Screen

Creating a table for Categories and a screen to edit them, is a task that can be completed in under a minute.

Right-click on the Data Sources node in the Solution Explorer, and select Add Table.

Click on the table name to change the name. Enter Category for the name.

Create the table above.

Right-click on the Screens node, and select Add Screen...

Create an Editable Grid Screen using Categories (LightSwitch automatically 'pluralizes' the name of the table).

The screen will display. 

Hit F5 to run the application.

We can now create Categories in the application.

Close your web browser to stop the application.

Create The Remaining Tables

Create a Post table with the schema above.

Create a Message table with the schema above.

Create Relationships

Open the Message table, and click the Relationship button.

In the Add New Relationship box, enter the settings above.

Open the Post table.

In the Add New Relationship box, enter the settings above.

The relationships are complete.

Setting relationships is very important with LightSwitch. It allows important features, such as allowing you to create screens, where the Posts and the Messages related to the Posts, always stay in sync, without requiring any code.

It is very rare for any Entity (table) to not have a relationship to one or more other Entities.

Set Default Values On Record Creation

Open the Message table, and select Write Code, then Message Created.

Change the method to the following:

         partial void Message_Created()
        {
            this.MessageCreated = DateTime.UtcNow;   
        }

This will set the date for a Message when it is created. Notice that we are using "UtcNow" so that the time is recorded in Coordinated Universal Time (UTC) time. When we display the time, we can convert it to the user's local time.

Open the Post table, and select Write Code, then Post Updating.

Change the method to the following:

         partial void Posts_Updating(Post entity)
        {
            entity.PostUpdated = DateTime.UtcNow;
        }

Open the Post table, and select Write Code, then Post Created.

Change the method to the following:

         partial void Post_Created()
        {
            this.PostedBy = this.Application.User.Name;
            this.PostCreated = DateTime.UtcNow;
            this.PostUpdated = DateTime.UtcNow;
            this.Active = true;
        }

Note the line:

this.PostedBy = this.Application.User.Name;

This is all that is required to segment the data by user.

At run-time, the DotNetNuke site (or any ASP.NET site running under Forms Authentication), will provide the username for "this.Application.User.Name".

In a later step, we will use a PreProcess query to restrict a user to only see their own Posts (and Messages).

Sending Emails

This application will require emails to be sent. Let's enable that functionality now.

To do this, we will need to switch to File View.

In the Server project, add references to System.configuration and System.Messaging.

Add a class called MailHelper.cs to the UserCode folder of the Server project.

Use the following code:

// Adapted from:
// http://www.paulspatterson.com/technology/lightswitch/
//   microsoft-lightswitch-sending-emails-from-the-client/#more-2896

using System.Net;
using System.Net.Mail;
using System.Configuration;
using System;

namespace LightSwitchApplication
{
    public class MailHelper
    {
        private string _SMTPSendingEmailAddress { get; set; }
        private string _SMTPServer { get; set; }
        private string _SMTPUserId { get; set; }
        private string _SMTPPassword { get; set; }
        private int _SMTPPort { get; set; }
        private bool _SMTPSSL { get; set; }

        private string _MailFromName { get; set; }
        private string _MailToEmail { get; set; }
        private string _MailToName { get; set; }
        private string _MailSubject { get; set; }
        private string _MailBody { get; set; }

        public MailHelper(
            string SendFromName, string SendToEmail,
            string SendToName, string Subject,
            string Body)
        {
            _MailFromName = SendFromName;
            _MailToEmail = SendToEmail;
            _MailToName = SendToName;
            _MailSubject = Subject;
            _MailBody = Body;

            _SMTPSendingEmailAddress = Convert.ToString(ConfigurationManager.AppSettings["SMTPSendingEmailAddress"]);
            _SMTPServer = Convert.ToString(ConfigurationManager.AppSettings["SMTPServer"]);
            _SMTPUserId = Convert.ToString(ConfigurationManager.AppSettings["SMTPUserID"]);
            _SMTPPassword = Convert.ToString(ConfigurationManager.AppSettings["SMTPPassword"]);
            _SMTPPort = Convert.ToInt32(ConfigurationManager.AppSettings["SMTPPort"]);
            _SMTPSSL = Convert.ToBoolean(ConfigurationManager.AppSettings["SMTPSSL"]);
        }

        public void SendMail()
        {
            MailMessage mail = new MailMessage();

            System.Net.Mail.MailAddress mailFrom =
                new System.Net.Mail.MailAddress(_SMTPSendingEmailAddress, _MailFromName);

            System.Net.Mail.MailAddress mailTo =
                new System.Net.Mail.MailAddress(_MailToEmail, _MailToName);

            var _with1 = mail;
            _with1.From = mailFrom;
            _with1.To.Add(mailTo);
            _with1.Subject = _MailSubject;
            _with1.Body = _MailBody;

            SmtpClient smtp = new SmtpClient(_SMTPServer, _SMTPPort);
            smtp.EnableSsl = _SMTPSSL;

            smtp.Credentials =
                new NetworkCredential(_SMTPUserId, _SMTPPassword);

            smtp.Send(mail);
        }
    }
}

Click on the project name in the Solution Explorer, then select Show All Files.

This will allow you to see the ServerGenerated project.

This project is created by LightSwitch and used when LightSwitch is deployed as a web application. It is the place where we will eventually place the .aspx files that will generate the HTML pages. For now, we only want to add some entries to the Web.config file:

This will allow us to easily change the SMTP Mail Server settings when the application is deployed.

Switch back to Logical View.

Open the Message table, and select the Messages_Inserted method.

Use the following code for the method (to send the email):

        #region Messages_Inserted
        partial void Messages_Inserted(Message entity)
        {
            string strSubject = "Message From ThingsForSale";

            string strMessage = String.Format("{0}", 
                "This is a message From the Things For Sale program.") 
                + Environment.NewLine + Environment.NewLine;

            strMessage = strMessage + String.Format("Regarding the post '{0}'", 
                entity.Post.Description) + Environment.NewLine;

            strMessage = strMessage + String.Format("This message was sent by {0}",
                entity.NameFrom) + Environment.NewLine + Environment.NewLine;

            strMessage = strMessage + String.Format("Message: {0}", 
                entity.MessageText) + Environment.NewLine;

            // Create the MailHelper class created in the Server project.
            MailHelper mailHelper =
                new MailHelper(
                    entity.NameFrom,
                    entity.EmailTo,
                    entity.NameTo,
                    strSubject,
                    strMessage);

            // Send Email
            mailHelper.SendMail();
        }
        #endregion

Create The Posts And Messages Screen

In the Solution Explorer, right-click on the Screens node and select Add Screen...

Create a List and Details Screen.

Note: because we created relationships between the tables, we can enable Posts and Messages to be on the same screen, by simply checking a box.

The screen will show.

When you run the application, you will be able to enter Posts and Messages.

Deploy Application Into A DotNetNuke Website

Follow the directions here to deploy the application into a DotNetNUke website: Easy DotNetNuke LightSwitch Deployment.

We now have the basic layout illustrated above. The LightSwitch application is running in an IFrame and has the same Database Connection, MachineKey, and Forms Cookie, so it is able to communicate with the DotNetNuke site hosting it, and share user authentication.

For many applications, this is enough. In our example we need to determine if a user is an Administrator or not, because we want to provide additional features to Administrators.

We could simply add the DotNetNuke user and roles tables to the LightSwitch application as external tables, but I have found that this can sometimes cause the user table to lock (see this link for more information).

Adding a WCF RIA Service prevents any locking issues.

Creating A WCF RIA Service

(note: you must have Visual Studio Professional, or higher, to perform the following steps)

(see this link for official information on creating WCF RIA Services for LightSwitch)

Add a New Project.

Create a new Class Library.

Right-click on the Class1.cs file that is created and delete it.

Add a Entity Data Model...

Connect to the DotNetNuke database.

Normally we only need to add the vw_UserRoles view to determine if a user is an Administrator or not.

However, we will also add the Category, Post, and Message tables, because we will also use the Entity Data Model for the .aspx (HTML) pages that we will create in a later step.

Build the project.

Add a Domain Service Class.

We only need the vw_userRoles in the Domain Service Class. Also, un-check Enable client access for added security because we wont need it.

The Domain Service Class will be created.

Add [Query(IsDefault = true)] to the top of the method (that is automatically created).

Save the file and Build Solution.

Right-click on the Data Sources node, and select Add Data Source...

Select WCF RIA Service and click Next.

(do not be surprised if the box goes away and nothing happens for a long time. Also the box may now be hidden behind the Visual Studio main window)

Click Add Reference.

Select the Data Project and click OK.

Wait for the Domain Service Class to appear in the list box. Sometimes it can take 1-2 minutes.

When it appears, select it, and click Next.

Select the Entity to use by checking it's box (in this case we want to use the vw_UserRoles)

Don't bother entering anything for the Connection String because we will set it in the Web.config manually.

Click Finish.

The data source will show up.

Copy the connection string from the App.config of the data project.

Switch to File View, and open the Web.config, and add the connection string.

Using The WCF RIA Service

To demonstrate how we can use our new WCF RIA Service, open the EditableCategoriesGrid screen and select the EditableCategoriesGrid_CanRun event.

Change the method to the following code:

        partial void EditableCategoriesGrid_CanRun(ref bool result)
        {
            // Must be an Administrator for this link to show            
            var WorkSpace = this.CreateDataWorkspace();

            var UserInRole = (from DNNUser in WorkSpace.DNNDomainServiceData.vw_UserRoles
                              where DNNUser.Username == this.User.Name
                              where DNNUser.RoleName == "Administrators"
                              select DNNUser).FirstOrDefault();

            result = (UserInRole != null);       
        }

Click on the project in the Solution Explorer.

This will allow you to select Publish.

Re-publish the application

You will have to redo all the changes you made to the web.config when you followed the directions described in Easy DotNetNuke LightSwitch Deployment because new things have been added to the web.config when we created the WCF RIA Service.

When you run the application in the DotNetNuke website, only an administrator will see the link to edit the Categories.

Enabling Security Using A Pre-Process Query

 

One of the requirements is that an administrator can see all Posts, but a non-administrator can only see their own Posts (and Messages).

Open the Posts Entity, and select Posts All PreprocessQuery

Change the code to the following:

         partial void Posts_All_PreprocessQuery(ref IQueryable<Post> query)
        {
            // Only run this PreProcess Query if user is Authenticated
            if (this.Application.User.IsAuthenticated)
            {
                string UserName = this.Application.User.Name;

                // Connect to DotNetNuke Data
                var WorkSpace = this.Application.CreateDataWorkspace();

                var UserInRole = (from DNNUser in WorkSpace.DNNDomainServiceData.vw_UserRoles
                                  where DNNUser.Username == UserName
                                  where DNNUser.RoleName == "Administrators"
                                  select DNNUser).FirstOrDefault();

                // If User is not an Administrator 
                // The User can only see their own posts
                if (UserInRole == null)
                {
                    query = query.Where(x => x.PostedBy == this.Application.User.Name);
                }
            }
        }

Modal Windows (PopUps)

 

Modal Windows (otherwise known as Popups) are an important User Interface tool because the require the user to complete the task set before them before doing anything else.

In this sample application we want Popups to show when a user is viewing an existing Message or responding to a Message.

There are other Popups, but they are created automatically by LightSwitch.

 

Currently, when an existing Message is opened, it shows all the fields like the image above. 

We desire the PopUp to resemble the image above.

To do this, we will make our own PopUp and then override the code that opens the current PopUp, to open our PopUp.

 

In the screen designer, select the Details Column, then Add the Selected Item for Messages.

It will display.

Change the section to a Modal Window.

Change all the TextBoxes to Labels and delete the remaining items.

Select the Modal Window, and note the name of the window. Uncheck the Show Button box (otherwise LightSwitch would show a button at the bottom of the screen to open the window).

Click on the Messages Data Grid, expand the Command Bar, right-click on the Edit button, and select Override Code.

Change the code to the following:

         partial void MessagesEditSelected_Execute()
        {
            this.OpenModalWindow("Messages_SelectedItem");
        }

Now if we select the Edit button it opens our custom Popup.

We will add a Respond button in the next step, that will allow us to actually create a Message, as a response to a Message entered in the HTML page (to be created in a later step).

Note: To understand the next steps, it is suggested that you read: This Is How LightSwitch Does MVVM.

Switch to File View, and add a Reference, in the Client project, to System.Windows.Controls (this is so we can programmatically interact with a PopUp as a ChildWindow).

Select Add Data Item...

Create a Local Property of type Message and call it Message_Response.

It will show on the screen's "View Model" (see: This Is How LightSwitch Does MVVM for an explanation of View Model).

Select the Details Column section, and add the Message Response property to the screen.

Change it to Modal Window.

The properties will show.

  • Remove all the controls except the Name To, Email To, and Message Text
  • Change the Name To to a Label
  • In the Properties of the Modal Window, uncheck Show Button

Add a Button to the Command Bar of the Modal Window and call it SaveResponse.

In the Properties for the Button, change the Display Name to Save Message.

Right-click on the Button, and select Edit Execute Code

Change the code to:

         #region SaveResponse_Execute
        partial void SaveResponse_Execute()
        {
            this.CloseModalWindow("Message_Response");
            this.Save();
        } 
        #endregion

Navigate up the object tree to the Command Bar for the Messages Data Grid, and delete the Add button, and add a New Button.

Call it RespondToMessage.

Drag it to the top of the other two remaining buttons, and right-click on it and select Edit Execute Code.

use the following code to create a new Message and open the Popup, also to detect when the PopUp is closed (when clicking the x in the upper right corner of the Popup), and to remove any unsaved Messages:

         #region RespondToMessage_Execute
        partial void RespondToMessage_Execute()
        {
            // Create a new Message
            Message_Response = new Message();

            //Set the Post
            Message_Response.Post = Posts.SelectedItem;

            // Set Email defaults
            Message_Response.MessageBy = this.Application.User.Name;

            // these values are from the currently selected Message
            Message_Response.NameFrom = Messages.SelectedItem.NameTo;
            Message_Response.EmailFrom = Messages.SelectedItem.EmailTo;
            Message_Response.NameTo = Messages.SelectedItem.NameFrom;
            Message_Response.EmailTo = Messages.SelectedItem.EmailFrom;

            this.OpenModalWindow("Message_Response");

            // Wire up an event to detect when the Modal window is closed
            this.FindControl("Message_Response").ControlAvailable +=
                new EventHandler<ControlAvailableEventArgs>(PostsListDetail_ControlAvailable);
        } 
        #endregion

        #region PostsListDetail_ControlAvailable
        void PostsListDetail_ControlAvailable(object sender, ControlAvailableEventArgs e)
        {
            ChildWindow window = (ChildWindow)e.Control;
            window.Closed += new EventHandler(Message_Response_Closed);
        }
        #endregion

        #region Message_Response_Closed
        void Message_Response_Closed(object sender, EventArgs e)
        {
            ChildWindow window = (ChildWindow)sender;
            if (!(window.DialogResult.HasValue))
            {
                // Remove unsaved records            
                foreach (Message message in this.DataWorkspace.ApplicationData.Details.GetChanges()
                    .AddedEntities.OfType<Message>())
                {
                    message.Details.DiscardChanges();
                }
            }
        }
        #endregion

You will also need to add using System.Windows.Controls; to the top of the class.

Creating HTML Pages

Switch to File View.

Add a Reference to System.configuration to the ServerGenerated project.

Add a .aspx page called PublicPage.aspx, and use the following code for the code behind (please get the HTML code from the download):

using DNNData;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text.RegularExpressions;
using System.Transactions;
using System.Web.UI;
using System.Web.UI.WebControls;
using LightSwitchApplication;

namespace ApplicationData.Implementation
{
    public partial class PublicPage : System.Web.UI.Page
    {
        #region CurrentPage
        public int CurrentPage
        {
            get
            {
                if (ViewState["CurrentPage"] == null)
                {
                    return 1;
                }
                else
                {
                    return (int)ViewState["CurrentPage"];
                }
            }
            set
            {
                ViewState["CurrentPage"] = value;
            }
        }
        #endregion

        #region CurrentPostID
        public int CurrentPostID
        {
            get
            {
                if (ViewState["CurrentPostID"] == null)
                {
                    return -1;
                }
                else
                {
                    return (int)ViewState["CurrentPostID"];
                }
            }
            set
            {
                ViewState["CurrentPostID"] = value;
            }
        }
        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                GetPosts(true, CurrentPage);
            }
        }

        #region GetPosts
        private void GetPosts(bool FillCategories, int intPage)
        {
            // Collections to hold the final results
            List<DNNData.Category> lstCategories = new List<DNNData.Category>();

            // Connect to DotNetNuke Data
            string _IntrinsicData = Convert.ToString(ConfigurationManager.ConnectionStrings["DotNetNuke5Entities"]);
            DotNetNuke5Entities db = new DotNetNuke5Entities(_IntrinsicData);

            int intCategoryID = -1;

            // Get selected category
            if (!FillCategories)
            {
                intCategoryID = Convert.ToInt32(ddlCategories.SelectedValue);
            }

            if (FillCategories)
            {
                // execute query
                var colCatagories = (from Cat in db.Categories
                                     select Cat).ToList();

                // Add an All option
                DNNData.Category objCategory = new DNNData.Category();
                objCategory.Id = -1;
                objCategory.CategoryName = "All";
                lstCategories.Add(objCategory);

                // Add Categories
                foreach (var item in colCatagories)
                {
                    lstCategories.Add(item);
                }

                // We now have the results - bind then to the dropdown
                ddlCategories.DataSource = lstCategories;
                ddlCategories.DataBind();
            }

            // Get Posts

            // create query
            var colPosts = from PST in db.Posts
                           select PST;

            // Get active posts
            colPosts = colPosts.Where(x => x.Active == true);

            // Get Category
            if (intCategoryID != -1)
            {
                colPosts = colPosts.Where(x => x.Category.Id == intCategoryID);
            }

            // Do paging
            colPosts =
                colPosts.OrderByDescending(x => x.PostUpdated).
                Skip(((intPage - 1) * 10)).Take(10);

            // We now have the results - bind then to the dropdown
            gvPosts.DataSource = colPosts;
            gvPosts.DataBind();

        }
        #endregion

        #region ddlCategories_SelectedIndexChanged
        protected void ddlCategories_SelectedIndexChanged(object sender, EventArgs e)
        {
            pnlMessage.Visible = false;
            GetPosts(false, CurrentPage);
        }
        #endregion

        #region btnLeft_Click
        protected void btnLeft_Click(object sender, EventArgs e)
        {
            pnlMessage.Visible = false;

            if (CurrentPage > 1)
            {
                CurrentPage--;
            }

            GetPosts(false, CurrentPage);
        }
        #endregion

        #region btnRight_Click
        protected void btnRight_Click(object sender, EventArgs e)
        {
            pnlMessage.Visible = false;

            if (gvPosts.Rows.Count > 0)
            {
                CurrentPage++;
            }

            GetPosts(false, CurrentPage);
        }
        #endregion

        #region gvPosts_RowCommand
        protected void gvPosts_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            LinkButton lnkButtton = (LinkButton)e.CommandSource;
            CurrentPostID = Convert.ToInt32(lnkButtton.CommandArgument);

            pnlMessage.Visible = true;
        }
        #endregion

        #region btnSubmit_Click
        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            try
            {
                Transaction currentTrx = Transaction.Current;
                Transaction.Current = null;

                // Validate
                if (!IsValidEmail(txtEmail.Text))
                {
                    lblError.Text = "Must use a valid Email";
                    return;
                }

                if (txtEmail.Text.Count() < 1)
                {
                    lblError.Text = "Must enter a message";
                    return;
                }

                if (txtEmail.Text.Count() > 255)
                {
                    lblError.Text = "Message must be less than 255 characters";
                    return;
                }

                // Connect to DotNetNuke Data
                string _IntrinsicData = Convert.ToString(ConfigurationManager.ConnectionStrings["DotNetNuke5Entities"]);
                DotNetNuke5Entities db = new DotNetNuke5Entities(_IntrinsicData);

                // Get the information for the user who made the Post
                var DNNUser = (from PST in db.Posts
                               from vw_Users in db.vw_UserRoles
                               where PST.PostedBy == vw_Users.Username
                               where PST.Id == CurrentPostID
                               select vw_Users).FirstOrDefault();

                // Create New Message
                DNNData.Message NewMessage = new DNNData.Message();

                NewMessage.NameFrom = txtName.Text;
                NewMessage.EmailFrom = txtEmail.Text;
                NewMessage.NameTo = DNNUser.DisplayName;
                NewMessage.EmailTo = DNNUser.Email;
                NewMessage.MessageText = txtMessage.Text;
                NewMessage.MessageCreated = DateTime.UtcNow;
                NewMessage.Message_Post = CurrentPostID;

                db.AddToMessages(NewMessage);
                db.SaveChanges();

                // Get the information for the Post
                var PostInfo = (from PST in db.Posts
                                where PST.Id == CurrentPostID
                                select PST).FirstOrDefault();

                // Send Email

                string strSubject = "Message From ThingsForSale";

                string strMessage = String.Format("{0}",
                    "This is a message From the Things For Sale program.")
                    + Environment.NewLine + Environment.NewLine;

                strMessage = strMessage + String.Format("Regarding the post '{0}'",
                    PostInfo.Description) + Environment.NewLine;

                strMessage = strMessage + String.Format("This message was sent by {0}",
                    txtName.Text) + Environment.NewLine + Environment.NewLine;

                strMessage = strMessage + String.Format("Message: {0}",
                    txtMessage.Text) + Environment.NewLine;

                // Create the MailHelper class created in the Server project.
                MailHelper mailHelper =
                    new MailHelper(
                        txtName.Text,
                        DNNUser.Email,
                        DNNUser.DisplayName,
                        strSubject,
                        strMessage);

                // Send Email
                mailHelper.SendMail();


                lblError.Text = "Success";

                // Clear fields
                txtMessage.Text = "";
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;
            }
        }
        #endregion

        #region IsValidEmail
        public static bool IsValidEmail(string strIn)
        {
            // Return true if strIn is in valid e-mail format.
            // From: http://msdn.microsoft.com/en-us/library/01escwtf.aspx
            return Regex.IsMatch(strIn,
                   @"^(?("")("".+?""@)|(([0-9a-zA-Z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-zA-Z])@))" +
                   @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,6}))$");
        }
        #endregion
    }
}

Creating A Link To the HTML Page In LightSwitch

Add a Reference, in the Client project, to System.Windows.Browser

Switch to Logical View.

Add Screen...

Add a New Data Screen called PublicPage with no Screen Data selected.

Select the PublicPage_Run method.

Change it to the following code:

        partial void PublicPage_Run(ref bool handled)
        {
            // Set handled to 'true' to stop further processing.
            Dispatchers.Main.Invoke(() =>
            {
                HtmlPage.Window.Navigate(new Uri("PublicPage.aspx", UriKind.Relative));
            });

            handled = true;
        }

You will also need to add the following using statements to the class:

using Microsoft.LightSwitch.Threading;
using System.Windows.Browser;

We now need to ad the PublicPage.aspx to the build file, so that LightSwitch will include it in the build.

Note: You will want to back up your entire solution before performing the following steps:

Switch to File View, right-click on the LightSwitch project and select Unload Project.

Right-click on the unloaded project and select Edit.

Add the following to the bottom of the _buildFile section:

    <_BuildFile Include="ServerGenerated\PublicPage.aspx">
          <SubFolder>
          </SubFolder>
          <PublishType>
          </PublishType>
      </_BuildFile>

Reload the project.

Now you can run the project and click on the Public Page link...

... and navigate to the HTML page.

In your application, you will want to make the HTML page available for your unauthenticated users.

The live demonstration on the LightSwitchHelpWebsite, has one IFrame that is pointed directly at the PublicPage.aspx, and is only shown to un-authenticated users. A second IFrame, enabled only for Registered users, shows the normal LightSwitch application.

Finishing Touches

On the Posts screen, delete Posted By because it is set programmatically

However, notice that it still shows up on the automatically created PopUp.

Open the Post Entity, and select the PostedBy field, then un-check the Display by Default box.

The PopUp will no longer show the field. 

On the Posts screen, set the Message Data Grid to Use Read-only Controls

Select the CanExecute Code for the Respond To Message button.

Change the code to the following:

        #region RespondToMessage_CanExecute
        partial void RespondToMessage_CanExecute(ref bool result)
        {
            // Must have a Message Selected
            result = (Messages.SelectedItem != null);
        } 
        #endregion

Do the same for the Message Edit button.

This causes the buttons to be disabled if there is no Message selected.

Go into Properties for the project, set the Post List Detail screen as the startup screen.

An Advanced LightSwitch Application

This demonstrates an advanced LightSwitch application. However there is still a lot more to LightSwitch. For example, the entire UI can be controlled using Silverlight Custom Controls.

There are a ton of tutorials, tips, blogs, and forums at:

http://LightSwitchHelpWebsite.com

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

defwebserver
Software Developer (Senior) http://ADefWebserver.com
United States United States
Michael Washington is a Microsoft MVP. He is a ASP.NET and
C# programmer.
He is the founder of
LightSwitchHelpWebsite.com

He has a son, Zachary and resides in Los Angeles with his wife Valerie.

He is the Author of:
Follow on   Twitter

Comments and Discussions

 
QuestionUsing the code in 2013 VS PinmemberMember 1088355716-Jun-14 16:18 
AnswerRe: Using the code in 2013 VS Pinmemberdefwebserver16-Jun-14 17:28 
GeneralRe: Using the code in 2013 VS PinmemberJim Grant17-Jun-14 3:39 
GeneralRe: Using the code in 2013 VS Pinmemberdefwebserver17-Jun-14 4:00 
GeneralRe: Using the code in 2013 VS PinmemberJim Grant17-Jun-14 5:10 
GeneralThanks PinmemberKonstantinos Takakis8-Jan-13 23:22 
Questionthank Pinmemberanilvegik13-Jun-12 1:30 
AnswerRe: thank Pinmemberdefwebserver13-Jun-12 3:24 
QuestionLightSwitch in silverlight PinmemberMember 871072127-Apr-12 2:03 
QuestionMy 5! PinmemberKarthik Harve22-Dec-11 2:42 
AnswerRe: My 5! Pinmvpdefwebserver22-Dec-11 3:51 
QuestionI created an account here just to vote (5) for this PinmemberEdward Wood26-Aug-11 5:36 
AnswerRe: I created an account here just to vote (5) for this Pinmvpdefwebserver26-Aug-11 5:56 
QuestionMy vote of 5 PinmemberAnuj Tripathi22-Jul-11 0:05 
AnswerRe: My vote of 5 Pinmvpdefwebserver22-Jul-11 3:16 
Thank you for your vote!
QuestionVery good article Pinmembermysorian25-Jun-11 10:52 
AnswerRe: Very good article Pinmvpdefwebserver25-Jun-11 10:56 
GeneralMy vote of 5 PinmvpKunal_Chowdhury20-Jun-11 20:20 
GeneralRe: My vote of 5 Pinmvpdefwebserver22-Jun-11 8:35 
GeneralMy vote of 5 PinmemberMonjurul Habib14-Jun-11 12:15 
GeneralRe: My vote of 5 Pinmvpdefwebserver14-Jun-11 14:48 
GeneralMy vote of 5 PinmemberRichard Waddell13-Jun-11 6:22 
GeneralRe: My vote of 5 Pinmvpdefwebserver13-Jun-11 10:49 
GeneralGood article but again....... PinmemberMember 456543313-Jun-11 1:50 
GeneralRe: Good article but again....... Pinmvpdefwebserver13-Jun-11 4:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411022.1 | Last Updated 25 Oct 2011
Article Copyright 2011 by defwebserver
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid