http://SilverlightDesktop.net

Intermediate Level - Creating a "Silverlight Notepad" module

This tutorial will cover creating a SilverlightDesktop module that allows users to save notes. The module uses web services to store and display the notes. Each user will have their own notes. If a user is not logged in, the note will be saved based on their IP address. This tutorial requires Visual Studio 2008 and Silverlight Tools for Visual Studio 2008.

Step #1: Install SilverlightDesktop for DotNetNuke.

You can find help on installing SilverlightDesktop at this link.

Step #2: Open Visual Studio and then open the DotNetNuke site.

Open Visual Studio and then open the SilverlightDesktop website by selecting File then Open Web Site...

You may get a message like this:

Click Yes.

The site will open.

From the toolbar, select Build then Build Web Site.

The site should build without errors.

Step #3: Create the SilverlightNotepad Web Service

In the web browser, navigate to the website and Login the website using the Host account.

Click on the HOST menu and select SQL

Paste the following script into the box:

CREATE TABLE [dbo].[SilverlightNotepad](
[NoteID] [int] IDENTITY(1,1) NOT NULL,
[UserName] [nvarchar](50) NOT NULL,
[IPAddress] [nvarchar](50) NOT NULL,
[Note] [nvarchar](100) NULL,
CONSTRAINT [PK_SilverlightNotepad] PRIMARY KEY CLUSTERED
(
[NoteID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

Select the "Run as Script" box and click "Execute".

Step #4: Create the Linq to SQL class

In Visual Studio, right-click on the App_Code/SilverlightDesktop folder in the Solution Explorer and select Add New Item...

In the Add New Item box, select LINQ to SQL Classes under Templates. Enter SilverlightNotepad.dbml for Name. Select Visual C# for the Language. Click the Add button.

Switch to the Server Explorer and right-click on Data Connections and select Add Connection... to create a new connection.

Create a connection to the SilverlightDesktop database.

Expand tables section and locate the SilverlightNotepad table created in the earlier step. 

Drag and drop the table on the design surface of the SilverlightNotepad Linq class.

Save and close the SilverlightNotepad.dbml file.

Right-click on the root of the webservice folder located at DesktopModules/SilverlightDesktop/webservice and select Add New Item...

In the Add New Item box:

When the SilverlightNotepadWebService.cs file is created it will be placed in the position indicated above.

 

Move the SilverlightNotepadWebService.cs file so that it resides in the position indicated above.

Double-click on SilverlightNotepadWebService.asmx (located in the DesktopModules/SilverlightDesktop/webservice folder) to open it up in the editor.

Replace ALL the code with the following code:

<%@ WebService Language="C#" CodeBehind="~/App_Code/SilverlightDesktop/webservice/SilverlightNotepadWebService.cs" 
Class="SilverlightDesktop.Module.SilverlightNotepadWebService" %>

Double-click on SilverlightNotepadWebService.cs (located in the App_Code/SilverlightDesktop/webservice folder) to open it up in the editor.

Replace ALL the code with the following code:

Note, you will find it easier to copy and paste from the file at this link: SilverlightNotepadWebService.txt

using System;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using System.Web.Script.Services;
using DotNetNuke.Entities.Users;
 
namespace SilverlightDesktop.Module
{
    [WebService(Namespace = "http://SilverlightDesktop.net/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ScriptService()]
    public class SilverlightNotepadWebService : System.Web.Services.WebService
    {
        #region GetNotepadContents
        [WebMethod(Description = "GetNotepadContents")]
        [ScriptMethod()]
        public String GetNotepadContents(int PortalID, int ModuleId, int UserID, string Password)
        {
            string NotepadContents = "";
            string strIPAddress = this.Context.Request.UserHostAddress;
            SilverlightDesktopAuthendicationHeader SilverlightDesktopAuthendicationHeader =
                new SilverlightDesktopAuthendicationHeader();
            SilverlightDesktopAuthendicationHeader.PortalID = PortalID;
            SilverlightDesktopAuthendicationHeader.UserID = UserID;
            SilverlightDesktopAuthendicationHeader.Password = Password;
            SilverlightDesktopAuthendicationHeader.ModuleId = ModuleId;
            SilverlightDesktopAuthendicationHeader.IPAddress = strIPAddress;
 
            Authendication Authendication = new Authendication(SilverlightDesktopAuthendicationHeader);
 
            SilverlightNotepadDataContext SilverlightNotepadDataContext = new SilverlightNotepadDataContext();
 
            if (Authendication.IsUserValid("Silverlight Notepad"))
            {
                UserInfo objUser = Authendication.GetUserInfo();
 
                var objSilverlightNotepad = (from SilverlightNote in SilverlightNotepadDataContext.SilverlightNotepads
                                             where SilverlightNote.UserName == objUser.Username
                                             select SilverlightNote).FirstOrDefault();
 
            if (!(objSilverlightNotepad == null)){
            NotepadContents = objSilverlightNotepad.Note;}
            }
            else
            {
                NotepadContents = "Must be logged in";
            }
 
            return NotepadContents;
        }
        #endregion
 
        #region SaveNotepadContents
        [WebMethod(Description = "SaveNotepadContents")]
        [ScriptMethod()]
        public void SaveNotepadContents(int PortalID, int ModuleId, int UserID, string Password, string NotepadContents)
        {
            string strIPAddress = this.Context.Request.UserHostAddress;
            SilverlightDesktopAuthendicationHeader SilverlightDesktopAuthendicationHeader =
                new SilverlightDesktopAuthendicationHeader();
            SilverlightDesktopAuthendicationHeader.PortalID = PortalID;
            SilverlightDesktopAuthendicationHeader.UserID = UserID;
            SilverlightDesktopAuthendicationHeader.Password = Password;
            SilverlightDesktopAuthendicationHeader.ModuleId = ModuleId;
            SilverlightDesktopAuthendicationHeader.IPAddress = strIPAddress;
 
            Authendication Authendication = new Authendication(SilverlightDesktopAuthendicationHeader);
 
            SilverlightNotepadDataContext SilverlightNotepadDataContext = new SilverlightNotepadDataContext();
 
            if (Authendication.IsUserValid("Silverlight Notepad"))
            {
                UserInfo objUser = Authendication.GetUserInfo();
 
                var objSilverlightNotepad = (from SilverlightNote in SilverlightNotepadDataContext.SilverlightNotepads
                                             where SilverlightNote.UserName == objUser.Username
                                             select SilverlightNote).FirstOrDefault();
 
                if (!(objSilverlightNotepad == null))
                {
                    SilverlightNotepadDataContext.SilverlightNotepads.DeleteOnSubmit(objSilverlightNotepad);
                    SilverlightNotepadDataContext.SubmitChanges();
                }
 
                SilverlightNotepad SilverlightNotepad = new SilverlightNotepad();
                SilverlightNotepad.UserName = objUser.Username;
                SilverlightNotepad.IPAddress = strIPAddress;
                SilverlightNotepad.Note = TrimLarge(NotepadContents);
 
                SilverlightNotepadDataContext.SilverlightNotepads.InsertOnSubmit(SilverlightNotepad);
                SilverlightNotepadDataContext.SubmitChanges();
            }
        }
        #endregion
 
        #region TrimLarge
        private string TrimLarge(string strText)
        {
            string strNewText;
 
            if (strText.Length > 99)
            {
                strNewText = strText.Substring(0, 99);
            }
            else
            {
                strNewText = strText;
            }
            return strNewText;
        }
        #endregion
    }
}

Step #5: Create the SilverlightNotepad Project

From the toolbar, select File then New Project.

In the New Project box:

On the Add Silverlight Application box:

The project will be created.

Step #6 Create the Silverlight module

Right-click on the SilverlightNotepad project and select Add Service Reference.

Enter the web address to the SilverlightNotepadWebService.asmx web service that your created and click the GO button.

When the web service is found, enter SilverlightNotepadWebService in the Namespace box and click the OK button.

The web service reference will be created.

Open the Page.xaml file and replace ALL the contents with the following:

Note, you may find it easier to copy from this page: SilverlightNotepad_xaml.txt

<UserControl x:Class="SilverlightNotepad.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="Auto" Height="Auto">
    <UserControl.Resources>
        <Storyboard x:Name="SaveAnimation">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="textBlock" 
	Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.01"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="0.92"/>
                <SplineDoubleKeyFrame KeyTime="00:00:02" Value="1"/>
                <SplineDoubleKeyFrame KeyTime="00:00:03" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </UserControl.Resources>
    <Canvas x:Name="LayoutRoot" Background="White">
        <Button Height="30" Width="87" Canvas.Left="1" Canvas.Top="2" Content="Save" x:Name="btnSave"/>
        <TextBox Height="160" Width="160" Canvas.Top="35" TextWrapping="Wrap" x:Name="txtContents"/>
        <TextBlock Height="23" Width="81" Canvas.Left="128.996" Canvas.Top="3.037" Text="Saved" TextWrapping="Wrap" 
	Foreground="#FF630404" HorizontalAlignment="Center" Opacity="0" x:Name="textBlock"/>
    </Canvas>
</UserControl>

Open the Page.xaml.cs file and replace ALL the contents with the following:Note, you may find it easier to copy from this page: SilverlightNotepad_Page_xaml_cs.txt

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ServiceModel;
using System.ServiceModel.Channels;
 
using SilverlightNotepad.SilverlightNotepadWebService;
 
namespace SilverlightNotepad
{
    public partial class Page : UserControl
    {
        public int intPortalID;
        public int intModuleId;
        public int intUserID;
        public string strPassword;
        public string strWebServiceBase;
 
        public Page()
        {
            // Required to initialize variables
            InitializeComponent();
            Loaded += new RoutedEventHandler(Page_Loaded);
        }
 
        #region Page_Loaded
        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            // Get parameters from the Tag
            char[] delimiterChars = { ',' };
            string[] strParameters = this.Tag.ToString().Split(delimiterChars);
 
            intPortalID = Convert.ToInt32(strParameters[0]);
            intModuleId = Convert.ToInt32(strParameters[1]);
            intUserID = Convert.ToInt32(strParameters[2]);
            strPassword = strParameters[3];
            strWebServiceBase = strParameters[4];
 
            ShowSilverlightNotepad();
 
            this.btnSave.Click += new RoutedEventHandler(btnSave_Click);
        }
        #endregion
 
        #region ShowSilverlightNotepad
        private void ShowSilverlightNotepad()
        {
            BasicHttpBinding bind = new BasicHttpBinding();
            EndpointAddress MyEndpointAddress = 
               new EndpointAddress(strWebServiceBase + "SilverlightNotepadWebService.asmx");
            var proxy = new SilverlightNotepadWebServiceSoapClient(bind, MyEndpointAddress);
 
            proxy.GetNotepadContentsCompleted += 
              new EventHandler<GetNotepadContentsCompletedEventArgs>(proxy_GetNotepadContentsCompleted);
            proxy.GetNotepadContentsAsync(intPortalID, intModuleId, intUserID, strPassword);
        }
 
        void proxy_GetNotepadContentsCompleted(object sender, GetNotepadContentsCompletedEventArgs e)
        {
            this.txtContents.Text = (string)e.Result;
        } 
        #endregion
 
        #region SaveNotepad
        void btnSave_Click(object sender, RoutedEventArgs e)
        {
            BasicHttpBinding bind = new BasicHttpBinding();
            EndpointAddress MyEndpointAddress = 
              new EndpointAddress(strWebServiceBase + "SilverlightNotepadWebService.asmx");
            var proxy = new SilverlightNotepadWebServiceSoapClient(bind, MyEndpointAddress);
 
            proxy.SaveNotepadContentsAsync(intPortalID, intModuleId, intUserID, 
              strPassword, this.txtContents.Text);
            SaveAnimation.Begin();
        } 
        #endregion
    }
}

Right-click on the DotNetNuke website (just below the Solution icon in the Solution Explorer) and select Property Pages.

In the Property Pages box, select Silverlight Applications on the left pane. Click on the SilverlightNotepad  project in the right pane and click the Remove button.

Click the Add button.

Enter DesktopModules\SilverlightDesktop\ClientBin for Destination Folder and click the Add button.

Click the OK button.

Right-click on the SilverlightNotepad Silverlight project and select Build.

Notice the SilverlightNotepad.xap file is now in the ClientBin folder of the DesktopModules/SilverlightDesktop/ClientBin directory.

Step #7: Register the module

In the web browser, log into the site as an administrator (or the Host account) and navigate to the SilverlightDesktop module.

Select Module Administration from either the module configuration menu or the Module Administration link.

On the Module Settings page and enter the following settings on the last line and click the Insert button.

Click the Back to Main link to navigate back to the main page.

The Silverlight Notepad button will display and when you click on it the module will show.

The source code is available in module downloads