My Blog

Sep24

Written by:Philip Beadle
Thursday, September 24, 2009 1:21 PM 

This series of posts will show you a bunch of things I have learnt about building integrated Silverlight – DotNetNuke modules with RIA Services

Projects to add:

  1. Add a new Silverlight Project.  Call it MySilverlightApplication.
  2. Select to host it in a new Web Application called MySilverlightApplication.Web and check the Enable RIA Services link.
  3. Add a new Silverlight Unit Testing project and call it MySilverlightApplication.SLtest.
  4. Add a new Unit Test Project and call it MySilverlightApplication.MSTest
  5. Create a Solution Folder called Modules and move these four projects into it.
  6. Create another solution folder and call it Services.
  7. Add a new .Net class library (not a Silverlight one) and call it AuthenticationServices
  8. Our module is going to interact with the Announcements table so add another .Net class library and call it AnnouncementServices

Ok we now have all the projects we need to build a fully testable and Blendable Silverlight Application for DotNetNuke.  Let’s do a little cleaning up and get everything ready for easy designing, testing and developing.

  1. Delete the .aspx and .html files from the MySilverlightApplication.Web project.
  2. Click on the web.config file and set the build action to None.  The DNN site already has a web.config.
  3. Click on the Silverlight.js file and set the Copy To Output Directory to Copy If Newer.
  4. Open double click teh Properties node in teh Solution Explorer and add the MySilverlightApplication.SLtest project as a linked Silverlight Application.
  5. Add a new Folder to the MySilverlightApplication.SLtest called Dependencies and add the Microsoft.Silverlight.Testing.dll and Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight.dll files to it. 
  6. Now add references to those two files so that your Silverlight Test project builds.
  7. Open the MSTest project and remove the references to System and System.Core, we need to replace these with the Silverlight specific versions.
  8. Add a reference to C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v3.0\system.dll.  You will also need references to System.Core, System.Net and System.Windows which are all in the same folder.
  9. Also add a reference to the same two dlls as in step 5 and to C:\Program Files (x86)\Microsoft SDKs\RIA Services\v1.0\Libraries\Silverlight\System.Windows.Ria.dll
  10. Now to both the SLTest and MSTest projects ad a reference to the Silverlight Application.

Everything should be building ok now so let’s make some changes to the .csproj files so that the correct files are deployed to our Development DotNetNuke site for easy debugging and automated integration testing.

For debugging we need the .xap, .dll and .pdb files to be deployed onto the Development DNN instance, to do this I modify the .csproj files to do a copy after the build is finished.

  1. Right click the MySilverlightApplication and select Unload Project.
  2. Right click it again and select Edit which will open the MSBuild file for the project.
  3. Towards the bottom of the file you will see some commented out code.  Paste the following immediately after that code.
<Target Name="AfterBuild" DependsOnTargets="DeployModule"
Condition=" '$(IsDesktopBuild)'!='false' ">
</Target>
<PropertyGroup>
<DNNDirectory>
      D:\DotNetNuke\DotNetNuke_Community_05.01.01_Install
</DNNDirectory>
<ModuleFolder>
      MySilverlightApplication
</ModuleFolder>
</PropertyGroup>
<Target Name="DeployModule">
<CreateItem Include="$(MSBuildProjectDirectory)\$(OutputPath)\*.xap">
<Output TaskParameter="Include" ItemName="ModuleXap" />
</CreateItem>
<CreateItem Include="$(MSBuildProjectDirectory)\$(OutputPath)\*.dll">
<Output TaskParameter="Include" ItemName="ModuleAssemblies" />
</CreateItem>
<CreateItem Include="$(MSBuildProjectDirectory)\$(OutputPath)\*.pdb">
<Output TaskParameter="Include" ItemName="ModuleDebug" />
</CreateItem>
<Copy SourceFiles="@(ModuleAssemblies);@(ModuleDebug);@(ModuleXap)" 
DestinationFolder="$(DNNDirectory)\DesktopModules\$(ModuleFolder)\ClientBin" />
</Target>

Make sure you update the DNNDirectory and the ModuleFolder to your required values.  Do exactly the same for the SLTest project as well.  The condition in the Target is there so that this step is ignored when the solution is built with Team Foundation Server Build.

We need to do a very similar modification to the Web project as well.  There is a slight difference here in that this change also packages up the appropriate files and creates the .zip file for install and source and a total package as well so every time you build you have a deployable .zip file ready to install on any other DotNetNuke site.  You will need to install the MSBuild Community Tasks from to use the Zip target.

  1. Install the MSBuild Community Tasks
  2. Paste the following Immediately after the commented out code as before.
<Import Project="$(MSBuildExtensionsPath)\
       MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<Target Name="AfterBuild" 
DependsOnTargets="DeployModule">
</Target>
<PropertyGroup>
<Major>01</Major>
<Minor>00</Minor>
<Build>00</Build>
</PropertyGroup>
<PropertyGroup>
<ModuleFolder>
      CHEAPLiveCosts
</ModuleFolder>
<DNNDirectory>
      C:\Sandboxes\CHEAP\CHEAP_Development
</DNNDirectory>
<PackageDirectory>
      C:\DotNetNuke\Packages
</PackageDirectory>
</PropertyGroup>
<Target Name="DeployModule">
<CreateItem Include="$(MSBuildProjectDirectory)\$(OutputPath)\*.dll">
<Output TaskParameter="Include" ItemName="ModuleAssemblies" />
</CreateItem>
<CreateItem Include="$(MSBuildProjectDirectory)\$(OutputPath)\*.pdb">
<Output TaskParameter="Include" ItemName="ModuleDebug" />
</CreateItem>
<Copy SourceFiles="@(Content)" 
DestinationFiles="@(Content -> '$(DNNDirectory)\
                         DesktopModules\$(ModuleFolder)\%(Identity)')" 
          SkipUnchangedFiles="true" />
<Copy SourceFiles="@(ModuleAssemblies);@(ModuleDebug)" 
DestinationFolder="$(DNNDirectory)\bin" />
<Copy SourceFiles="@(Content)" 
DestinationFiles="@(Content -> '$(MSBuildProjectDirectory)\Package\%(Identity)')" SkipUnchangedFiles="true" />
<Copy SourceFiles="@(ModuleAssemblies);" 
DestinationFolder="$(MSBuildProjectDirectory)\Package\bin" />
<CreateItem Include="$(MSBuildProjectDirectory)\Package\**\*.*">
<Output TaskParameter="Include" ItemName="OutputContent" />
</CreateItem>
<Zip Files="@(OutputContent)" 
WorkingDirectory="$(MSBuildProjectDirectory)\Package" 
ZipFileName="$(ProjectName)_$(Major).$(Minor).$(Build)_Install.zip" />
</Target>

For formatting I have changed the DNNDirectory, PackageDirectory and ModuleFolder nodes.  Remove the line breaks otherwise you will get an error that says you have illegal characters in the path.

 

Now when you build your solution you should get a new folder under DesktopModules that has a ClientBin folder and the js file.  The ClientBin folder should have the .xap file and any associated dlls and pdb files.

Next we need to add the Usercontrol files to the .Web project so we can register and host the Silverlight application inside DotNetNuke.  Lately i have been using the same Web project to host both the Silverlight Application and the SLTest xap, I add a setting so that i can switch from real to integration test easily. 

  1. Add a new User Control to the Web project and call it View.ascx.
  2. Add another User Control and call it Settings.
  3. Add a reference to the DotNetNuke.dll file.
  4. Open up the View.ascx file and paste the following in:
    <script type="text/javascript">
    function onSilverlightError(sender, args) {
    var appSource = "";
    if (sender != null && sender != 0) {
                appSource = sender.getHost().Source;
            } var errorType = args.ErrorType;
    var iErrorCode = args.ErrorCode;
    if (errorType == "ImageError" || errorType == "MediaError") {
     return;
            }
    var errMsg = "Unhandled Error in Silverlight Application " + 
            appSource + "\n";
            errMsg += "Code: " + iErrorCode + "    \n";
            errMsg += "Category: " + errorType + "       \n";
            errMsg += "Message: " + args.ErrorMessage + "     \n";
    if (errorType == "ParserError") {
                errMsg += "File: " + args.xamlFile + "     \n";
                errMsg += "Line: " + args.lineNumber + "     \n";
                errMsg += "Position: " + args.charPosition + "     \n";
            }
    else if (errorType == "RuntimeError") {
     if (args.lineNumber != 0) {
                    errMsg += "Line: " + args.lineNumber + "     \n";
                    errMsg += "Position: " + args.charPosition + "     \n";
                }
                errMsg += "MethodName: " + args.methodName + "     \n";
            }
    throw new Error(errMsg);
        }
    </script>
     
    <div id="silverlightControlHost" style="position: relative; 
        width: 100%; height: 500px;
        vertical-align: top; z-index: 50;">
    <object data="data:application/x-silverlight-2," 
    type="application/x-silverlight-2"
    width="100%" height="100%">
    <param name="source" value='<%=SilverlightApplication %>'/>
    <param name="onError" value="onSilverlightError" />
    <param name="background" value="Transparent" />
    <param name="windowless" value="true" /> 
    <param name="minRuntimeVersion" value="3.0.40624.0" />
    <param name="autoUpgrade" value="true" />
    <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration: none">
     <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight"
     style="border-style: none" />
    </a>
    </object>
    <iframe id="_sl_historyFrame" style="visibility: 
            hidden; height: 0px; width: 0px;
            border: 0px"></iframe>
    </div>
  5. Open up the code behind file and modify it to look like this.
    public partial class View : PortalModuleBase
    {
    public string SilverlightApplication { get; set; }
    public string SilverlightInitParams { get; set; }
    protected void Page_Load(object sender, EventArgs e)
    {
    bool isChecked;
    var xapFile = "MySilverlightApplication.xap";if (bool.TryParse(Settings["IsTest"].ToString(), out isChecked))
    {
    if (isChecked)
    xapFile = "MySilverlightApplication.SLTest.xap";
    }
    // Register Silverlight.js file
    Page.ClientScript.RegisterClientScriptInclude(this.GetType(), "SilverlightJS", (String.Format(@"{0}{1}", 
    TemplateSourceDirectory, "/Silverlight.js")));// Set the path to the .xap file
    SilverlightApplication = String.Format("{0}/ClientBin/{1}", 
    TemplateSourceDirectory, xapFile);// Pass the Initialization Parameters to the Silverlight Control
    SilverlightInitParams = string.Format("Test={0}", "Some init stuff");
    }
    }
  6. In the settings file add a check box and save its value as a setting and call the setting “IsTest”.
  7. Now build you solution.
  8. You are now ready to register your module with DotNetNuke so go ahead and do that.

That’s it for Part 1.  You are now set up ready to start developing, designing and testing your application. 

Tags:

Your name:
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment  Cancel 
DNN Template Maker

Artisteer - Web Design Generator

  
UsersOnline
MembershipMembership:
Latest New UserLatest:andpro
Past 24 HoursPast 24 Hours:0
Prev. 24 HoursPrev. 24 Hours:0
User CountOverall:32

People OnlinePeople Online:
VisitorsVisitors:12
MembersMembers:0
TotalTotal:12

Online NowOnline Now:
  
Talk to me
  
Good Books
My Logos


MVP Logo
From: 2004-2009

Lorraine Young's DNN Site

DotNetNuke Sponsor and Platinum Benefactor logo

 Microsoft ASP.net logo

microsoftcertifiedprofessional.gif

vicnet_logo.gif