Upgrading DNN 3.x to DNN 4.x 

Recently I have noticed an increased number of questions regarding the upgrade process from DNN 3.x to DNN 4.x and overall I do not think there is very much good documentation available on how to actually complete the upgrade. Therefore with this article I will walk you through the process of upgrading a 3.x site to 4.x, I will try to cover as many of the "gotchas" as possible, but please remember as with all of my other tutorials PLEASE use these at your own risk!

Prerequisites

Prior to completing the upgrade following these instructions you should make sure that each of the following statements are true!

Your DNN Version is 3.3.5 or 3.3.7

I have had much greater success upgrading to the 4.x platform when using either 3.3.5 or 3.3.7 as the base version of DotNetNuke for the upgrade. If you are on a previous version of 3.x or 2.x I would recommend an incremental upgrade to take you to 3.3.5 or 3.3.7 before continuing with the upgrade per these instructions.

Your Webserver Supports .NET 2.0

Another important factor to note when performing this upgrade is that your hosting server must support .NET 2.0, typically this is not an issue but you should be aware of what is needed to switch the .NET runtime version for your website. If you are on shared hosting the methods vary and you might need to contact technical support to have the version changed, this all depends on the features of your provider's control panel. The instructions in this guide will cover this change using IIS directly; users on shared hosting must substitute their provider's instructions for those steps.

You have taken a complete site backup!

I cannot stress the importance of this item enough! Be sure prior to attempting an upgrade that you have a full site and database backup, you will need these backups in case something goes wrong during the upgrade. For instructions on how to create a backup please see my tutorial on "Creating DNN Backups".

You have validated that all installed modules will work with 4.x

An often overlooked portion of the upgrade process from 3.x to 4.x is making sure that all of your modules will work successfully with the new version of DNN. This is something that isn't necessarily 100% as there are many unknowns, however I do recommend researching the modules via the developers website to obtain information regarding its use with the 4.x platform.

You have downloaded the 4.x Install Package

The last prerequisite to performing the site upgrade is to ensure that you have downloaded the "Install" version of DNN 4.x that you wish to upgrade your site to. At this time the most current version is 4.5.3 however these instructions should work for any 4.x version. You must NOT use the upgrade package as it does not necessarily contain all needed files.

Starting the Upgrade

The upgrade process can take a significant amount of time to complete so the first thing that I like to do is to switch my application over to the 2.0 framework and then provide an app_offline.htm file to provide a message to the users. I typicaly perform this step as the first part of a 3.x -> 4.x upgrade as this way I can take the site entirely offline and still provide my users a detailed upgrade message. The use of app_offline.htm is ONLY supported by ASP.NET 2.0 therefore we must perform this switch early on.

The first step is to create the app_offline.htm file. This is a static HTML document that will be served to our users while we perform the various file manipulations necessary to upgrade the site from 3.x to 4.x. You may place any content desired in this file then save it as "app_offline.htm" to the ROOT of your DNN installation. Once we update the .NET Framework version to 2.0 it will serve this page as the only content for the site until we delete the file!

Change Virtual Directory to .NET 2.0

Below are the instructions to change your DNN virtual directory to ASP.NET 2.0 using the IIS tool within Windows XP. If you are on a different version of Windows (Vista, 2003) these instructions might be slightly different. If you are on a shared hosting provider please use their instructions and jump to the "Testing The app_offline.htm File" section of this tutorial.

  1. Open the Control Panel
  2. Click on "Administrative Tools"
  3. Click on "Internet Information Services"
  4. Expand the websites node and right click on your virtual directory
    IIS Menu
  5. Switch to the "ASP.NET" tab and change the version to "2.0.50727", then press Ok
    IIS ASP NET Options
  6. You may now exit from all other open windows, including IIS and the control panel

Testing the "app_offline.htm" File

Now that you have performed the above IIS change to ensure that everything is configured properly for the rest of the upgrade you should try to navigate to your website. When you pull up your website the ONLY content you should see is the "app_offline.htm" file. If you see this content please continue on, if you do not please retrace the above steps and ensure that the file is in the proper location with the proper name and that ASP.NET 2.0 is selected.

Rename Existing Web.config

The final thing to do in preparing to upgrade is to rename your existing web.config file. I do this to ensure that the file is not accidentally overwritten. I recommend renaming the file to "web_3x.config" this way that you can easily find it.

Unzip the 4.x Install Package

The next step of the process is to unzip the 4.x install package, you should unzip this and extract all files OVER the existing files for your website. You want to make sure that ALL files are replaces as it is VERY important that no existing 3.x files exist.

File Removal (4.5 and later only)

After unzipping the installation package if you are going to DNN 4.5.0 or later you will need to manually remove a few .dll files from your website's bin directory. These dll's were previously used by the Text/HTML module which was integrated into the DNN core after version 4.5.0. If you find either of the following files in your bin directory you must delete them.

  • DotNetNuke.Modules.Html.dll
  • DotNetNuke.Modules.Html.SqlDataProvider.dll

Update/Merge release.config

The final step in the upgrade process is to update/merge the release.config file with the information from your existing web.config file, each sub-section below will discuss 1 action that you will need to take to validate/merge the information.

Rename release.config

To prepare for the final site upgrade you must rename the release.config file to web.config. This file is the standard production configuration of a DotNetNuke website for the upgrade version. We will now merge your existing settings into the file as well as change a few existing configuration items to set your site up for long term success!

Copy Connection Strings

Your existing web.config file (which you should have renamed to web_3x.config) has 1 connection string and it should look like the following:

<add key="SiteSqlServer" value="Server=YourServer;Database=YourDb;uid=YourUser;pwd=YourPassword" />

The new web.config file contains 2 different locations for connection strings, you will need to copy the values from the "Key=" Section of your existing to your new web.config file. After copying the values you should have the following in your new web.config file. (This would be towards the top of the file)

<!-- More options exist above this section..... -->
<connectionStrings>
  
<!-- Connection String for SQL Server 2005 Express -->
  
<add name="SiteSqlServer" connectionString="Server=YourServer;Database=YourDatabase;uid=YourUser;pwd=YourPassword;" providerName="System.Data.SqlClient" />
</
connectionStrings>
<appSettings>
  
<!-- Connection String for SQL Server 2005 Express - kept for backwards compatability - legacy modules   -->
  
<add key="SiteSqlServer" value="Server=YourServer;Database=YourDatabase;uid=YourUser;pwd=YourPassword;" />
  
<!-- More settings exist below this line! -->

Note in my above example that I have removed the other declaration that ws provided as part of the default file but was commented out, this is done to make the web.config more readable.

Modify AppSettings To Prevent Auto Install

Another item that I like to do is to modify the application settings values to ensure that automatic upgrades are not completed. I also put an "installationDate" setting in the new file to make sure that DotNetNuke does not change our machine keys. Please see the below snippet and ensure that your configuration settings match the values below, if you do not have an installation date setting please add it. You will have other items in the AppSettings section but these are the only ones you need to change.

<add key="AutoUpgrade" value="false" />
<
add key="UseInstallWizard" value="false" />
<
add key="InstallationDate" value="05/01/2006" /> 

Copy Machine Key Values

In your existing application you will have two additional appSettings for MachineValidationKey and MachineDecryptionKey it is very important that you copy these values as not copying them will render all of your user accounts useless as the system will not be able to retreive the password. Below is what that settings should look like in your old web.config file, your values WILL be different.

<add key="MachineValidationKey" value="449FEF64C3792134D949DDAA20D29B5D4AB1C61A" />
<
add key="MachineDecryptionKey" value="9C8288BA9F0C4F48B3D8FAF264F4BAA9C600CB31CA383354" />

These values will need to be copied to a slightly different location in your new web config file, to the "MachineKeys" tag. This section should look like the following in your new web.config, replace the existing values with those from your old web.config.

<machineKey validationKey="449FEF64C3792134D949DDAA20D29B5D4AB1C61A" decryptionKey="9C8288BA9F0C4F48B3D8FAF264F4BAA9C600CB31CA383354" decryption="3DES" validation="SHA1" />

Copy Additional Config Settings (If Needed)

The above should be all of the items that you MUST copy over to your new web config file, however, you should take an additional look over your old file to identify any other items that will need to be copied to the new file. Items to look for include appSettings, HttpModules, and HttpRuntime settings. It is impossible to list all of the possibilities of items that must be copied over, so if you have any questions as to what should/shouldn't be copied over please feel free to post a question in the forum on this site.

Running the Update

After completing all of the above steps you should now be ready to actually trigger the DNN upgrade process. To do this you need to first delete the "app_offline.htm" file that you placed on your site in the beginning. Then navigate to <YourUrl>/Install/Install.aspx where <YourUrl> is your websites URL. This should then trigger the upgrade process, you should see a series of progress updates then a completion message. Take note of any errors listed on this page, then click on the link to navigate to your portal. You should now have a fully upgraded DNN site.

Troubleshooting

If you encounter any difficulties when trying to run the upgrade to your site be sure to research/view any error logs that are referenced by the DNN installation process. Also if you have any third party modules be sure to check for known issues with the 4.x platform, also, it might be worthwhile to change to a default DNN skin to see if you potentially have an issue related to a 3.x skin.

If you are still unable to get your site working after reviewing the logs, modules, and skins you can revert to your backup or post your question either here or on DotNetNuke.com and someone can try to help you resolve the issues.

Conclusion

I hope this article has been a help to get your website upgraded to the latest and greatest DotNetNuke. If you encounter any difficulties during your upgrade please feel free to use my forums for questions. If you have any comments or suggestions regarding this article please leave it below!

Posted by Mitchel on Thursday, June 28, 2007
 

Comments

This is great information.

But ... to avoid having to take down an existing site to do the upgrade, I'd recommend that you make a duplicate of the existing site (say on a local computer) and do the upgrade there. Then you can test the upgrade without interfering with your site.

When all is well, just replace the existing site with the upgraded site (i.e. move the directory and database to the live server).

And maybe make a second set of backups before migrating the updated site to the live server. (You can NEVER have too many backups!)

By Joe Craig on Friday, June 29, 2007 at 9:12 AM

Joe,

For the most part I would agree with you. My only recommendation against that is that if you are in shared hosting it is most likely NOT possible to do that type of an upgrade. Also if you do not switch the .NET version prior to pushing the site and putting an app_offline.htm file your users will get many errors.

It all depends on your environment, this article is meant for an inplace update, granted many better ideas exist. And you should test the upgrade first!

By mitchel.sellers@gmail.com on Friday, June 29, 2007 at 9:20 AM

Mitchel; Currious as to why you recommend the install version of 4.x rather than the update version of 4.x. I've only done test upgrades so far, but the update seems to work OK (except for a minor font change problem). Also thanks for explaining WHY some of the steps had to be taken; the existing docs were none too clear on why things had to be done. And yes, the 2 connection strings were a gotcha for me <g>

By Wolffy on Monday, July 02, 2007 at 4:19 AM

I recommend the install version to be 100% sure that ALL files are included. The upgrade from 3.x to 4.x is not necessarily an "upgrade" in the manner that a 4.x to 4.y upgrade is. The change from 3.x to 4.x involved many very deep code changes and I have found that I have the best luck using the install version to ensure that all files get copied.

By mitchel.sellers@gmail.com on Monday, July 02, 2007 at 4:54 AM

Mitchel,

Great article and thoroughly explained. I have one sole client still on the 3.x framework that I will be upgrading in the next day or two to 4.x.

I'll put your instructions to good use. ;-)

Thanks again!

-Ed DeGagne
www.southvillagesoftware.com

By Ed DeGagne on Monday, July 16, 2007 at 9:03 AM

Good luck Ed! Be sure to take good backups first!!!

By mitchel.sellers@gmail.com on Monday, July 16, 2007 at 9:13 AM

Comments from the following blog entry: Upgrading DotNetNuke from 3.x to 4.x, located at: http://guy.dotnet-expertise.com/PermaLink,guid,41c7ac4c-e785-4b3a-88fd-eef5c30bb27e.aspx

By Guy Barrette's Blog on Friday, July 20, 2007 at 4:32 PM

I followed your instructions and my upgrade went very smoothly. Thanks a lot Mitchel.

By Guy Barrette on Friday, July 20, 2007 at 4:35 PM

Another great tutorial by Mitchel, Thanks :)

By Ismet Dumlupinar on Thursday, July 26, 2007 at 10:15 PM

Good article Mitchel.

I'm still running DNN 3.1 but wanting to upgrade to 4.x soon. I have a few modules/skins that only work on 3.x - how would you foresee an upgrade path for this?

I'm guessing i'd have to acquire the latest versions of those modules/skins, perform an upgrade then reinstall those modules/skins.. but would that mean i'd lose some of the formatting/data?

By Luke Myer on Wednesday, August 01, 2007 at 3:48 PM

Luke,

If you get the new module versions, for the most part you should simply be able to upgrade then install the new version and it will then work.

You might get some intermittent errors before the installation of the new version, but typically it isn't too big of a deal.

By mitchel.sellers@gmail.com on Wednesday, August 01, 2007 at 3:51 PM

Hi Mitchel,

Could you shed some light on the database upgrade aspect – I’m still running on SQL2000 - do need to upgrade to 2005 express and restore my backups or will the application work on the old db platform?

Regards,
Hendrik

By Hendrik on Thursday, August 02, 2007 at 1:32 AM

You can stay on 2000 with NO problems at all!

By mitchel.sellers@gmail.com on Thursday, August 02, 2007 at 3:36 AM

I followed the guide and for the most part it was very usefull. However, after the upgrade my site wasn't accesible anymore. Only thing i got was a message that the modules couldn't be loaded.

After trying various things i put back the 2 files which according to the guide had to be removed. After that the site was up and running again.

Not sure what this is about but i thought it would be good idea to post my findings here.

Regards,
Jacob

By Jacob Iedema on Monday, August 13, 2007 at 4:03 AM

Hi... I followed the directions but the site does not upgrade. I have a dedicated server.

I see the following error in the Event log:

".... stored procedure 'GetEventMessages' does not exist...." (it does not exist in the database)

Any ideas? Thanks!

By Jonathan on Saturday, September 08, 2007 at 12:19 PM

When going through the upgrade process did you get any errors?

Also, are you 100% sure that you have BOTH connection strings set properly in the new web.config?

By mitchel.sellers@gmail.com on Saturday, September 08, 2007 at 12:22 PM

Hi... I was able to upgrade. Previously I was using the server's IP address in the URL. I switched everything to one of my un-used domain names, and that worked.

But I'm getting flaky results... In particular, I set Host Settings > Perfomance > Page State to Memory. Now I can't change it to disk (setting does not stay when I click 'update'). If I change the entry in the table and re-set the services, I get this when I try to login:

Could not find file 'M:\websites\DNN1\Portals\7\Cache\VIEWSTATE_l1pzoo45ajp0v4jaljxzlju1__Default.aspx.txt'

By Jonathan on Saturday, September 08, 2007 at 7:14 PM

Are you sure that the ASP.NET process has full permissions to the file system?

Also, was any error, or module level message displayed when you tried to save the setting?

By mitchel.sellers@gmail.com on Saturday, September 08, 2007 at 7:34 PM

I'm not positive the permissions are set correctly. The Services are set to use 'Local System'. In IIS Admin > App Pools > Identity, 'Network Service' is selected. In IIS Admin > {Web site Name} > Annoymous Access is set to 'IUSR_DED716'.

The web site folder is not under 'Inetpub' (it is on a different drive). What ACLs should I set on the website folder? Would it be better to configure everything to use a Local User Name instead of the service/system accounts?

Thanks!

By Jonathan on Sunday, September 09, 2007 at 7:18 AM

Well, I'm about to give up on this. I started the upgrade process over (using my backed-up 3.3.5 install).

The upgrade worked. However, now I can't add any module to tabs/pages... I get the following error:

I upgraded my site using these helpful instructions: http://www.mitchelsellers.com/Blogs/tabid/54/articleType/ArticleView/articleId/106/Upgrading-DNN-3x-to-DNN-4x.aspx

Now I can't add any modules to tabs/pages. I get the following error; looks like the code is using *two* SQL "objectQualifiers" -- "dnn_" --

DotNetNuke.Services.Exceptions.ModuleLoadException: Invalid object name 'dnn_dnn_Roles'. ---> System.Data.SqlClient.SqlException: Invalid object name 'dnn_dnn_Roles'. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) . . .

The code is using *two* SQL ObejctQualifiers... I checked the web.config and it is correct...

Any ideas? Many thanks!

Thanks.

By Jonathan on Sunday, September 09, 2007 at 5:08 PM

There was a script in the DNN upgrade package that at one time included two object qualifiers. It is discussed on the DNN site, you just need to update the stored procedure to have only 1. I would have to try and dig up the posting..

By mitchel.sellers@gmail.com on Sunday, September 09, 2007 at 5:12 PM

Thanks!! Got it working.

Sorry for the multiple posts!

By Jonathan on Sunday, September 09, 2007 at 5:30 PM

I updated from 3.1.0 to 4.7.0. After updating, everything works fine. But When I click the "login" button, or try to go into login page, it shows the following error......... Thanks.

Server Error in '/' Application.
--------------------------------------------------------------------------------

Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:


Line 78: Public Overrides ReadOnly Property Enabled() As Boolean
Line 79: Get
Line 80: Return AuthenticationConfig.GetConfig(PortalId).Enabled
Line 81: End Get
Line 82: End Property


Source File: C:\Inetpub\wwwroot\citypa.ca.offline\DesktopModules\AuthenticationServices\DNN\Login.ascx.vb Line: 80

By feng on Monday, December 03, 2007 at 12:34 PM

feng,

Are you sure you fully merged all web.config items into the new web.config setup. Also are you sure that all files coped successfully. (If you need further assistance can you please migrate this discussion to the forums on this site.)

By mitchel.sellers@gmail.com on Tuesday, December 04, 2007 at 3:38 AM

Thanks. I have checked web.config and it's ok. but in the past, i removed the login button from the home page, and now in 4.7.0, there is a login control in \DesktopModules\AuthenticationServices\DNN, will this be the problem?

By feng on Tuesday, December 04, 2007 at 4:57 AM

Yes, if you are hard coding the link to the login control that will most likely be an issue as in 4.6.0 they changed the way that login works..

By mitchel.sellers@gmail.com on Tuesday, December 04, 2007 at 7:24 AM

Thanks, So if I wanna upgrade from 3.1.0 to 4.x , the best choice is 4.6.0?

By feng on Tuesday, December 04, 2007 at 11:15 AM

Hi Mitchel,

I upgraded from 3.2.2 to 4.7 and am getting these errors all over the place for basically every third party module. Plus I am not getting the drop-down menus on each module that allows you to delete, move, etc. the module.

Any ideas or suggestions?

Thanks,

Will

Error: Quotable.... is currently unavailable.
DotNetNuke.Services.Exceptions.ModuleLoadException: Could not load type 'DnnForge.Quotes.Quotes'. ---> System.Web.HttpParseException: Could not load type 'DnnForge.Quotes.Quotes'. ---> System.Web.HttpParseException: Could not load type 'DnnForge.Quotes.Quotes'. ---> System.Web.HttpException: Could not load type 'DnnForge.Quotes.Quotes'. at System.Web.UI.TemplateParser.GetType(String typeName, Boolean ignoreCase, Boolean throwOnError) at System.Web.UI.TemplateParser.ProcessInheritsAttribute(String baseTypeName, String codeFileBaseTypeName, String src, Assembly assembly) at System.Web.UI.TemplateParser.PostProcessMainDirectiveAttributes(IDictionary parseData) --- End of inner exception stack trace --- at System.Web.UI.TemplateParser.ProcessException(Exception ex) at System.Web.UI.TemplateParser.ParseStringInternal(String text, Encoding fileEncoding) at System.Web.UI.TemplateParser.ParseString(String text, VirtualPath virtualPath, Encoding fileEncoding) --- End of inner exception stack trace --- at System.Web.UI.TemplateParser.ParseString(String text, VirtualPath virtualPath, Encoding fileEncoding) at System.Web.UI.TemplateParser.ParseFile(String physicalPath, VirtualPath virtualPath) at System.Web.UI.TemplateParser.ParseInternal() at System.Web.UI.TemplateParser.Parse() at System.Web.Compilation.BaseTemplateBuildProvider.get_CodeCompilerType() at System.Web.Compilation.BuildProvider.GetCompilerTypeFromBuildProvider(BuildProvider buildProvider) at System.Web.Compilation.BuildProvidersCompiler.ProcessBuildProviders() at System.Web.Compilation.BuildProvidersCompiler.PerformBuild() at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath) at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) at System.Web.UI.TemplateControl.LoadControl(VirtualPath virtualPath) at System.Web.UI.TemplateControl.LoadControl(String virtualPath) at DotNetNuke.UI.Skins.Skin.InjectModule(Control objPane, ModuleInfo objModule, PortalSettings PortalSettings) --- End of inner exception stack trace ---

By Planet Maine on Friday, December 14, 2007 at 5:13 AM

Thanks for the tutorial - it worked great!

By Joe Caracci on Wednesday, June 11, 2008 at 2:08 PM

Does this process work upto DNN 4.8.x ?
What is the best possible DNN 4 version, as per you ?

Because, when I load DNN 4.8.x, I notice that it starts from DNN 4.4.1

By Jaydeep Bhatt on Saturday, June 14, 2008 at 8:36 PM

Jaydeep,

Yes, it should work just fine. I would go via this process from 3.3.7 -> 4.4.1 -> 4.6.2 -> 4.8.4.

4.8.4 is the ONLY version that I recommend!

By mitchel.sellers@gmail.com on Monday, June 16, 2008 at 4:44 AM

I have manually upgraded from 4 to 4.8

Previously we are using login link http://www.farhathashmi.com/dn/Home/tabid/36/ctl/Login/Default.aspx
like that but now it is not working it gives error that Could not load file or assembly 'DotNetNuke.Modules.Html'

By Anis on Wednesday, July 09, 2008 at 10:35 PM

I have manually upgraded from 4 to 4.8

Previously we are using login link http://www.farhathashmi.com/dn/Home/tabid/36/ctl/Login/Default.aspx
like that but now it is not working it gives error that Could not load file or assembly 'DotNetNuke.Modules.Html'

By Anis on Wednesday, July 09, 2008 at 10:35 PM

The problem is that if I now go to localhost/default.aspx?ctl=login I get an 'object reference not set to an

instance of an object' error. The original 3.2 site does not give me this error so I guess something broke after

upgradation.

- How do I verify if the upgrade was successfull
- Is there some sort of a log with a stack trace which I can examine which would give me a clue as to why the

login page is not coming up.
- Could this be caused by a wrong setting in the machine key in web.config.
I have copied the old key to web.config as it is:
<machineKey validationKey="..." decryptionKey="..." validation="SHA1"/>
I notice 4.8 has some new options like validationKey="AutoGenerate,IsolateApps" and decryption="3DES"
do I need to merge these in?
- Should I compile and run the DNN 4.8 site through Visual Studio 2005 to debug. Is there some documentation on

how to compile the solution

During upgrade I received an error message saying 04.04.00.log Error:HelpURL
The upgrade seemed to have completed successfully though.
I looked at the .SqlData file and I found that 'vw_Modules' had been created in my database.


By zodiac7 on Friday, July 11, 2008 at 1:26 AM

Is there an easier migration path where I can simply create a new 4.x DNN installation and then move my existing sites and content (from 3.x) into the new 4.x installation?

By Peter on Monday, October 20, 2008 at 2:17 PM

Peter,

No, there isn't really. The upgrade isn't THAT hard, you just have to follow a methodical process and you will be fine! (With backups of course!)

By mitchel.sellers@gmail.com on Tuesday, October 21, 2008 at 5:02 AM

I had a problem with the upgrade. After I changed the web.config and try to access install.aspx, it prompts me for username and password. Where does this come from? Any help is appreciated. Thanks.

By caofangc on Monday, November 10, 2008 at 3:03 PM
Click here to post a comment

Donate

Show your appreciation for the content/modules made available by MitchelSellers.com by making a donation. Donations are used to assist with dedicating time to creating free content.