|
by Naveen
19. September 2011 15:15
Every now and then we all run into development of functionality in ASP.Net that requires do some
scheduled tasks that need to be done at some pre-defined time and frequency. Same is true for
development in DNN. Fortunately DNN framework provides a built in framework that allows you to
develop custom scheduled tasks and then deploy them into the portal. The process is
very straight farward. There are some caveats that you need to be aware of when developing
schedules tasks in DNN. I will focus on those caveats in this post exclusively.
DNN Schedule Task Development
To get started you will need a .Net assembly developed that has a class that derives from
ScheduleClient class. If your schedule task is part of an existing module then
you can add a new class to the same module project. Otherwise you will need to create
a new library project. Here is how new class definition may look like.
using DotNetNuke.Services.Scheduling;
public class ReminderScheduler : SchedulerClient
{
public ReminderScheduler()
{ }
public ReminderScheduler(ScheduleHistoryItem historyItem)
: base()
{
this.ScheduleHistoryItem = historyItem;
}
public override void DoWork()
{
this.Progressing();
// ... Add schedular implementation here ...
this.ScheduleHistoryItem.Succeeded = true;
this.Completed();
}
}
As you can see that I have included Scheduling namespace in this class. You
will need it for SchedulerClient definition. DNN uses reflection to create object of scheduler's
class and passes ScheduleHistoryItem as constructor argument. It is important
that implement the parameterized constructor for your class so can set the instance of this
ScheduleHistoryItem object in your implementation. You will need this ScheduleHistoryItem object
for lot of things during the implementation. For example to record log messages for your task
you can use this object to record messages. DoWork is the method that
gets executed when scheduler needs to run. You put all the implementation related to your
scheduled task in this method.
You indicate progress of your task by calling Progressing method and then indicate
finish by calling Completed method. It is best practice to call this method to inidcate
start and finish to let DNN framework do its book keeping and clean up. You will set
property Succeeded on ScheduleHistoryItem object. Now you can
see why it is important to have parameterized constructor implemented. If you do not do so then
any attempt to use ScheduleHistoryItem object will end up exception thrown from your scheduled
task implementation.
No HttpContext
This is very important part of the implementation that you will have to understand. You may think that
since scheduled task is deployed in your DNN portal there will always be web context to work with. That is
not the case. These scheduled tasks are dispatched on separate threads. The context of these threads is
not your web application. So if you try to use objects like HttpContext.Current you
will end up with exception. Therefore it is very important that whatever implementation you
put in place for your task, you do not rely on web context.
Deploying Schedule Task In DNN
You will have to log in with host account to access the menu item used to deploy schedule task(s). Click
on Schedule option and then on that page click on Add Item to Schedule. You
will be presented with UI that looks as below (as of version 5.6.2).
Fill the information as asked in that interface. It is very important that you provide fully qualified name
of the class for your schedule task. Rest of the imformation is very self explanatory. Once
your tasks is deployed it will run as per the schedule you specified.
by Naveen
23. June 2011 19:50
Logging of events, success or failures, during life of an application is very integral part of diagnostics.
When something goes wrong happens first place I would like to go is to some log table (database, file etc.)
to find out what went wrong. I am not going to discuss what it is important to implement logging
mechanism in your application. There are plenty of books, article and posts that provide
some good discussion on this design decision. In this post I am going to focus on how do you use
logging and provide custom events. DotnetNuke provides built in mechanism for logging of all the events. You can
look at these events under Admin > Event Viewer menu when you log in with admin or host account.
When you look at the event viewer page you will find lot of entries. Some of those entries are informative and some
would be related to exceptions and errors that occur during life of application. Let me first show how these entries make
it to the tables in the database or any logging mechanism in DNN. Following code snippet shows
the simplest implementation that you can put in your DNN module to log some entries.
var logController = new EventLogController();
var logInfo = new LogInfo();
logInfo.LogPortalID = portalSettings.PortalId;
logInfo.BypassBuffering = true;
logInfo.LogTypeKey = logType;
logInfo.AddProperty("Message", message);
logController.AddLog(logInfo);
I will describe this code in details as I discuss the logging mechanism during the course of this post. You
can see how easy it is to add entries in the event log of DNN portal. The key to this code snippet and
logging of event is LogTypeKey property of LogInfo object. When you look at
event log, there is a column named Log Type in the grid as you can see from the image below.
You will notice that above the log grid, there is Type dropdown list. If you look at all entries
in this list, you will find that the names in this list match some of the entries in the event log. Yes, each entry
in the event log is associated with these types. This means that you just can not have som arbitrary name specified
for log type entry. Each of these entries have a unique name associated with it which acts as LogTypeKey.
Look at the tables for your DNN installation and you will find two tables dnn_EventLogTypes and
dnn_EventLogConfig that control the logging mechanism. If you look at the entries
in dnn_EventLogTypes, you will find all the names in Types dropdown list in
LogTypeFriendlyName field. And there is a field named LogTypeKey that stores
unique names for each of the log type. And for each of these LogTypeKey values there are entries in
dnn_EventLogConfig table that define attributes for each of these log types. Most importnat
of the fields in that table is LoggingIsActive. This is the field that control if entry for
that type of log will be entered in the database or not.
If you specify value of LogTypeKey that does not exist in dnn_EventLogTypes table, the call
for AddLog method on EventLogController simply returns without adding any
entry in the database for the message that you are trying to add. If you want to use the built in event types, then
you can use simply use of the values from DotNetNuke.Services.Log.EventLog.EventLogType enum.
Color Coding Of Entries In Event Log
When you look at entries in event viewer grid, you will notice that different event types are represented with
different color or styles. These colors or styles come from LogTypeCSSClass field in
dnn_EventLogTypes tables. You will notice heading Color Coding Legend above
the event log grid. If you click on + icon on left, it will expand to a section showing colors for different
log type entries as show in image below.
Custom Event Log Type In DotnetNuke
When you are doing custom module development for DotnetNuke, then you want to have entries in the log that are specific
to your module only. By doing this, it makes it very easy for you to filter the view to see what all errors or
activities are present in the event log for your module. To add custom entries in event log, you have to perform
following two steps before you could use AddLog method to add log entries.
Add New Log Type Key
Pick a unique name that will be used as key for your custom log entry type. And then decide on a friendly
name that will be displayed in the event log view for custom event. Then you can use following code to
add your log type.
var logController = new LogController();
var logTypeInfo = new LogTypeInfo();
logTypeInfo.LogTypeCSSClass = "MyEventCssClass";
logTypeInfo.LogTypeDescription = description;
logTypeInfo.LogTypeFriendlyName = "My friendly name for event";
logTypeInfo.LogTypeOwner = "DotNetNuke.Logging.EventLogType";
logTypeInfo.LogTypeKey = "My Module Event Key"; // Pick unique key name
logController.AddLogType(logTypeInfo);
In the code above replace the values for LogTypeCSSClass, LogTypeKey, LogTypeFriendlyName and LogTypeDescription
properties with the ones that you want to use for your custom event. You can not add the same key twice. If
you call AddLogType with same LogTypeKey again, you will end up with following error.
Violation of PRIMARY KEY constraint 'PK_dnn_EventLogTypes'.
Cannot insert duplicate key in object 'dbo.dnn_EventLogTypes'.
Activate Custom Event Type
After you have added your custom log type, you will need to set its attribute to make it active for logging. This
is done by using AddLogTypeConfigInfo method on LogController. Following
code snippet shows some code from my module.
var logTypeConfigInfo = new LogTypeConfigInfo();
logTypeConfigInfo.LogTypeKey = logTypeKey;
logTypeConfigInfo.LoggingIsActive = true;
logTypeConfigInfo.MailFromAddress = mailserver;
logTypeConfigInfo.MailToAddress = mailTo;
logTypeConfigInfo.EmailNotificationIsActive = false;
logController.AddLogTypeConfigInfo(logTypeConfigInfo);
The most important property of LogTypeConfigInfo object is LoggingIsActive.
If you do not set this property, your custom log type will stay inactive and any AddLog method call
will be ignored. You can call AddLogTypeConfigInfo multiple types. The underlying stored procedure
checks for existing settings. If there is already one for that log type, it simply updates the vlaues in the
table.
Custom Event Log Type Ready!
One you have performed above two steps, you are all set to use your custom event log type in DNN module.
Since you can add entries in dnn_EventLogTypes only one time, you will have to make sure that you do not
attempt to add more than one time. Check if certain log type already exists before adding. Following code
snippet from my custom module shows how it can be done.
public static bool LogTypeKeyInstalled(string logTypeKey)
{
var eventLogController = new EventLogController();
var logTypes = new List<LogTypeInfo>
(eventLogController.GetLogTypeInfo().Cast<LogTypeInfo>());
return logTypes.Any(lt => lt.LogTypeKey == logTypeKey);
}
if (!LogTypeKeyInstalled("LOAD_FAIL"))
{
// Perform add operation for custom log type
}
Now we are all set with custom log type!
2ca08ac9-e556-4ce7-88ae-62413c10f653|0|.0
Views: 1809
Tags: DNN
DotNetNuke
by Naveen
25. May 2011 15:25
While moving my ASP.Net application from Windows 2003 server to Windows 2008 R2 server I ran into following exception
when I tried to access the application.
The value for the 'compilerVersion' attribute in the provider options must be 'v4.0' or later if you are
compiling for version 4.0 or later of the .NET Framework. To compile this Web application for version 3.5
or earlier of the .NET Framework, remove the 'targetFramework' attribute from the element of the Web.config file.
Well this took me by surprise a little because this application has been working for over a year
on Windows 2003 server. I remembered that since this was child application under parent DNN portal, I had to add
following entry in web.config. From being a child application means that my application was configured as
another web application under DNN web application.
<location path="" inheritInChildApplications="false" >
So my first thought based on the exception details was that probably by mistake somebody removed that entry. Well
that was not the case. Then I checked the application pool for parent as well as child application. They both
were configured to use application pool that was using .Net 4.0 with classic pipe line. Then I looked at
compiler options in my child application. It was set as follows and nothing seemed to be wrong
here as well.
<compilation debug="true" targetFramework="4.0" />
Only place left was to check in parent application. After digging through million entries in DNN web.config
file, I found the following that had compiler option set to V3.5.
<compiler language="vb;vbs;visualbasic;vbscript"
type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089" extension=".vb" warningLevel="4">
<providerOption name="CompilerVersion" value="v3.5" />
<providerOption name="OptionInfer" value="true" />
<providerOption name="WarnAsError" value="false" />
</compiler>
<compiler language="c#;cs;csharp"
extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider,System,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
<providerOption name="CompilerVersion" value="v3.5" />
<providerOption name="WarnAsError" value="false" />
</compiler>
After I changed the compiler version to V4.0, my application was happy as a pie! Here is
link to Microsoft document on breaking changes that describes this issue in more detail.
ASP.NET 4 Child Applications Fail to Start When Under ASP.NET 2.0 or ASP.NET 3.5 Applications
by Naveen
11. May 2011 06:56
Caching of data and content plays a big part in performance optimization of any application. This statement
is not limited to a web application. It is pretty much true for any kind of application. In this
post I will not be discussing what is caching and why do it. You will find lot of good resouces
about this on internet.
DNN is no different in this regard that caching can affect performance and some time operations of your
web portal. Recently I spent some time researching how caching works in DNN. And I found some very
interesting and useful information that answered a lot of questions that lot of DNN users have asked
me in the past and I did not have definite answers. In this post I am going to discuss some DNN implementation
details that will help you understand caching in DNN little better.
Cache Time Settings
Lets first look at all the places from where you can control caching in DNN.
Host Settings > Performance Settings
As header suggests and you can see from screenshot below, first place to control caching is in
Host Settings. I will explain little later what the settings under Cache Setting mean
and how they affect caching on your portal.
Module > Settings
Next comes the entry in module's settings. As you can see from screenshot below, you will find
this is under Page Settings section of a module settings.
Caching Provider
Now that you have see how to set cache time, next you will need to know the caching method
used by DNN. Out of the box you have two options, File based and
Memory. As the name suggests, Memory based caching is your standard ASP.Net inproc
cache object. File based caching stores cached content on the disk itself.
FileCacheProvider
DNN stores cached content in a folder under each portal in Portals\0\Cache\Pages
folder. There you will find files containing cached content. You will notice that there are
two types of files in that folder. For example following are two entries from my machine.
44_ACABA51644A302FBB325E30E7931BAF8.attrib.resources
44_ACABA51644A302FBB325E30E7931BAF8.data.resources
First part of the file name is unique cache key that identifies the resource. Second part
of file name is either data or attrib. The file with name attrib stores
time when the cache item is suppose to expire. The file with name data stores actual content
of the cached item. So if you delete any one of these two files, you will end up trashing the cached
content for that item.
Now you are wondering how does cached entries get cleaed up or refresh. DNN launches a thread when application
starts. This thread runs on one minute interval. Every minuts it goes through this folder and
reads attrib files to decide what content files need to be deleted. This thread performs
its action asynchronously so there is minimal performance impact of this thread.
So if you ever feel the need to manually clear cache of your portal, go to the folder and delete all the files
and you will be good. Only caveat is that if your site is live, there is a good chance that cache file may be
in use and locked if some user is accessing the site. You can retry deleting the file.
How does DNN caching works?
Host Settings
In DNN caching works at different levels. First lets see what Cache Setting values in
Host setting mean. There are four posisble values that you can set. These four values
are actually multipliers used with cache time value. Following are values for these multipliers.
- None - 0
- Light - 1
- Moderate - 3
- Heavy - 6
DNN uses these value with caching of module settings. Yes, it is not for caching of module content. It is
actually module settings. You do not want DNN to make a call into database to get settings for the module
for every single user and every single tab. It will put a lot of load on your database and site will be slow.
DNN uses 20 minute cache time for module settings. You can affect this time by changing
value of Cache Setting. For example if you have set this value to moderate,
it would mean that module settings are going to be caches for 20 * 3 = 60 minutes.
Well, this module cache time out setting is well and good when you are using DNN UI to make
modifications to modules. But if you directly want to change your module's settings in database, then
you are at a loss because portal has those settings cached. This would mean that you will have to
some how trigger cache refresh on your module.
Module Settings
Caching of module's content is controlled by time you set in module's settings. This time value is not affected
by Cache Setting value in host setting. If you do not want DNN to cache content of your module, then
set this value to 0. When you hit Update in module settings, DNN clears the cache for the module
as well as that tab. And your users will see fresh content. If you will change cahe time for module directly in database,
it is not going to take into affect till cache time has expired for the module. That means you will have to goto
DNN UI to hit update or clear the cache for the module by hitting Update link.
File Based Cache and Application Restart
As I described earlier how file based caching works. Here is little caveat that may affect you. When
you restart IIS or web server, you probably are expecting all cached items to be cleaned up. This is the
behavior you are used to when using InProc or OutofProc caching in ASP.Net. In DNN when you use
File based caching, the items are not cleared from cache folder untill the time that is set in attrib
file for that item. So if you restart IIS or your server, when DNN application comes back up, it will pick
up the cached content if not expired so far. This can be good or bad depending on your situation. If you
restarted IIS or Web server to refresh content of portal after some major changes, then you are at loss
because DNN will read the content from old cache files. But if restart was for some maintence on server
then you are good because your application is already primed with cached content.
This is where Clear Cache and Restart Application links in
Module Settings and Host Settings will help you. If you need to dump the cache in your portal,
use these links.
This is how DNN caching works under the cover for you. This information is based on DNN 5.6.2 community
version. The implementation may have changed since I reviewed the implementation or it may be
different from Professional version.
by Naveen
9. May 2011 04:56
When you are upgrading a DNN portal or moving the portal from one server to another or attaching to some
existing or different database, you may end up with a situation where Installation Wizard screen
comes up for you. Every time InstallaWizard.aspx page comes up in your DNN portal, it
means that DNN framework thinks that it is a new install of the portal. This could be very
embarassing situation in a live portal. Imagine, you make some changes on server and your user
is presented with installation wizard.
It is important that we all understand what are the factors involved that can cause this installation wizard
to appear. When your DNN portal starts it goes through a series to checks to decide if it needs to prompt
the user to perform a new install or upgrade of the portal.
Is Database provider installed?
First test is performs is a check on Providers/Data Providers folder under your web application.
If this test passes, then it tries to get DNN dataabase version. This test is performed by calling
dnn_GetDatabaseVersion stored procedure. If you have a good installtion of DNN, you will find
this sproc in your DNN database. .Net will throw SqlException if you do not have a database installed
or for some reason it is corrupted. DNN looks for SQL Error Code: 2812 with Severity Level: 16. This error
code translates to Could not find stored procedure. If there is any other error, DNN tags the
error message with suffix ERROR: and then subsequent code goes to next test. If DNN does
not find this sproc in your database, then no further tests are performed and status of your execution is
set to Install and you are presented with InstallWizard screen.
Four Factors To Check
If database check ends up with a status message starting with ERROR:, DNN performs further
tests to determine status. It checks for following things:
- Do you have a InstallationDate entry in web.config file? This test add a score of 1.
- Do you have HTML module installed under DesktopModules folder?
This test adds a score of 2.
- Do you have Portals directory in your web application folder? This test adds a score
of 2.
- Do you have *.log.resources files in your Providers folders? This
add a score of 3.
If test passes with a score of 4 or higher then your installation is considered good. Otherwise your status
is set to Install. This test is not a deterministic test but provides a good indicator
of health of your installation.
Troubleshooting
If you are having problem of InstallWizard.aspx coming up in your already installed DNN portal, start with
answering questions for above tests and then go from there.
6e3599cf-551a-4017-831e-c12960de5c4a|0|.0
Views: 1313
Tags: DNN
DotNetNuke
by Naveen
8. May 2011 20:55
Recently I worked on creating a portal using DNN5.6. This portal was going to replace an existing
site that was built with every early version of DNN that used .Net1.1. After completing the site
came the time to import all the users from existing site to new site. The latest site used ASP.Net
SQL Membership provider. User management tables in old DNN are very different from how DNN
uses ASP.Net membership provider in latest version of DNN. To import DNN users from old version, I had
to do some research on new database tables involved. In this post I will try to provide some details on
all the tables involved in user account managements in DNN that uses SqlMembershipProvider.
MemberShipProvider Table
DNN uses following two tables to store bare minimum login information for a user.
- aspnet_Users
- aspnet_Membership
SqlMembership provider stores user's password in aspnet_Membership table where as user ID as primary
key is stored in aspnet_Users table. These two tables are used to perform first stage of authentication
for a DNN user.
DNN User Tables
DNN maps SqlMembershipProvider user accounts to DNN user accounts in following tables.
- dnn_Users
- dnn_UserPortals
- dnn_UserRoles
Every membership user account has an entry in dnn_Users table. DNN uses a single sign-on for a user for
all portals. An entry in dnn_UserPortals determine user's access to individual portals. By default a user
is not assigned any roles. If you need to assign certain role(s) to user accounts, then look in
dnn_Roles tables and then appropriate entries need to be created in dnn_UserRoles table.
You do not have to manually create any entries in these tables. I would highly recommend using
stored procedures created by DNN to take care of all the database tasks involved in creating user
account(s). Here is simple procedure to follow.
- Use Membership object to create user's account in membership provider. This
can be accomplsihed by Membership.CreateUser method.
- Now call dnn_AddUser stored procedure to create DNN user account mapping to membership
provider user.
- If you need to assign role(s) to user account, then call dnn_AddRole stored procedure
for each user.
This should get you started with importing user accounts into DNN.
4a889324-5221-48b2-b789-2dfc55d450fb|0|.0
Views: 1425
Tags: DNN
DotNetNuke
by Naveen
3. May 2011 13:45
In this post I will discuss decoding of encrypted passwords in ASP.Net SqlMembershipProvider table. This
discussion will help answer to questions as follows:
- How to decrypt passwords stored database created by SqlMembershipProvider?
- How to decrypt passwords in DNN (Dotnetnuke)?
- How to extend a memebership provider object?
- And more questions related to ASP.Net membership provoider using Sql database...
If you are using Microsoft provider SqlMembershipProvider in DNN or any other ASP.Net application,
look in the database and you will find a table aspnet_Membership. This is where
passwords are stored. Depending on how you configured your membership provider, these passwords
may already be in clear text. This behavior is controlled by an attribute in definition of
membership provider in config file of your application.
passwordFormat="Encrypted"
There is PasswordFormat field in the database table as well. That means handling
of password values depends very heavily of this value. If your passwords are encrypted, then
the value of this field is set to 2.
Algorithm for encrypt and decrypt of password
Next you need to know what algorithm and key is used to encrypt and decrypt the password. Default
implementation of Membership provider picks up these values from machineKey
settings from your config file. So in your config file under system.web you
will notice an entry like:
<machineKey validationKey="AD3642D1C078D34C05741E5A63514C784......."
decryptionKey="F18D8F1FA9F986B26B9F0C8CB4067CAC45E25F4BD6........"
decryption="3DES" validation="SHA1" />
This is where your algorithm and keys are defined. And this is what default implementation of
SqlMembershipProvider uses.
How to decrypt password?
MembershipProvider class has DecryptPassword and EncryptPassword methods that
are used by SqlMembershipProvider. When I started researching this topic, I found suggestions on
creating a new class that inherits from MembershipProvider class and then call DecryptPassword
method to do the job. Well I did try that approach and it did not work. I always ended up with following
exception.
Unable to validate data.
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData
(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length,
Boolean useValidationSymAlgo, Boolean useLegacyMode, IVType ivType, Boolean signData)
at System.Web.Security.MembershipAdapter.EncryptOrDecryptData(Boolean encrypt,
Byte[] buffer, Boolean useLegacyMode)
at System.Web.Security.MembershipProvider.DecryptPassword(Byte[] encodedPassword)
at MembershipPasswordRecover.NetFourMembershipProvider.GetPassword(String encPwd) in
at MembershipPasswordRecover.Program.Main(String[] args) in
After looking through the code in reflector, I saw that Microsoft providers decrypts in two steps.
The encrypted password is actually a Base64 conversion of encrypted data. So first it converts it
back from Base64 and then calls DecryptPassword method. I just did the easiest thing. Copied the code
from Microsoft implementation, removed all the checks it was doing and then used it. Following
class is an example of a class derived form SqlMembershipProvider with a method that just
returns me password in clear text for a given encrypted password.
namespace MembershipPasswordRecover
{
public class NetFourMembershipProvider : SqlMembershipProvider
{
public string GetClearTextPassword(string encryptedPwd)
{
byte[] encodedPassword = Convert.FromBase64String(encryptedPwd);
byte[] bytes = this.DecryptPassword(encodedPassword);
if (bytes == null)
{
return null;
}
return Encoding.Unicode.GetString(bytes, 0x10, bytes.Length - 0x10);
}
}
}
static void Main(string[] args)
{
var passwordManager = new NetFourMembershipProvider();
var clearPWd = passwordManager.GetClearTextPassword("encryptedpasswordhere");
Console.WriteLine(clearPWd);
}
Configuration of your recovery application
If you are putting this password decryption code in a separate application, then you have to
ensure the following things.
- Create machineKey section in your configuration file under system.web section.
It does not matter if you are creating a web application or console application, you always
have a application configuration file you can create this entry.
- You do not have to add an entry for SqlMembershipProvider in configuration file for recovery
of the password. But it is good idea to that you copy the same settings from web application into
your password decryption application as well.
Here is how app.config file looks in my sample console application. You can
see that I do not need a web application to include system.web section in my console
application.
<?xml version="1.0"?>
<configuration>
<system.web>
<machineKey validationKey="AD3642D1C078D34C05741E5A63514C784......."
decryptionKey="F18D8F1FA9F986B26B9F0C8CB4067CAC45E25F4BD......"
decryption="3DES" validation="SHA1" />
<membership defaultProvider="AspNetSqlMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="SiteSqlServer" enablePasswordRetrieval="true"
enablePasswordReset="true" requiresQuestionAndAnswer="false"
minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0"
requiresUniqueEmail="false"
passwordFormat="Encrypted"
applicationName="DotNetNuke"
description="Stores and retrieves ......." />
</providers>
</membership>
</system.web>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
</configuration>
by Naveen
5. April 2011 14:23
In this post I will discuss how to programtically login into a DNN protal. In the past
I wrote about how to do this for any ASP.Net in general. Well the basic idea is still the same.
You will need to HttpWebRequest object to send a POST request to login page of
DNN portal. In the POST request you will provide login credentials, user name and password, through
FORM variables or query string variables. And then set the value for __EVENTTARGET
variable to ID to login button and you are done. Only thing that is left is to know
what are names of keys that corresponds to text boxes for user name and password.
If you are using default Login page of DNN then here are the values of those control
IDs.
- dnn$ctr$Login$Login_DNN$txtUsername: For user name value
- dnn$ctr$Login$Login_DNN$txtPassword: For password value
- dnn$ctr$Login$Login_DNN$cmdLogin: For __EVENTTARGET that corresponds to Login button page
Here is code snippet that shows how I had set up my handy method to prepare login data
that goes in the POST request.
public static String CreateLoginRequestData()
{
StringBuilder reqData = new StringBuilder();
reqData.AppendFormat("{0}={1}","returnurl", "home.aspx");
reqData.AppendFormat("&{0}={1}", "dnn$ctr$Login$Login_DNN$txtUsername",
"myloginname");
reqData.AppendFormat("&{0}={1}", "dnn$ctr$Login$Login_DNN$txtPassword",
"mypassword");
reqData.AppendFormat("&{0}={1}", "__EVENTTARGET",
"dnn$ctr$Login$Login_DNN$cmdLogin");
return reqData.ToString();
}
Based on this information, here is code snippet that will send request to login page
and then get response.
HttpWebRequest webReq = WebRequest.Create(loginUrl) as HttpWebRequest;
webReq.CookieContainer = cookies;
webReq.AllowAutoRedirect = true;
webReq.Method = "POST";
webReq.ContentType = "application/x-www-form-urlencoded";
byte[] postDataBuffer =
Encoding.UTF8.GetBytes(CreateLoginRequestData());
webReq.ContentLength = postDataBuffer.Length;
var strmPostData = webReq.GetRequestStream();
strmPostData.Write(postDataBuffer, 0, postDataBuffer.Length);
strmPostData.Close();
var webResponse = webReq.GetResponse() as HttpWebResponse;
by Naveen
16. December 2010 14:59
Recently I was working on a DNN portal that was restricted to intranet view only because of it being
in development stage. We did not want to open the access to publc yet. So I had IP restrictions
in place so only internal network access is allowed. When it came time to do the demo for external
client, I ad to open up the access to DNN portal for public access. One option you have is to
add IP address in access restriction list and allow it to access it. But lot of time you may run
into external users who do not have a fixed IP address. And this is more of a case for mobile users
where IP addresses change every single time you get disconnected and connected. So the solution
you can use is to enable windows authentication on your portal and create an account for user(s) who
want to view it from outside the network.
Enabling windows authentication for a DNN portal is no different than doing it for any other
ASP.Net application. Your first instinct is that you can change authentication type in web.config
of DNN application. No, that is not what you want to do because then you will not be able to
use your DNN membership provider that works off of the database. Here are steps that you will
need to follow to use mixed Windows and Forms authentication for DNN portal.
-
Start IIS and click on your DNN portal web site and click on Authentication tab
or icon.
-
Disable anonymous authentication and Enable windows authentication. On IIS7 and
higher, your UI may look as below.
Next step is very important. Since DNN requires full permission set on the physical folder
where DNN portal is installed, you will have to make changes to the security on that folder. Give
user(s) or group(s) the required rights on the folder. Otherwise you will end up with
401 - Access Denied even after you enter valid windows credentials.
by Naveen
28. September 2010 13:54
Download Custom DNN Login Module (43.27 kb)
These days I am working on putting together a DNN site. One of the requirements for the
site is to have a login page that is different from what DNN offers out of the box. There
are some third party DNN modules available that allow you to customize the look of the login page
all together. But my requirements are something that does not fit into any of the modules
available out there. So I was on mission to develop my own DNN login module.
If you understand how default login process works and what module gets displayed when you click
on login link on the page, then things are very stright forward.
Click on Login link
If you look at the skin that you are using, you will find that it is using Login control
that is present in admin>skins folder of your DNN web site folder. Key to the
whole process is cmdLogin_Click event handler method that gets called when
you click on Login link or button on your page. If you look at the code, you will find the following
set of code that is trying to find URL to where request should be redirected.
Response.Redirect(LoginURL(ReturnUrl, (Request.QueryString("override") IsNot Nothing)), True)
This LoginURL method is the one that decides what page will be shown for login. This
method is implemented in core DNN library. This is present in DotnetNuke.Common namespace
in Globals.vb file. I will not post the code here but I will explain it how this
discovery of login page works.
First it is looking for a tab id for login page. This is critical piece that you will need to know. If
login as Admin on the site and goto Site Settings menu item, you will find
the following set of controls on there under Advanced Settings that allows you to configure some of the key pages of your site.
The drop down for Login Page is where you will configure what page to show when
user clicks on Login link. If this entry is set to Not specified that means
tab id fotr login page in Portal Settings is -1. LoginURL looks at the TabID for login page. If this
value is not set meaning the value is -1, then code redirects the users to default DNN login page.

But if you have a page set in Login Page dropdown then LoginURL finds all the
modules on that page. Then it iterates over all the modules and check if there is atleeast one
module that has frieldly name of Active Login. Following code is from Globals.vb that
shows this implementation.
Public Function ValidateLoginTabID(ByVal tabId As Integer) As Boolean
Dim hasAccountModule As Boolean = Null.NullBoolean
For Each objModule As ModuleInfo In New ModuleController().GetTabModules(tabId).Values
If objModule.ModuleDefinition.FriendlyName = "Account Login" Then
'We need to ensure that Anonymous Users or All Users have View permissions to the login page
Dim tab As TabInfo = New TabController().GetTab(tabId, objModule.PortalID, False)
If TabPermissionController.CanViewPage(tab) Then
hasAccountModule = True
Exit For
End If
End If
Next
Return hasAccountModule
End Function
Now this is a big problem. This is friendly name of login module that DNN supplies with the framework. So
in a way you are forced into using the built in login module. So if you do not have this module
on the page, then you will get following error.
You have been redirected to this default Login Page because the Login Page set for this website does not contain a valid DotNetNuke Account Login module, or the permissions have not been set correctly.
Does this mean that you can not build a custom login module. Answer is simple. Yes, you can build your own
custom module but you will just need to work around this bug or feature or whatever you want to call it. I
will discuss that shortly.
Build Custom DNN Login Module
Now you can go ahead build your custom module that you want to use for login. I will leave those
details to you. I have included a sample custom login module that I have put together by copying implementation
from DNN login module and tailored it to my needs. Once you have developed the module, add a page into
your portal. You can choose the option of not showing in menu. Now goto Admin > Site Settings > Advanced Settings option. Under Page Management section, in Login Page dropdown list, select the page that we just added for login. On this page, add your custom module. Now add Active Login module that ships with DNN framework. Now in settings of this Active Login module, set the option that it is visible to Administrators only. This will ensure that all conditions of login module are satisfied on the page to include your custom login module. And this default login module will stay hidden from your users. And you are all set to go!
Caution
Login module is very crucial module in your portal. If you mess this up, you can make your site unusable because
nobody will be able to login including you as super user. Now you can see why DNN has some kind of check on
module on the page to decide if they want to allow custom login module or not. Here are some of my suggestions
that I follow when doing custom login module development.
- When starting development and initial testing of the module, do not make changes in site settings to
direct login link to your new login page. Initially have your login page visible in menu or access it
directly test out your module. Once you are satisified with it, then make site settings change.
-
If you do mess up the module and find your self in situation where you can't login. You have few options.
- Go into the database and remove the portal settings for Login tab id.
- If you can't find the entryies in database, then in ValidateLoginTabID method that
i mentioned above, force it to return False all the time. This will make sure that
you will get redirected to built-in login page.
Sample Custom DNN Login Module
The attached sample is custom DNN login module developed using DNN5.5 libraries in Visual Studio 2010. I have
just added bare minimum code to show you how login works. You can extend this module to customize to your
need and taste. If you have any quesitons, feel free to contact.
9dcd0643-9179-4b4e-8e5e-d637faa3bc17|1|5.0
Views: 7878
Tags:
DotNetNuke
|
|