Note: To save a date you should use ToBinary
The IPortable interface will allow the users of your module to develop content on a development server and easily deploy this content to a production server. You will want to implement this interface in practically every module you create no matter how simple it is. The good news is that this task is very easy to do and does not require advanced programming or a significant amount of time.
Let's say you have a development server at your company and you created a survey using the Survey module (using the 04.00.00 or higher version. A link to the Beta is available at the end of this article).
You now want to put the Survey on your production server. To do so you would simply follow these steps:
1) From the menu of the Survey module select Export Content
2) Next, from the Export Module page click the Export button
3) While logged in as the portal Administrator select File Manger from the Admin menu
(do this while logged in as portal Administrator not as the portal Host using
the Host account because you will not see the correct directory in the File Manager)
We see the .xml file that has been created (in this example content.Survey.Survey.xml)
4) Import the .xml file to your production server using these steps:
5) Next place an instance of the Survey module on a page (click here for directions on adding a module to a page) and from the Survey module's menu select Import Content
6) The .xml file is show in the drop-down. Click the Import button
And you're done!
To implement this functionality in your own custom DotNetNuke module you simply:
The first thing you need to do is indicate a business controller class in the module definition for your module (If you have already started working on your module and you neglected to do this step initially you will have to delete the module definition and recreate it).
Here are the steps I used to create the module definition for the Survey module:
While logged into the DotNetNuke site as the "host" account, from the menu bar I selected Host and then selected Module Definitions
I clicked on the black arrow that is pointing down to make the fly-out menu to appear. On that menu I selected Create New Module
In the Edit Module Definitions page I entered:
I then clicked UPDATE and completed the module definition (see my tutorial that describes how to create a module definition)
I created a SurveyController.vb class file
In that class I added the line Implements Entities.Modules.IPortable
Visual Studio then automatically adds the two stub methods.
Public
Function ExportModule(ByVal
ModuleID As
Integer)
As
String
Implements
Entities.Modules.IPortable.ExportModule
End
Function
Public
Sub ImportModule(ByVal
ModuleID As
Integer,
ByVal Content
As
String,
ByVal Version
As
String,
ByVal UserID
As
Integer)
Implements
Entities.Modules.IPortable.ImportModule
End
Sub
When the users of your module selects Export
Content, the DotNetNuke framework will call the ExportModule method
that you create and pass it a ModuleID parameter. It is expecting your
method to return an .xml formatted response as a String data type.
When implementing this for the Survey module I can see that the Surveys are contained in the Surveys table, but the options (for example "First Choice") are contained in the SurveyOptions table.
For each Survey in the Surveys table, I will need to export the matching options for that survey in the SurveyOptions table. Another thing to notice is that while the primary key for the Surveys table is SurveyID, the field that is important right now is the ModuleID field. In the DotNetNuke architecture the ModuleID is an important parameter. A ModuleID represents a single instance of a module and is used to segment the data for each instance of that module in the database. A ModuleID is unique across all portals in a DotNetNuke installation.
Here is my implementation of the ExportModule method:
Public
Function ExportModule(ByVal ModuleID As Integer) As String Implements DotNetNuke.Entities.Modules.IPortable.ExportModuleIn C#:
string
DotNetNuke.Entities.Modules.IPortable.ExportModule(int ModuleID)Here is a sample of the output created by the DotNetNuke framework from the output of this method:
<?xml version="1.0" encoding="utf-8" ?>
<content type="Survey" version="04.00.00">
<surveys>
<survey>
<question><![CDATA[Question Number
One]]></question>
<vieworder><![CDATA[-1]]></vieworder>
<createdbyuser><![CDATA[-1]]></createdbyuser>
<createddate><![CDATA[9/3/2006
4:46:45 PM]]></createddate>
<optiontype><![CDATA[R]]></optiontype>
<surveyoptions>
<surveyoption>
<optionname><![CDATA[First Choice]]></optionname>
<iscorrect><![CDATA[False]]></iscorrect>
<vieworder><![CDATA[0]]></vieworder>
</surveyoption>
<surveyoption>
<optionname><![CDATA[Second Choice]]></optionname>
<iscorrect><![CDATA[False]]></iscorrect>
<vieworder><![CDATA[1]]></vieworder>
</surveyoption>
</surveyoptions>
</survey>
</surveys>
</content>
When the users of your module select Import
Content, the DotNetNuke framework will call the ImportModule method
that you create and pass it a ModuleID parameter and a Content
parameter as well as Version and UserID. It expects your
controller class to process the contents of the Content parameter which
has a string data type. The Content parameter will contain the data in
the form of the sample above. Your ImportModule method will not return
anything. Your method will usually just insert the data passed to in in the
Content parameter into the database.
Here is my implementation of the ImportModule method:
Public
Sub ImportModule(ByVal ModuleID As Integer, ByVal Content As String, ByVal Version As String, ByVal UserId As Integer) Implements DotNetNuke.Entities.Modules.IPortable.ImportModulein C#:
void DotNetNuke.Entities.Modules.IPortable.ImportModule(int ModuleID, string Content, string Version, int UserID)Now, return to the module definition you created and click the Update link.
The Portable feature will now have check box.
It is not a lot of code, yet the functionality that this creates for the end user is significant.
Hopefully you will find this example helpful because if you examine the code you will see that I had to insert a survey, retrieve the SurveyID and then use that SurveyID when inserting the matching survey options.
This interface represents another example of why you would choose to use the DotNetNuke framework for a project rather than coding the project completely from scratch. By simply creating two simple methods you can provide your project with a process to move content between servers. Unlike the sometimes awkward and error prone methods of direct data transfer, you will have .xml files that can be easily backed up and versioned. Most importantly the data is separated from the content (for example the survey results are not exported just the surveys). In addition you have complete control over what defines content.
In future postings I will cover other Interfaces that are important to module developers such as IActionable and ISearchable,
The Survey code covered above is BETA and has not
been released. You can download the code using
this link. Before you upload it to an existing DNN4 site you have to remove
these two assemblies from the "\bin" directory of your existing DNN site.
DotNetNuke.Modules.Survey.dll
DotNetNuke.Modules.Survey.SqlDataProvider.dll
A special thanks to Stefan Cullmann for the enhancements to the xml generation code.
DotNetNuke® is a registered trademark of Perpetual Motion Interactive Systems Inc.