Resolving "fileid=xxx" field values to actual file paths

Following a previous article of mine, The dbo.tabs.IconFile field issue, I would like to share an easy way to resolve any field that holds values of the type "FileID=xxx" (where xxx is the primary key of a record in the Files table) into the actual file path. This is especially useful when you deal with the IconFile field in the Tabs table, as well as with fields of type Image in a User Defined Table, and probably in a lot more places too.


I have created a UDF (User Defined Function) which accepts a string value and looks whether it's of type "FileID=xxx". If it is, it constructs the full path (including the portal number) and returns that, otherwise it just returns the initial string with no modification at all. You can use this scalar-valued function inline, in your own SELECT statements, like this:



FROM tabs 



@file varchar(1000)
RETURNS varchar(1000)
declare @retval varchar(1000)
declare @portalid int

if patindex ('FileID=%', @file) >0


declare @fileid int
set @fileid = 
, 'fileid='
, ''

@retval = 
+ convert
, files.portalid
+ '/' 
+ folders.folderpath 
+ files.filename 
left outer join folders
on files.folderid = folders.folderid


set @retval = @file

return @retval




How to promote a regular DotNetNuke user to a superuser

I found this in Kevin Southworth's blog and I think it's worth mentioning since it may save your life in case you have forgotten your superuser's password. Using SQL, you can promote a regular DNN user to a superuser like this:


-- Promote regular user to SuperUser

DECLARE @username varchar(50)

SET @username = 'theUsernameToPromote'

IsSuperUser = 1 
username = @username

UserId = 
FROM Users 
WHERE username = @username)


Simply replace 'theUsernameToPromote' with the user name you need.


Thanks Kevin!



Persisting large values in Module Settings when creating a custom module

So you want to create a simple custom module. At first, it seems easy. Just two or three settings to take care of, no need for complicated, custom tables and unistall/uninstall scripts. DNN's built-in module settings API seems to be enough. But suddenly, needs grow a lot. There are some large values you need to store and the ModuleSettings table won't allow large chunks of information per row. It seems that you have to switch to a custom table which will be holding your settings...

...or use my class :)


I came upon the need of storing just one large value (a serialized object, to be more specific) in a custom module I was creating. I didn't have any way to know how large the serialized (XML) sting would be, since the object was a collection, and I HAD to store it in module settings. I thought it wouldn't be worth to create a custom table and the accompanying code to store settings in a case like this, so I decided to extend DNN's ModuleController class instead.

What I did was to write a new ModuleControllerExtended class which inherits from ModuleController (so I could use it in its place) and add two methods to it:

1. UpdateLargeTabModuleSetting: This method is essentially an extension of the UpdateTabModuleSetting method of the ModuleController class which allows storing large string values in the ModuleSettings table by breaking them into smaller chunks and storing multiple name/value pairs. If a value is small enough to fit into a single row of the ModuleSettings table, then it's stored normally, as it would with the UpdateTabModuleSetting method.

When the value is large, it's stored in 2KB chunks in several rows using a numeric prefix (in the form of _x) for each row, based on the initial name given for the setting. For example, a setting named "SerializedObject" with a value sized at 5KB would be stored in 3 rows with names "SerializedObject_0", "SerializedObject_1" and "SerializedObject_2" accordingly.

The method also takes care to delete rows from the ModuleSettings table every time an update takes place to ensure that there are no leftovers should you specify a value of a smaller size (and probably fewer chunks) than the one that may be already stored.


2. ReadLargeTabModuleSetting: This one reads a large setting doing all the work needed to give you back its string value, but it can also read single-row settings. This is a shared method, and it was added to the class only for consistency. It does not extend any of the known methods of the ModuleController class, meaning you can always remove it from the definition of the class and use it as stand-alone code.


To use the method, you will need the hashtable containing the module's settings, which you can easily get by using the base class GetModuleSettings() method. You feed the method with the hashtable, the module's id and the name of the setting you want and you get a string value containing the "large" value for the setting you specified, or just a setting value should the setting be a "normal" one.


It's not really complicated and it should save you a lot of time when dealing with situations like the one I described above. I would love to hear your comments, though.


Here's the code:


Imports Microsoft.VisualBasic
Imports System.Collections.Generic

Public Class ModuleControllerExtended
Inherits DotNetNuke.Entities.Modules.ModuleController

Public Sub New()
End Sub

Public Sub UpdateLargeTabModuleSetting( _
ByVal tabModuleSettings As Hashtable _
, ByVal tabModuleID As Int32 _
, ByVal settingName As String _
, ByVal settingValue As String)

Dim cntDel As Int32 = 0
Dim o As Object
Dim continueDeleting As Boolean
continueDeleting = True

'Delete all multiple-value module settings, if they exist. 
    While continueDeleting = True
o = tabModuleSettings(settingName + "_" + cntDel.ToString)
If Not o Is Nothing Then
DeleteTabModuleSetting(tabModuleID, settingName + "_" + cntDel.ToString)
cntDel += 1
continueDeleting = False
End If
End While

'Guard - if setting value is less than 2KB, update normally and exit 
    If settingValue.Length < 2000 Then
'Normal value 
        UpdateTabModuleSetting(tabModuleID, settingName, settingValue)
Exit Sub
End If

'If we get to this point, then setting value is more than 2KB. 
    'Delete the original setting (if it exists) so as not to get confused. 
    DeleteTabModuleSetting(tabModuleID, settingName)

'Split the value in 2KB chunks 
    Dim stringList As New List(Of String)
Dim sb As New StringBuilder(settingValue)

While sb.Length >= 2000
stringList.Add(sb.ToString.Substring(0, 1999))
sb.Remove(0, 1999)
End While

'Add the last chunk 
    If sb.Length > 0 Then stringList.Add(sb.ToString)

'Now do the update changing the setting name with the suffix _x (x=0,1,2,etc.) for 
    'each update 
    Dim cnt As Int32 = 0
For Each s As String In stringList
UpdateTabModuleSetting(tabModuleID, settingName + "_" + cnt.ToString, s)
cnt += 1

End Sub

Public Shared Function ReadLargeTabModuleSetting( _
ByVal tabModuleSettings As Hashtable _
, ByVal tabModuleID As Int32 _
, ByVal settingName As String) As String

'Guard - if there is a single setting, just return that and exit 
    Dim objTester As Object
objTester = tabModuleSettings(settingName)
If Not objTester Is Nothing Then
Return (CType(objTester, String))
End If

'If we got to this point, there's a large value stored. 
    'Loop through the records and reconstruct the value. 
    Dim sb As New StringBuilder
Dim cnt As Int32 = 0
Dim o As Object
Dim continueAdding As Boolean
continueAdding = True

While continueAdding = True
o = tabModuleSettings(settingName + "_" + cnt.ToString)
If Not o Is Nothing Then
sb.Append(CType(o, String))
cnt += 1
continueAdding = False
End If
End While

Return sb.ToString

End Function

End Class



Creating pages based on templates - eventually!

All my attempts to use custom templates when creating new DNN pages for my portals were frustrating. Even though I exported the template from a page using the Export feature, the new template would not show up at all in the combo box when creating a new page, although it existed in the file system. Even the default template wouldn't show up!

Here's a simple solution to make those template files appear when you create a new page:

1. Go to Host Settings - Other Settings and locate the "File Upload Extensions" section. Add "template" (without the quotes) there and save your changes.

2. Click "Restart Application" in Host Settings.

3. Go to the File Manager and synchronize files with the "recursive" option set.

4. Optionally, clear the portal's cache in Host Settings (only if it doesn't seem to work differently).

Now you'll have access to your custom templates when creating new pages. Hope that helps.

Related Posts with Thumbnails

Recent Comments

Free DotNetNuke Stuff

Free DotNet Videos

  © Blogger template The Professional Template by Ourblogtemplates.com 2008

Back to TOP