Thursday, June 9, 2011
Useful .Net Tools
Profiling Tools
Slimetune - http://code.google.com/p/slimtune/
xteprofiler - http://www.xteprofiler.com/
Prof-It for C# - http://dotnet.jku.at/projects/Prof-It/Default.aspx
Decompilers
JustDecompile - http://www.telerik.com/products/decompiling.aspx
dotPeek EAP - http://www.jetbrains.com/decompiler/
ILSpy - http://wiki.sharpdevelop.net/ilspy.ashx
Load Testing Tools
loadUI - http://www.eviware.com/loadUI/whats-new-in-loadui-15.html
openSTA - http://opensta.org/
storm - http://storm.codeplex.com/
Functional Testing Tools
soapUI - http://www.eviware.com/soapUI/what-is-soapui.html
WebAii Testing Framework - http://www.telerik.com/automated-testing-tools/webaii-framework-features.aspx
Sunday, May 23, 2010
Pre-populating the Login Control’s Username and Password
We’ve all visited websites that provide a test or demo site and allow you to login for the purpose of testing features out using specific user accounts with assigned roles. If you have a website or web application that needs to provide this type of functionality, I’m going to show you how you can save the user a few keystrokes by filling in the Username and Password for them, so that all they have to do is click the Login button.
What I have done is created three accounts: Admin, User, and Guest along with a Default.aspx page which resides under the respective folder. The folder structure is as follows for these accounts:
Admin/Default.aspx
User/Default.aspx
Guest/Default.aspx
I’ve created a login page (Login.aspx) and dropped a Login Control on it. The Login Control has been converted to a template and I’ve added a label and dropdown list to it. The dropdown list contains the user accounts that will be selected for logging in.
Within the Load event of the Login Control I get a reference to the dropdown list and password textbox controls, so that they can be used in selecting the proper user and populating the password textbox. I add an attribute to the password textbox, which sets the password, so that the user does not have to type it in. Something to be mindful of is that the password is viewable in plain text if you view the pages source. Because these accounts are being used to save the user a few of keystrokes for a test or demo site login this isn’t much of an issue.
DropDownList userLogin = (DropDownList)DemoLogin.FindControl("UserDropDownList");TextBox passwd = (TextBox)DemoLogin.FindControl("Password");switch (userLogin.SelectedValue){case "Admin":DemoLogin.UserName = userLogin.SelectedValue;passwd.Attributes.Add("value", "Adm!n123");break;case "User":DemoLogin.UserName = userLogin.SelectedValue;passwd.Attributes.Add("value", "U$er123");break;case "Guest":DemoLogin.UserName = userLogin.SelectedValue;passwd.Attributes.Add("value", "Gue$t123");break;default:DemoLogin.UserName = string.Empty;passwd.Attributes.Add("value", "");break;}
The only other thing needed is within the Login Control’s LoggedIn event to check the role of the user and then redirect them to the appropriate Default.aspx page.
if (Roles.IsUserInRole(DemoLogin.UserName, "Admin")){Response.Redirect("~/Admin/Default.aspx");}else if (Roles.IsUserInRole(DemoLogin.UserName, "User")){Response.Redirect("~/User/Default.aspx");}else if (Roles.IsUserInRole(DemoLogin.UserName, "Guest")){Response.Redirect("~/Guest/Default.aspx");}else{Response.Redirect("~/Login.aspx");}
While this is pretty trivial, it does save a few keystrokes by allowing the user to just select the user account they wish to login as and then all they have to do is click the login button.
Thursday, May 6, 2010
Display a list of locked users
This example uses a Master Page and within the code-behind is where you keep track of the number of failed login attempts. I’ve set the maxInvalidPasswordAttempts = 3 within the web.config as this is where the hard limit is defined.
<add name="AspNetSqlMembershipProvider" connectionStringName="MyAspNetDB" applicationName="/"passwordFormat="Hashed"passwordAttemptWindow="30"minRequiredNonalphanumericCharacters="1"minRequiredPasswordLength="7"maxInvalidPasswordAttempts="3"type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
Back in the Master Page’s code-behind I’ve defined a member variable called failedLoginCount that will contain the number of failed logins. In addition I’ve added a Page_Init that stores the failedLoginCount in ViewState. I choose to use ViewState because this is a very small amount of information that will be stored, so it won’t inflate the ViewState tremendously.
public int failedLoginCount;protected void Page_Init(object sender, EventArgs e){ViewState.Add("FailedLoginCount", failedLoginCount + 1);}protected void Page_Load(object sender, EventArgs e){failedLoginCount = (int) ViewState["FailedLoginCount"];}
Now within the Login Control’s LoggedIn event the role the user is a member of is checked and if they are in the Administrator role they are redirected to the Admin page; otherwise they are assumed to be a standard user and directed to the Standard users page.
protected void Login1_LoggedIn(object sender, EventArgs e){Login logIn = (Login) LoginView1.FindControl("Login1");if (Roles.IsUserInRole(logIn.UserName, "Administrators")){Response.Redirect("~/Admin/Admin.aspx");}else{Response.Redirect("~/Standard/Standard.aspx");}}
It is within the Login Control’s LoginError event that failedLoginCount is checked to see if it equals the maxInvalidPasswordAttempts value that is defined within the web.config file. I get a reference to the Login control that is contained within a LoginView Control and then set the FailureText letting the user know that their account has been disabled and they need to contact the administrator once their failedLoginCount equals 3. This is followed by locking the user’s account, more formally setting IsApproved to false, which indicates that the user cannot be authenticated. If the failedLoginCount is not equal to 3 the failedLoginCount gets incremented and added to the ViewState key defined as well as the current count is displayed to the user.
protected void Login1_LoginError(object sender, EventArgs e){string emailLink = "<a href=mailto:admin@somesite.com>";emailLink += "Site Administrator";emailLink += "</a>";Login logIn = (Login)LoginView1.FindControl("Login1");if (failedLoginCount == 3){logIn.FailureText = "Your account has been disabled. Please contact the site administrator: " + emailLink;MembershipUser user = Membership.GetUser(logIn.UserName);user.IsApproved = false;}else{logIn.FailureText = "Failed login attempt [" + ViewState["FailedLoginCount"].ToString() + "]";failedLoginCount++;ViewState.Add("FailedLoginCount", failedLoginCount);}}



Now for the Admin portion I simply have a GridView Control that displays the list of users on the site whose accounts are currently locked out. A simple SQL query provides the list of users. I’ve coded this in-line, but in a real application I highly suggest that you put this into a Stored Procedure.
SELECT UserName, Email, LastLockoutDate, IsLockedOutFROM vw_aspnet_MembershipUsersWHERE IsLockedOut = 1
The unlocking of users takes place within the RowUpdating event of the GridView by calling UnlockUser() on the reference to MembershipUser. The following is the code for the admin section.
protected void Page_Load(object sender, EventArgs e){if (!Page.IsPostBack)
{LockedUsersGridView.DataSource = GetLockedUsers();LockedUsersGridView.DataBind();}}private DataTable GetLockedUsers()
{DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyAspNetDB"].ConnectionString)){using (SqlCommand cmd = new SqlCommand("SELECT UserName, Email, LastLockoutDate, IsLockedOut FROM vw_aspnet_MembershipUsers WHERE IsLockedOut = 1", conn)){cmd.CommandType = CommandType.Text;try
{conn.Open();da.SelectCommand = cmd;da.Fill(dt);if (dt.Rows == null || dt.Rows.Count < 1){LockedUsersLabel.Text = string.Empty;
return dt;
}cmd.ExecuteNonQuery();}catch (SqlException sqlEx)
{LockedUsersGridView.Rows[0].Cells[0].Text = sqlEx.ToString();}}}return dt;
}protected void LockedUsersGridView_SelectedIndexChanging(object sender, GridViewSelectEventArgs e){LockedUsersGridView.PageIndex = e.NewSelectedIndex;LockedUsersGridView.DataSource = GetLockedUsers();LockedUsersGridView.DataBind();}protected void LockedUsersGridView_RowEditing(object sender, GridViewEditEventArgs e){LockedUsersGridView.EditIndex = e.NewEditIndex;LockedUsersGridView.DataSource = GetLockedUsers();LockedUsersGridView.DataBind();}protected void LockedUsersGridView_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e){LockedUsersGridView.EditIndex = -1;LockedUsersGridView.DataSource = GetLockedUsers();LockedUsersGridView.DataBind();}protected void LockedUsersGridView_RowUpdating(object sender, GridViewUpdateEventArgs e){TextBox userName = LockedUsersGridView.Rows[e.RowIndex].FindControl("UserNameTextBox") as TextBox;if (userName != null){MembershipUser user = Membership.GetUser(userName.Text.Trim());user.UnlockUser();Membership.UpdateUser(user);}LockedUsersGridView.EditIndex = -1;LockedUsersGridView.DataSource = GetLockedUsers();LockedUsersGridView.DataBind();}protected void LockedUsersGridView_PageIndexChanging(object sender, GridViewPageEventArgs e){LockedUsersGridView.PageIndex = e.NewPageIndex;LockedUsersGridView.DataSource = GetLockedUsers();LockedUsersGridView.DataBind();}
Hopefully you’ll find this useful as a basis for creating a more advanced admin screen for user management.






DisplayLockedUsers.zip
Monday, December 21, 2009
Optimized Cable Experience
I just thought I’d take a moment and share the experience I had with Optimized Cable Company. I was searching for a set of HDMI-DVI and DVI-DVI cables for two monitors and decided to try the products of Optimized Cable Company. I found their selection of cables to be of high quality and their prices to be competitive. What prompted me; however, to write about this was the excellent customer service they provided. So often we are quick to post and talk about our bad experiences and rarely do we share the positive experiences we have with companies.
The positive experience I had with Optimized Cable Company is one of those great experiences you rarely hear about. When I ordered my set of cables, which were delivered very quickly (I might add), I realized I had not paid close enough attention to the connectors. One of my monitors had an HDMI connector, while the other had DVI; however, both of my video cards had DVI connectors. When I realized my ordering error I promptly called them and explained my mistake and they said to just send them back the incorrect cable and they would promptly send me the correct cable, which was slightly more expensive than the one I originally ordered. They did an even exchange and I received the cable I intended to purchase at no additional cost to me or hassle.
Based on the quality of the cables I received, prompt delivery, and the ease of doing business with them. I will direct my future needs for cables to them and highly recommend them for all of your cable needs.
Thank you Optimized Cable Company!
Optimized Cable Company
Thursday, August 6, 2009
Linux and USB Hard Drive “fsck died with exit status 8”
I decided to setup an old AMD 1.7 GHz system I had as a BackupPC server to back up a few machines I have and experienced an issue with a USB 2.0 Hard Drive. I thought I’d share my situation in case someone else runs into a similar situation.
My BackupPC server has 2 internal IDE hard drives and an external USB 2.0 750 GB SATA hard drive, which is used to store the backups. After I had completed the installation of Ubuntu 9.04 Server edition and rebooted I received the following error during the file system checks.
Failed to open the device 'UUID=2b1da3c5-d190-47c9-8f39-760100368e2c' : No Such file or directory
fsck died with exit status 8
...fail!
* File system check failed.
A log is being saved in /var/log/fsck/checkfs if that location is writable.
Please repair the file system manually.
* A maintenance shell will now be started.
CONTROL-D will terminate this shell and resume system boot.
After researching the error and trying various suggestions I realized that all I needed to do was exclude the external USB hard drive from having it’s file system checked during startup. I solved the issue by editing /etc/fstab and setting the entry for the USB hard drive’s PASS column to a 0, which essentially tells fsck to not check the file system.
Before:
# /var was on /dev/sdc1 during installation
UUID=2b1da3c5-d190-47c9-8f39-760100368e2c /var reiserfs relatime 0 2
After:
# /var was on /dev/sdc1 during installation
UUID=2b1da3c5-d190-47c9-8f39-760100368e2c /var reiserfs relatime 0 0
After this little modification to /etc/fstab, I rebooted and once the system came up, I manually mounted the device for my USB 2.0 hard drive as such and all was good.
sudo mount /dev/sdc1
By the way BackupPC setup and configuration can be a little challenging, so I recommend aside from the official documentation the following link, which I’ve found to still be relevant for both Debian and Ubuntu.
Wednesday, November 26, 2008
New Microsoft Charting Control
Congratulations to Microsoft for finally offering a nice set of free charting controls. You can read more and get the download links from ScottGu's Blog link below.
http://weblogs.asp.net/scottgu/archive/2008/11/24/new-asp-net-charting-control-lt-asp-chart-runat-quot-server-quot-gt.aspx
Monday, November 17, 2008
Embedding an image within an email
Here is the Sample's HTML.
NOTE: Make sure to add the attribute ValidateRequest="false" to the Page Directive. This is so that you can embeded HTML into your email message. Also please beware that this will also allow for XSS via Javascript.
<div>
<div>
<asp:Label ID="ToLabel" runat="server" Style="padding-left: 1.8em" Text="To:" />
<asp:TextBox ID="ToTextBox" runat="server" />
</div>
<div>
<asp:Label ID="FromLabel" runat="server" Style="padding-left: .8em" Text="From:" />
<asp:TextBox ID="FromTextBox" runat="server" />
</div>
<div>
<asp:Label ID="SubjectLabel" runat="server" Text="Subject:" />
<asp:TextBox ID="SubjectTextBox" runat="server" />
</div>
<div>
<asp:Label ID="BodyLabel" runat="server" Style="padding-left: .8em" Text="Body:" />
<asp:TextBox ID="BodyTextBox" runat="server" TextMode="MultiLine" Width="250px" Height="100px" />
<asp:Image ID="SelectedImage" runat="server" style="left: 200px; top: 200px;"
Height="100px" Width="100px" />
</div>
<div>
<br />
<asp:Button ID="SendButton" runat="server" Style="margin-left: 10em"
Text="Send" onclick="SendButton_Click" />
</div>
<div>
<br />
<div style="width: 550px; overflow: scroll; height: 100px;">
<asp:DataList ID="ImageDataList" runat="server" BackColor="White"
BorderColor="#CCCCCC" BorderStyle="None" BorderWidth="1px" CellPadding="4"
ForeColor="Black" GridLines="Horizontal" HorizontalAlign="Center"
RepeatDirection="Horizontal" Height="90px" Width="500px"
onitemcommand="ImageDataList_ItemCommand">
<FooterStyle BackColor="#CCCC99" ForeColor="Black" />
<SelectedItemStyle BackColor="#CC3333" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#333333" Font-Bold="True" ForeColor="White" />
<ItemTemplate>
<asp:ImageButton ID="ProfileImageButton" runat="server"
ImageUrl='<%# Eval("FullName") %>' />
</ItemTemplate>
</asp:DataList>
</div>
</div>
</div>
<br />
<asp:Label ID="StatusLabel" runat="server" />
Here's the Sample's Code make sure to include the following namespaces.using System.IO;
using System.Net;
using System.Net.Mail;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
StatusLabel.Visible = false;
DirectoryInfo dir = new DirectoryInfo(Server.MapPath("~/Images"));
int total = dir.GetFiles("*.jpg").Length;
if (total > 3)
{
ImageDataList.RepeatColumns = total + 1;
}
ImageDataList.DataSource = dir.GetFiles("*.jpg");
ImageDataList.DataBind();
}
}
protected void SendButton_Click(object sender, EventArgs e)
{
NetworkCredential loginInfo = new NetworkCredential("username@gmail.com", "yourGMailPassword");
MailMessage msg = new MailMessage();
msg.To.Add(new MailAddress(Server.HtmlEncode(ToTextBox.Text)));
msg.From = new MailAddress(Server.HtmlEncode(FromTextBox.Text));
msg.Subject = Server.HtmlEncode(SubjectTextBox.Text);
msg.Body = BodyTextBox.Text;
AlternateView body = AlternateView.CreateAlternateViewFromString(msg.Subject + "<br /><br />" + msg.Body + "<br /><br /><img src=cid:profile />", null, "text/html");
try
{
LinkedResource profileImg = new LinkedResource(SelectedImage.ImageUrl);
profileImg.ContentId = "profile";
body.LinkedResources.Add(profileImg);
}
catch (ArgumentException argEx)
{
StatusLabel.Visible = true;
StatusLabel.Style.Add("color", "#CC0033");
StatusLabel.Text = "An image was not selected.";
return;
}
catch (Exception ex)
{
StatusLabel.Visible = true;
StatusLabel.Style.Add("color", "#CC0033");
StatusLabel.Text = "The following error occurred: " + "<br /><br />" + ex.Message;
}
msg.AlternateViews.Add(body);
msg.IsBodyHtml = true;
SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
client.EnableSsl = true;
client.UseDefaultCredentials = false;
client.Credentials = loginInfo;
try
{
client.Send(msg);
}
catch (SmtpException smtpEx)
{
StatusLabel.Visible = true;
StatusLabel.Style.Add("color", "#CC0033");
StatusLabel.Text = "The following error occurred: " + "<br /><br />" + smtpEx.Message;
}
catch (Exception ex)
{
StatusLabel.Visible = true;
StatusLabel.Style.Add("color", "#CC0033");
StatusLabel.Text = "The following error occurred: " + "<br /><br />" + ex.Message;
}
StatusLabel.Visible = true;
StatusLabel.Style.Add("color", "#009966");
StatusLabel.Text = "Email sent successfully.";
}
protected void ImageDataList_ItemCommand(object source, DataListCommandEventArgs e)
{
SelectedImage.ImageUrl = ((ImageButton)e.CommandSource).ImageUrl;
}



