My Blog

Author:Philip BeadleCreated:Monday, September 15, 2008 10:40 AM
This blog is more general than my Blog at http://www.dotnetnuke.com/Community/Blogs/tabid/825/Default.aspx. You'll find mostly technical tips and tricks and things i am doing in the MS user group community.

On Tuesday 15th October 2008 my lovely wife Lorraine gave birth to our beautiful daughter Allegra Rose.  She weighed 4.00kg and was 51cm long, big baby :).  We are now home from the hospital and settling into a new life of being parents.  Here's a pic of her beautiful face.

Read More »

I had a TextBlock with a couple of buttons in a StackPanel and the text wouldn't wrap.  This is because the StackPanel is not limiting so the TextBlock doesn't know how long it should be and hence where to wrap.  I changed the StackPanel to a Grid with 2 columns and the text wrapping now works nicely.

Read More »

 

Read More »

 

I have been working on a Silverlight (RC0) module for DotNetNuke and I needed to have access to some of the objects that DotNetNuke supports such as the userInfo object inside my Silverlight Module. 

So what I have done is use the XmlSerializer to serialise the UserInfo object then pass the string in the initParams of the Silverlight control and Deserailise inside the Silverlight app.

Read More »

Not sure where this came from so can't credit them.

Read More »

 Today we were discussing the merits of code reviews and Rick threw this is in to stir the pot.

 I am going to play the devil’s advocate here: Don’t shoot the messenger J
This is me playing a PM/Primary stake holder in a project you are working on…

What is the problem a  code review (by 2 others) meant to solve exactly?

Read More »

When building DotNetNuke modules that use a Silverlight 2 interface there are a few things you need to be aware of:

  • How are you going to debug you project
  • How are you going to access your data
  • How to present your data in the UI.

This post deals with setting up your solution so you can easily debug your Silverlight control.

Debugging

When you open VS2008 with the Silverlight tools installed and create a new Silverlight project the debugging experience is excellent.  You hit F5 and away you go.  However this technique relies on you using the default aspx page which is no good when you are building a DotNetNuke module or for that matter a SharePoint Web part – this technique works just as well for SharePoint as for DotNetNuke.    The reason for this is that you will need to have the Silverlight control hosted inside the DotNetNuke module on the host site not in the default site so that you can easily access all of your resources and data via web services or WCF.  So what to do?  
Use the cool MSBuild tasks from the MSBuild Community Tasks Project http://msbuildtasks.tigris.org/ to let you copy over the files you need into the target site each time you build your solution. 

Once the files are copied over you simply access the page as normal and attach to the process.  I use the same process for all of my normal DotNetNuke modules as it allows me to keep my development code separate from my production sites.  So lets see how its done.

First up lets get the Module side of things sorted out.

  1. Create a new DotNetNuke compiled module using the template in the starter kit, do not add it to the DesktopModules folder of your site, put it somewhere else
  2. Right click the project and unload it
  3. Right click the project and Edit it so you can change the proj file easily
  4. Paste in this line to use the MSBuild tasks
     <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" Condition="" />
     
  5. Paste in the following code inside the Afterbuild Target (change the physical path to your own)
     <Target Name="AfterBuild" DependsOnTargets="DeployModule">
     Target>
     <PropertyGroup>
        <ModuleFolder>DNN_TechEdModuleFolder>
        <DNNDirectory>C:\Sandboxes\TechEd\DotNetNuke\DotNetNuke_05.00.00_Install_BETA7DNNDirectory>
     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" />
     Target>
     
  6. Reload the project and build it to make sure its all working correctly and copying your files into the correct folders on your DotNetNuke site.
  7. Now register your module using the dnn file in your site (see Lorraine's Help if you dont know how to do this 
  8. Delete the standard List and associated code in the ViewModule.ascx and ViewModule.ascx.vb files
  9. Rebuild and add the module to a page.

Ok so now we have a "host" for the Silverlight control lets add the Silverlight project to our solution and get then to the module.

  1. Add a new Silverlight project to the solution
  2. Unload it and Edit the proj file as before
  3. Paste in this line to use the MSBuild tasks
     <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" Condition="" />
  4. Paste in the following code which will copy the dll, pdb and xap files to the ClientBin folder of your target DotNetNuke site
     <Target Name="AfterBuild" DependsOnTargets="DeployModule">
     Target>
     <PropertyGroup>
        <DNNDirectory>C:\Sandboxes\TechEd\DotNetNuke\DotNetNuke_05.00.00_Install_BETA7DNNDirectory>
     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)\ClientBin" />
     Target>
  5. Reload the project and rebuild.
  6. Check your target ClientBin folder for the *.dll, *.pdb and *.xap files

Ok now we need to host the Silverlight control in the DotNetNuke module.

  1. Add a place holder control to the View control
  2. Open the vb file for the View control and in the Page_Load event paste this - Notice that you need to register the ScriptManager for Silverlight to work properly
                DotNetNuke.Framework.AJAX.RegisterScriptManager()
                Dim silverlightControl As New System.Web.UI.SilverlightControls.Silverlight
                silverlightControl.ID = "TechEd2008"
                silverlightControl.MinimumVersion = "2.0.30523"
                silverlightControl.Source = "~/ClientBin/SL_TechEd.xap"
                silverlightControl.Width = 850
                silverlightControl.Height = 850
                Dim initParams As String = String.Format("ModuleId={0},IsEditable={1},UserId={2}", ModuleId.ToString, IsEditable, UserId)
                silverlightControl.InitParameters = initParams
                phSilverlight.Controls.Add(silverlightControl)
     
  3. Now build the project and open IE to the page you added the module and see that there is now a Silverlight control hosted on the page.
  4. Go back to VS2008 and attach the debugger to the Silverlight control by selecting Tools --> Attach To Process and finding the iexplore.exe process that has a type of Silverlight
     
  5. Now you can debug your Silverlight control inside a DotNetNuke module.

Left to right we have Paul Glavich, Aymeric Gaurat-Apelli, Graeme Strange and Andy Lamb. Now you know why we all love working at Readify :)

Last year I saw Nikhil Kothari do a session called - Enhancing Ajax Applications with Silverlight.  One of his demos was using the OpenFileDialog and a webservice to transfer chunks of data up to the webserver which I downloaded and worked out how it all fit together.  Now that beta 2 is released I thought I'd update the demo to call the webservice using a Service Reference and the Async event model.

So lets see how it works.

  1. The web page has a single button and a div that works as the progress bar.
  2. The user clicks the button which opens the OpenFileDialog
  3. User selects as many files as they want
  4. The files are sent one at a time by breaking them down into chunks
  5. A chunk is sent through the webservice and then the system waits for the Async Completed event
  6. The async event will then send the next chunk until the file is sent and moves on to the next file.

 Lets see what the code does now:

The aspx page hosts the Silverlight control with a couple of extra parameters than standard.

<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/FileUploader.xap"            OnPluginLoaded="onUploaderAvailable"
MinimumVersion="2.0.30523"
Width="0" Height="0" HtmlAccess="Enabled" InitParameters="UploadServiceUrl=http://localhost:7345/ClientBin/Uploader.asmx" />

I want the Silverlight control to be able to interact with the HTML so HtmlAccess is set to true.  I also want to set the location of the service so the InitParameters is set and lastly I want to run some javascript when the Silverlight control has loaded so the OnPluginLoaded event is wired up. 

 Now have a look at the js for the page.

 <script type="text/javascript">

 
    var _uploader;
 
    function onUploaderAvailable(sender, e) {
        slCtl = sender.get_element();
        _uploader = slCtl.Content.uploader;
 
        _uploader.uploadStarting = onUploaderStarting;
        _uploader.uploadCompleted = onUploaderCompleted;
        _uploader.uploadProgress = onUploaderProgress;
    }
 
    function onUploaderCompleted(sender, e) {
        document.getElementById('progressContainer').style.visibility = 'hidden';
    }
 
    function onUploaderProgress(sender, e) {
        document.getElementById('progressLabel').innerHTML = e.fileName;
        var total = e.totalLength;
        var sent = e.sentLength;
 
        var width = Math.ceil(200 * sent / total) + 'px';
        document.getElementById('progressFill').style.width = width;
    }
 
    function onUploaderStarting(sender, e) {
        document.getElementById('progressCountLabel').innerHTML = _uploader.uploadCount;
        document.getElementById('progressContainer').style.visibility = 'visible';
    }
 
    function uploadFiles() {
        _uploader.uploadFiles();
    }
script>

When the Silverlight control has loaded the first method will fire which gets a reference to a custom object called "uploader".  This object is a [ScritableMember] that gets registered with the Page (you'll see that in a minute) that can now be accessed and used by the js on the page.  Now that we have a reference the events on the "Uploader" are wired up to the js methods so that when an event such as UploadStarting fires the UI can be updated.  As you can see there will be no visible XAML component.

[ScriptableMember]
public event UploadEventHandler uploadProgress;
 

 In the Uploader class you can see the [ScriptableMember] marked on the public events and methods that the js needs access to.  In the onUploaderAvailable js event that is fired when the Silverlight plugin is loaded a reference to the Uploader instance is gained and the public events are wired up to the js methods.  the Uploader instance is registered in the load event of the Page.xaml class like so:

_uploader = new Uploader();
HtmlPage.RegisterScriptableObject("uploader", _uploader);
 

 Now that the Html page knows about the uploader and the events have been wired up we can now click the Upload Button which will fire the uploadFiles js method which fires the uploadFiles method on the uploader object.  If you debug the method in the cs file you will see that the js is calling directly into the cs via the scripting bridge that [ScritableMember] creates.

The uploadFiles method spins up an OpenFileDialog which has MultiSelect set to true and the filter set to XML, once the user selects the files they want a list of those files is created to be processed.  You can also see that a new webservice client is created and its Completed event is wired up.

// Create the Service
client = new UploaderSoapClient(binding, addr);
// Register for the Completed Event
client.UploadFileChunkCompleted += new EventHandler<UploadFileChunkCompletedEventArgs>(client_UploadFileChunkCompleted);
 

Since any call to a webservice is Asynchronous a completed event must be wired up to handle the call back, here we define client_UploadFileChunkCompleted to fire when the web service call to UploadFileChunk is done.  To do the call to the web service a ServiceReference was added to the Silverlight project and the binding and end point set up as shown here:

EndpointAddress addr = new EndpointAddress(App.uploaderEndPoint);
BasicHttpBinding binding = new BasicHttpBinding();
UploaderSoapClient client;
 

The uploaderEndPoint was retrieved from the InitParams in App.xaml.cs like so:

private void Application_Startup(object sender, StartupEventArgs e)
{
    this.RootVisual = new Page();
    uploaderEndPoint = e.InitParams["UploadServiceUrl"].ToString();
}
 

 The InitParams are set on the Silverlightncontrol like this

<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/FileUploader.xap"
OnPluginLoaded="onUploaderAvailable" MinimumVersion="2.0.30523" Width="0"
Height="0" HtmlAccess="Enabled" InitParameters="UploadServiceUrl=http://localhost:7345/ClientBin/Uploader.asmx" />

So now everything is wired up we are ready to upload the files. Enjoy!

You can download this solution here...

  
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:10
MembersMembers:0
TotalTotal:10

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