In order to start this post I want to take a big step back first talk about communities.
Communities, at the base level, really boil down to social interactions of organisms with each other. These organisms coexist in a society. Societies can be thought of people that are related to each other, that share common expectations and/or authority.
Seems simple enough, right?
If we dig a bit deeper into the social interactions of organisms we can begin to get an idea that there are a variety of types of people – as defined by their behaviour. Typically there are 4 types that really stick out, at least for me.
- Socializers
- This is the biggest group of any community. Usually about 80% of the population.
- They are seeking light-weight, non-confrontational easy to reciprocate social interactions with other people.
- Achievers
- These folks go to great lengths to achieve rewards simple for the prestige of having it.
- Explorers
- They are involved in the community for the social credit of having discovered something. They love to discover an unknown glitch or a hidden Easter egg.
- Killers
- These types thrive on competition with others in the community, in order to win and their expense.
Think of each community you belong to and what type of behaviour you typically exhibit. How your actions/interactions impact the overall state of the community. What is your typical tone within those communities. Also, are you typically a positive person or do you “bring the hammer” with negativity? Maybe your a realist?
No matter your behaviour type and the tone you use, you do impact the community.
So why all the preamble?
Its important to understand the nature of our community - DotNetNuke and the smaller/sub community of The Store. As, essentially, the “authority” for The Store we must keep our eyes and ears open to all input from the community. We must adapt and change with the “expectations” of our community. We must learn from each other. The very second we stop listening to the community (to you) we all lose.
While doing so we are sensitive to the fact that there will always be those people that are very positive – they are looking out for the community and want to see it foster and grow; and then there are the negative types. I would almost always agree that they too are looking out for the greater good of the community they just express themselves in a slightly different manner.
You must develop a pretty thick skin for those that exhibit a very high level of negativity about any change (good or bad) within the community – after we all cant put our biggest smile on every day, right?
Both of those types serve a huge purpose for the Community and do play an essential role to our collective success.
In this past week, since we launched what we are calling version 2 (v2.0) of The Store we have directly come into contact with pretty much every type of personality out there: Socializers, Achievers, Killers, Positive types, negative types, etc.. Everyone is coming out of the woodworks…
This is awesome!
The most encouraging thing for us right now is that feedback. Have confidence that we are tracking all items and triaging/fixing the high priority issues as soon as humanly possible. Gemini (bug tracker) and TFS (source control) are very active with frequent changes. We are doing our best to keep on top of the list and publishing to production as soon as it makes sense. Based on twitter there are many of you out there that have directly experienced the fast turn around we strive for, we will do our best to keep that pace going.
Right now, the best way for us to receive feedback is to either email us at store [at] dnncorp [dot] com, or by using our Help Desk.
We need you to communicate, no matter your style - keep it coming!
When we (DNNCorp) originally took ownership of SnowCovered.com from Brice Snow it was running on DotNetNuke 2.1.2 (Release date was June 14, 2004), v1.0 of the .NET Framework and on a low-end hosting provider. Looking back, I recall that we were lucky to get 80% to 90% uptime in any given month. It was on its last legs. We knew, the community knew, we HAD to take action.
Fast forward a little while, and just over a year ago we launched an internal “Upgrade” project for SnowCovered.com. Here is how that story played out…
Our first initiative was to upgrade from the low-end hosting to our own infrastructure which brought up our stability immediately to 99.9% uptime. This was a huge gain for us and the community as a whole. It was nice to be able to rely on solid infrastructure. All of the negativity around the amount of downtime simply fizzled.
Our first significant win!
The next step was to tackle the DNN 2.1.2 issue. For those of you that don’t recall the history of DNN, 2.1.2 was release before the ASP.NET Team release the (then) new Personalization and Membership pieces. The team here spent hours ensuring that every single user in the SnowCovered membership database was upgraded. Countless tests and dry runs were performed, and in the end we prevailed. All users can and will be upgraded fully.
Another win for the team.
The largest task was the actual code base itself. There was a significant amount of rework and simply replacing much of the codebase (VB.NET to C#) as we transitioned it all to the 6.x family of the core framework. At that time we had just hired Nathan Rover and put him on this challenge. He gladly accepted and took the lead. For those of you want have not yet met Nathan, he is a marathon runner – just the man suited for this marathon upgrade and release schedule.
Over the year they took inventory of the feature points, upgraded code, reviewed artwork & designs, cried/yelled/screamed, held design meetings, drank a few gallons of redbull/monster/beaver buzz, QA, upgrade meetings, daily scrums, Unit Tests, more QA, frequent vendor reviews & demos. Project plans were scraped, created and scraped again. We have had churn in almost every aspect of the project.
The team kept running.
There were a few points over the past year were we almost gave up. The stress was high; the light at the end of the tunnel was just barely visible. Nathan and the team pushed on. We persisted.
The team kept running.
Finally the light was blinding. We invited many (~100) of the vendors in for a private Beta; received well over 40 issues, all of which were addressed with great care and attention, and finally accepted the final list of bugs in for the initial RTM release. The team worked day and night nailing these issues down in order to meet our aggressive release schedule, without sacrificing the level of quality we demanded in this release.
As of 3:00AM PST February 9th, 2012 we crossed the finish line!
We are proud to announce that we have released initial public release of "DotNetNuke, The Store"
Congrats goes out to the entire team!
Here is a before screenshot, as of July 19, 2012:

and now…

..we are just getting started…
As we all download the Beta of IE9 we are faced with the challenge of many sites having breaking changes to the UI. This becomes more apparent when you have rich functionality provided by vendors such as Telerik, the FCK Editor, or whatever you have chosen internally.
For example, here is a screen shot of DotNetNuke, using our default skin, breaking under IE9 when using the default “IE9 Standards” mode.
What you see above is the Telerik Editor Provider when editing content using the Text/HTML module. In order to correct the above issue, you must switch IE9 to use a more compatible mode.
If you bring up the IE9 Developer tools, which are standard now as part of the browser installation, by hitting the F12 key.
You will see the tool shown at the bottom of the browser:
Notice the “Browser Mode: IE9” and the “Document Mode: IE9 standards”. You only need to change the “Document Mode:” drop down to “IE8 Standards”:
You page will refresh with the new Document Mode, and it should now properly be showing the right UI.
Last night most of the DotNetnuke team and I traveled into Burnaby, to the BCIT campus where I gave a real quick (1 hour) presentation on the WebMatrix Beta, and Razor Syntax.
I was happy to see that we had over 60 people attend. It was awesome to see the turn out on a hot summer evening.
Download the Slide Deck
There were a number of questions which came up, I will try to remember them all here.
Working with Data – the db.Query() execution, can it be parametrized?
@{
var db = Database.OpenFile("SmallBakery.sdf");
var selectQueryString = "SELECT * FROM Products ORDER BY Name";
}
@foreach (var row in db.Query(selectQueryString)){
<tr>
<td>@row.Id</td>
<td>@row.Name</td>
<td>@row.Description</td>
<td>@row.Price</td>
</tr>
}
Yes, you can. Here is an example.
@{
var db = Database.OpenFile("SmallBakery.sdf");
var Name = Request["Name"];
var Description = Request["Description"];
var Price = Request["Price"];
var insertQuery = "INSERT INTO Products (Name, Description, Price) VALUES (@0, @1, @2)";
db.Execute(insertQuery, Name, Description, Price);
}
What and Who is WebMatrix and Razor targeted to?
Essentially the breadth developer. Those folks that possibly come from a PHP background or even are new to the development world. This will allow for them to onboard with a few minor tweaks to existing projects to get up and running as fast as possible.
Why is Web Matrix even needed when we have Visual Studio?
The initial thoughts are that this product is going to be free. It will have a bare minimum feature set targeted to the scripter. The UI is far simpler than what VS.NET Users are used to. You could consider it as a a stepping stone into VS.NET.
There was some discussion around Razor Syntax and MVC. Using it as a view engine. Here are some resources to help with this answer.
http://gurustop.net/blog/2010/07/06/thoughts-on-razor-microsofts-new-asp-net-mvc-view-engine/
and
http://www.dotnetcurry.com/ShowArticle.aspx?ID=561
The topic of LightSwitch came up as well. Here is the product page
http://www.microsoft.com/visualstudio/en-us/lightswitch
SIMPLEST WAY TO BUILD BUSINESS APPLICATIONS FOR THE DESKTOP, WEB AND CLOUD
Microsoft Visual Studio LightSwitch gives you a simpler and faster way to create professional-quality business applications for the desktop, the web, and the cloud. LightSwitch is a new addition to the Visual Studio family. Visit this page often to learn more about this exciting product.
Conclusion
All in all I felt the talk went well. As usual I went a mile a minute and really tried to slow things down near the end. Luckily there were enough questions to push us for the full hour. If you attended feel free to send me feedback and ask questions. I will do my best to get you the answers – just keep them on topic!
Resources for the discussion
http://www.asp.net/webmatrix
http://netbc.ca/DNCal/EventDetail.aspx?date=2010/08/24
In a shared environment you typically don't have access to delete your database, and recreate it for fresh installs of your product.
I managed to find these scripts which should help you clean out your database.
Use at your own risk.
Delete All Tables
--Delete All Keys
DECLARE @Sql NVARCHAR(500) DECLARE @Cursor CURSOR
SET @Cursor = CURSOR FAST_FORWARD FOR
SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc2 ON tc2.CONSTRAINT_NAME =rc1.CONSTRAINT_NAME
OPEN @Cursor FETCH NEXT FROM @Cursor INTO @Sql
WHILE (@@FETCH_STATUS = 0)
BEGIN
Exec SP_EXECUTESQL @Sql
FETCH NEXT FROM @Cursor INTO @Sql
END
CLOSE @Cursor DEALLOCATE @Cursor
GO
EXEC sp_MSForEachTable 'DROP TABLE ?'
GO
Delete All Stored Procedures
declare @procName varchar(500)
declare cur cursor
for select [name] from sys.objects where type = 'p'
open cur
fetch next from cur into @procName
while @@fetch_status = 0
begin
if @procName <> 'DeleteAllProcedures'
exec('drop procedure ' + @procName)
fetch next from cur into @procName
end
close cur
deallocate cur
Delete All Views
declare @procName varchar(500)
declare cur cursor
for select [name] from sys.objects where type = 'v'
open cur
fetch next from cur into @procName
while @@fetch_status = 0
begin
exec('drop view ' + @procName)
fetch next from cur into @procName
end
close cur
deallocate cur
Delete All Functions
declare @procName varchar(500)
declare cur cursor
for select [name] from sys.objects where type = 'fn'
open cur
fetch next from cur into @procName
while @@fetch_status = 0
begin
exec('drop function ' + @procName)
fetch next from cur into @procName
end
close cur
deallocate cur
I just checked and it looks like the folks at .NET BC have managed to get around to post my up-coming presentation.
Topic: A Lap around WebMatrix
Please join Rob Chartier, VP of Engineering & Support at DotNetNuke, in a brief Lap around the new WebMatrix tool from Microsoft. Rob will cover most of the high-level features of the tool and even dig into the new Razor syntax.
http://netbc.ca/DNCal/EventDetail.aspx?date=2010/08/24
See you then!
A few weeks ago I ripped out a module over the weekend which allowed a Content Editor for DotNetNuke to be able to actually start scripting content within the UI. Imagine being able to embed scripts within (a) the Text/Html module which is complied+interpreted on the server; a Text/Html/Script module.
That is essentially what this Dynamo module allows you to do; Dynamic Language Execution within DotNetNuke. It doesn’t use Reflection.Emit so it is safe in Medium Trust.
I wanted to do a follow-up post to highlight some of the changes that I have made over the past few weeks and to request feedback from you folks.
Context Switching
The first revision of my module did not allow you to switch between HTML and Script in a single script block. In fact it took the entire input you gave it and treated it as Script. Thus you had to hard code all HTML blocks within “echo” statements (aka Response.Write). This was one of my goals for the first release, but I decided to move ahead without it.
I spent a decent amount of time figuring out the best way to handle this, and here is what I came up with:
- By Default the script will treated as HTML.
- You must enclose actual Script within @{ ….. }@ tags.
- It will process each Context in order and append that to a string builder
- Finally, once all Context blocks are complete, emit a LiteralControl with the final content.
I have this working in the recent builds (past 1.5.0), and working quite well.
Error Handling
There are two core areas around Error Handling that I had defaulted to (poorly) in the past. The first was when the Jint (the internal mechanism that handles the Dynamic Scripting Support) throws/returns an error I added it to the module output and emitted it to the page along with the rest of the content. This is now being suppressed. I also break out of step execution of all of the context switching. That is, the step which threw the exception will be the last one to execute. This is for a normal user. For a SuperUser it will Append() the exception and continue the execution.
Second, I set Jint’s debug mode to that of the HttpContext.Current.IsDebuggingEnabled flag. So it aligns Jint’s debugging with what you have set in web.config.
Security
The last piece that I still have left to take care of is Security. Ultimately the Jint engine relies on two methods to handle security. The first of which is to completely Disable the security and the second is to utilize the System.Security.Permissions Namespace in order to control access. For this release I have just completely Disabled Security. My next set of work will be dedicated to creating an Host->Scripting menu item which allows you to control Security on a per Portal basis.
Finally, if you are using the module for anything or if you have any feature enhancements or changes, please let me know. I plan on contributing to this module for the coming months.
I just updated to 1.6 on Codeplex. Go upgrade now!
Introduction
The folks over at Microsoft recently pushed a open source release of their Sprite and Image Optimization Framework onto Codeplex last week. And after a few tweaks I was able to get it running within DotNetNuke, here is how…
Download the Sprite and Image Optimization Framework. Unzip it and open up the ImageOptimizationFramework.sln file using Visual Studio .NET 2010.
Getting it 3.5 Compatible
If you are still running your DotNetNuke installation on 3.5, you will need to change the “Target Framework” for both the “Web Forms Control” and the “Image Optimization Framework” down to 3.5. This can be achieved by right clicking the project and under the “Application” Tab / Target Framework choose “.NET 3.5 Framework”, save and close both property windows.
Next you will notice that when you attempt to build (now that we are on 3.5) you will get a compiler error. In ImageOptimization.cs I changed the following method to look like:
private static void RebuildFromCacheHit(string key, object value, CacheItemRemovedReason reason) {
var data = (object[])value;
string path = (string)data[0];
IEnumerable<string> cachedDirectoriesBelowCurrentFolder = (IEnumerable<string>)data[1];
That is, I replaced their use of the Tuple class with the generic object[]
The second method that needed to be changed is:
private static void InsertItemIntoCache(string path, IEnumerable<string> directoriesBelowCurrentFolder) {
string key = Guid.NewGuid().ToString();
//var value = Tuple.Create(path, directoriesBelowCurrentFolder);
var value= new object[]{path, directoriesBelowCurrentFolder};
HttpRuntime.Cache.Insert(key, value, new CacheDependency(path), Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, RebuildFromCacheHit);
}
Notice again, it was converting the Tuple to use an object[]. I’m sure there is a more optimal way available but this is good enough for this round of testing.
The solution should compile now.
DotNetNuke
If you navigate to the folder” %My Download Directory%\sprite-image-optimization-framework\WebFormsControlSample\Bin\ you will see the 2 compiled DLLs and PDB files. XCopy deploy these into your local (testing) DNN installation’s bin folder.
You will now need to crack open your web.config for your DNN installation and add the following line, under the “System.Web/httpModules” section:
<add type ="Microsoft.Samples.Web.ImageOptimizationModule" name ="Microsoft.Samples.Web.ImageOptimizationModule"/>
This HttpModule assumes that there is a folder at the root of your web site named App_Sprites. You should create that folder now otherwise you will get a yellow screen of death at first load.
The HttpHandler wires up a cache dependency to the App_Sprites folder after “indexing” the content. It will take all of the images in that folder and create the Sprite Image, and associated CSS files. I also noticed that it will actually rebuild these files if they are deleted for any reason.
Notice the CSS files, a dat file and the new sprite0.png file; all of these were created based on the existing images in that folder by the HttpHandler.
Within your module folder structure, create a “App_Sprites” folder, copy your images in to that folder. Like so:
Notice that I set references to both of the ImageOptimizationFramework.dll and the ImageSprite.dll in this project.
In your code-behind file for your module, we will follow the same pattern as the HttpHandler in order to add our Cache Dependency to the ImageOptimizer, like so:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.Samples.Web;
namespace DNN.Sprites.DesktopModules.SpriteSample
{
public partial class Sprite : DotNetNuke.Entities.Modules.PortalModuleBase
{
private static readonly object _lockObj = new object();
private static bool _hasAlreadyRun;
static Sprite()
{
lock (_lockObj)
{
if (_hasAlreadyRun)
return;
else
_hasAlreadyRun = true;
}
ImageOptimizations.AddCacheDependencies(System.Web.HttpContext.Current.Server.MapPath("~/DesktopModules/SpriteSample/App_Sprites/"), rebuildImages: true);
return;
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
And finally in our ascx document we can now use the new ImageSprite control to refer to our images:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Sprite.ascx.cs" Inherits="DNN.Sprites.DesktopModules.SpriteSample.Sprite" %>
<%@ Register TagPrefix="asp" Namespace="Microsoft.Samples.Web" Assembly="ImageSprite" %>
<asp:ImageSprite runat="server" ImageUrl="~/DesktopModules/SpriteSample/App_Sprites/windowsLogo.png" />
<asp:ImageSprite ID="ImageSprite1" runat="server" ImageUrl="~/DesktopModules/SpriteSample/App_Sprites/xbox.png" />
<asp:ImageSprite ID="ImageSprite2" runat="server" ImageUrl="~/DesktopModules/SpriteSample/App_Sprites/office.png" />
Which emits:
With the HTML:
<div id="dnn_ctr6123_ModuleContent" class="SpriteContent">
<img class="windowsLogo-png" src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="border-width:0px;" />
<img id="dnn_ctr6123_Sprite_ImageSprite1" class="xbox-png" src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="border-width:0px;" />
<img id="dnn_ctr6123_Sprite_ImageSprite2" class="office-png" src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="border-width:0px;" />
</div
Play close attention to the class attribute as well. They are using a fairly simplistic naming convention to automatically emit the attribute for predictability.
Although the project seems to be in the early stages I can see it receiving very broad adoption in the near future.
Introduction
Imagine, for a second, you have a server sided JavaScript interpreter built right into a Content Management System. It should have full access to the entire Server sided API’s, depending on security requirements of course. You could literally treat source code as content. That is what this post is about.
If you have ever created a module for DotNetNuke you probably have spent (wasted) countless hours mucking around with Visual Studio, IIS, the file system, packaging, deploying, etc. It didn’t matter if they were the most complex modules, or a simple Hello World module. In the end you probably have come to the conclusion that there just has to be an easier way of doing this.
Enter Dynamo.. (Sorry for the lame name…)
Essentially Dynamo is a DotNetNuke Module which uses Jint under the covers.
Dynamo allows you to completely skip Visual Studio, the debugger, IIS, deployment, packaging, etc... Install this single module and open your DNN installation to the world of dynamic language interpretation.
Since DotNetNuke is a content management system, Dynamo brings your source code directly into the DNN UI. It allows you to create code, on the fly, and manage that code within DNN itself.
A screenshot might help clarify…
As you might not be able to interpret from the above screen shot, this is a server sided scripting language built right into DotNetNuke. In the Scripting Window you edit your script and either Preview or Save it. Notice the fancy syntax highlighting, just no intellisense. When viewing the module it will interpret and render the script at the server side. So the above example produces:
The echo method will emit text to the output container directly. Anything return’ed out of the function will also get slapped into the output container automatically. So you can either use a StringBuilder to append up your content, or just echo content directly. Watch out for Page.Response.Write, it will emit the content at the top of the page; which is consistent with ASP.NET’s rendering.
Examples
Another real world example would be to reproduce (at a very rudimentary level) the Feedback Module which ships with DotNetNuke. Here is the code block:
1: echo("<div valign='top'><fieldset><legend>Provide Feedback</legend>"); 2: echo("Your Email:<br /><input type='text' name='fromemail'><br />"); 3: echo("Subject:<br /><input type='text' name='subject'><br />"); 4: echo("Body:<br /><textarea name='body' rows='10' cols='50'></textarea><br />"); 5: echo("<input type='submit' value='Send Feedback'><br />"); 6: echo("</fieldset></div>");
7: if(Page.IsPostBack) { 8: var fromemail = get("fromemail"); 9: var subject = get("subject"); 10: var body= get("body"); 11: if(fromemail!="" && subject!="" && body!="")
12: return DotNetNuke.Services.Mail.Mail.SendMail(fromemail, "toemail@localhost", "", subject, body, "", "", "", "", "", "");
13: else
14: return ""
15: }
16: else { 17: return "";
18: }
So you should first notice that Dynamo does not support context switching between plain HTML and Code Blocks. Everything is a code block. If you want to emit HTML, you must do something like:
echo("<div valign='top'><fieldset><legend>Provide Feedback</legend>");
Mixing HTML and code is a nice-to-have in the ole product roadmap for the project.
Next you will notice the code itself is a slight mix with JavaScript syntax and .NET Types. The interpreter has the ability to mix each and interpret it accordingly. This also includes being able to call into the DotNetNuke API library as well. It’s important to note that we are using an interpreter and NOT using Reflection.Emit(). Thus we are just fine within Medium Trust.
What else can Dynamo do? Here is a short list of tested scenarios:
- Consumes RSS Feeds (uses RSS.NET)
- Full Database CRUD
- Full Access to the DNN API, including but not limited to Portals/Tabs, Modules, Users, etc..
- Emitting custom JavaScript and CSS (into the Head tag, or CSS inline)
- Detecting PostBack’s
- File I/O
- Rendering files (into the interpreter, and getting the results)
- Twitter Timeline
- Page caching
Your options you have are literally limitless.
Debugging
Since DotNetNuke is Web Based it would be extremely hard difficult to get stuff like intellisense and full step by step debugging working. I don’t have the time right now, but you never know with a future version of the product.
For now, I have the ability to “Show Debugger Details”, in the Edit Script control, when you hit Preview. It literally will emit debug information at each step of the code as it interprets it. I did a simple dump of the Current Statement and the locals available.
With that said I don’t block any exceptions and do bubble them up to the UI, so if you do have issues they will very obvious.
Source Code Versioning
Most professional software developers do use some sort of Source Control software. Right now the tool does NOT have anything built in to help with this. I would love to add this at the very least to the product backlog. Eventually I would love to get to it…
Security
The source code itself contains the line of code which completely disabled all security validations. You can do some serious damage with this. If this bothers you, you should do one of two things:
1. Find the line: JintEngine.DisableSecurity(); Remove it, recompile and redeploy to your server
2. Don’t use this package version in production.
Getting started
There are two methods for you to get started; the easiest method would be to use the prepackaged module installation file here. Download it, and install it into your Development DNN Installation site. The module’s name is “Dynamo” and should be available for you to drop on a page.
The more difficult method would be to grab the source code, and compile it. This would be the method you would need to take in order to re-enable the Security (See the Security section above). This is what I use when building/testing the module itself. So if you need to make other fundamental changes you will need to do this as well.
I would recommend you reset your references to the DotNetNuke specific DLL’s out of your actual bin folder for DotNetNuke. Once you have it building, I personally just use xcopy deployment to the website’s bin and DesktopModules folder and refresh the browser. Debugging can easily be done by setting the breakpoint and attaching VS.NET to w3wp.exe.
Show your DotNetNuke passion by using the DotNetNuke 2010 Firefox Persona, found here.

More Posts
Next page »