Wednesday, February 27, 2013

DNN Manage Button Hidden Behind Another Module

There is one issue I've run into several times with DNN and that is an HTML module covering up another module.  I had this issue with the Dark Knight skin.  An HTML module I had on the ContentPane was covering up the dropdown menu, so I had to make some CSS adjustments to the z-index property.

The issue I have now is slightly different.  I've written several modules that either:
  1. Do not display anything in the View (they work in the background), but you still need to access the Settings to make changes
  2. Do not display anything in the View if there is no data
The problem is if you are in Edit mode and nothing is being displayed, you cannot get to the Manage button because it is 'behind' the Manage button of the module below it.


I've come up with a simple fix for this that I include in my View.ascx file:


<% if(DotNetNuke.Common.Globals.IsEditMode()) { %> 
 
<div runat="server" id="showIfEditMode" >
   <br />
   <br />
   <br />
</div>
 
<% } %> 
 
 


This adds some padding below the module when you are in Edit mode. That way, your Manage button will be visible even when there is nothing to display.

Monday, February 11, 2013

Sorting ArrayList with Linq

This was my first forray into Linq, so I thought I'd post it in case I need it again in the near future.

I needed a list of user to populate a DropDownList.  In DotNetNuke, you can get an ArrayList of all users on the system with a call to: UserController.GetUsers(int PortalID).

The problem is the list is sorted by UserID, so when you open the DDL, you'll see all the users in what seems to be random order.  I wanted the list to be sorted by LastName, FirstName without having to write some sort of IComparer.

This is a great use case for Linq ( I've heard a lot about it, but never used it).


ArrayList a = UserController.GetUsers(0);
var so = from UserInfo s in a orderby s.LastName,s.FirstName select s;
            
ddlUser.DataSource = so;
ddlUser.DataValueField = "UserID"; // Alias Name from Sproc
ddlUser.DataTextField = "DisplayName";   // Alias name from sproc
ddlUser.DataBind();
ddlUser.Items.Insert(0, new ListItem("Select One", "0")); // Adds items to DDL


If you are using a custom object (ie UserInfo), then you must explicitly declare the type.
When using LINQ to query non-generic IEnumerable collections such as ArrayList, you must explicitly declare the type of the range variable to reflect the specific type of the objects in the collection.

Wednesday, August 15, 2012

asp.NET Password Requirements

For an asp.net website, using AspNetSqlMembershipProvider for authentication, there are several settings you can specify to handle password requirements.  Most corporate sites that want to make sure users are entering strong password have several things they look for in a password.

  1. Password Length
  2. Character Types
  3. Password Complexity
  4. Password History
  5. Encryption
  6. Attempts
Most of these settings are kept in the web.config.  Here is a standard setting for the membership provider:


<membership>
  <providers>
    <add 
      name="AspNetSqlMembershipProvider" 
      type="System.Web.Security.SqlMembershipProvider, ..." 
      connectionStringName="LocalSqlServer" 
      enablePasswordRetrieval="false" 
      enablePasswordReset="true" 
      requiresQuestionAndAnswer="true" 
      applicationName="/" 
      requiresUniqueEmail="false" 
      passwordFormat="Hashed" 
      maxInvalidPasswordAttempts="5" 
      minRequiredPasswordLength="7" 
      minRequiredNonalphanumericCharacters="1" 
      passwordAttemptWindow="10" 
      passwordStrengthRegularExpression="" 
    />
  </providers>
</membership>


To control the password complexity, you'll need to set the "passwordStrengthRegularExpression" under the "AspNetSqlMembershipProvider".

I'm not great with Regular Expressions, so I turned to StackOverflow for the following password requirements:
  • At least 8 Characters (up to 100)
  • Must have 3 of the 4 character types (Upper, Lower, Number, Symbol)



(?=^[^\s]{8,100}$)((?=.*?\d)(?=.*?[A-Z])(?=.*?[a-z])|(?=.*?\d)(?=.*?[^\w\d\s])(?=.*?[a-z])|(?=.*?[^\w\d\s])(?=.*?[A-Z])(?=.*?[a-z])|(?=.*?\d)(?=.*?[A-Z])(?=.*?[^\w\d\s]))^.*



An explanation of individual components:

• (?=^[^\s]{8,100}$) - contain between 8 and 100 non-whitespace characters

• (?=.*?\d) - contains 1 numeric

• (?=.*?[A-Z]) - contains 1 uppercase character

• (?=.*?[a-z]) - contains 1 lowercase character

• (?=.*?[^\w\d\s]) - contains 1 symbol

Notice after the length segment the double parens and later in the expression you'll see several
's. This allows for the either/or comparison of the 4 possible combinations that are allowed.

Also, check out RAD Regex Designer, for a FREE tool to test your Regular Expression!

Monday, July 16, 2012

Finding Duplicates in MS SQL Server

Here is a quick snippet on how to find duplicates:


SELECT a.[dr_id]
      ,a.[sch_type]
      ,COUNT(*) as '# records'
  FROM [LZ].[dbo].[lz_src_address1] a
  where a.sch_type = '23'
  group by a.dr_id, a.sch_type
  having COUNT(*) > 1


You only include the fields that you need to determine if its a duplicate and put them in the GROUP BY clausing.  the HAVING clause tells you if there is more than 1 record.

There are several ways to delete duplicates.  They way you choose will depend on if you have a unique key for each row.  If so, you can delete them with a single statement.  If not, you may need to use a cursor and/or temp tables.

Friday, June 29, 2012

MS SQL UPDATE with a JOIN

This describes how to UPDATE a table when you have to JOIN another table.  This is for MS SQL Server, so the syntax varies with other versions.

In this example, I am updating the [aspnet_Membership] table, but I want to join the [aspnet_Users] table so I can do it user UserName.  This script allows me to set the password of a user to my password so I can log in as that user.  This is done by updating the ASP.NET Membership table.  I would need to store the [Password] and [PasswordSalt] of this account if I wanted to change it back.



UPDATE m 
SET   m.[Password] = 'mrhLMUfIWCuTHDwOtm1s/I9ABMQsS=='
    , m.[PasswordSalt] = 'suyp+Nsd2lmMPpQ=='
FROM [dnnDB].[dbo].[aspnet_Membership] m
JOIN [dnnDB].[dbo].[aspnet_Users] u on m.UserId = u.UserId
WHERE 1=1
  AND u.UserName in 
  (
      'FirstUser'
    , 'SecondUser'
    , 'ThirdUser'
  )
  

Wednesday, March 14, 2012

View the Contents of a DataTable or DataView While Debugging

I always forget this because I use four different programming languages(3 different IDEs), so I'll put it up here in case I forget ...... again!  Also, credit to Rob Prouse (on StackOverflow).


The Visual Studio debugger comes with four standard visualizers. These are the text, HTML, and XML visualizers, all of which work on string objects, and the dataset visualizer, which works for DataSet, DataView, and DataTable objects.
To use it, break into your code, mouse over your DataSet, expand the quick watch, view the Tables, expand that, then view Table[0] (for example). You will see something like {Table1} in the quick watch, but notice that there is also a magnifying glass icon. Click on that icon and your DataTable will open up in a grid view.

Friday, March 9, 2012

ASPX Hyperlinks: Opening automatically and in New Windows

Here's a couple quick tips that took me some time to work out.

1. Opening a Hyperlink in a new window:

ASPX


<asp:HyperLink ID="jiraLink" 
runat="server">&nbsp;&nbsp;&nbsp;&nbsp;Click here to Expand Window </asp:HyperLink>

Code-behind:


String jiraURL = "http://" + jiraServerURL +"/jira/secure/IssueNavigator.jspa?sId=" + sessionGUID;
jiraLink.NavigateUrl = jiraURL;
jiraLink.Target = "_blank";



And, to automatically open a Hyperlink, put this in the Page_Load:


Response.Write("<script type='text/javascript'>window.open('" + serverURL+ "','_blank');</script>");