ASP.NET Snippet: Delete All Users and Roles

Deleting all users and related data from a site using ASP.NET authentication is fairly simple. Useful if copying a database and you want to remove all the users, but keep the structure and other data (e.g. user content) intact.

Delete all users:

foreach (MembershipUser u in Membership.GetAllUsers())
{
 Membership.DeleteUser(u.UserName, true);
}

Delete all roles:

foreach (string role in Roles.GetAllRoles())
{
 Roles.DeleteRole(role);
}

ASP.NET Snippet: Quick Password Reset

Here is a simple way, via code to reset a password when you are using the built-in ASP.NET authentication system. Useful if you either don’t have a reset password form, or you just want to quickly change a password. Create a blank page, and place in the code behind Page_Load event.

C#

    protected void Page_Load(object sender, EventArgs e)
    {
        MembershipUser u = Membership.FindUsersByName("Username")["Username"];
        u.UnlockUser();
        u.ChangePassword(u.ResetPassword(), "newpassword");
    }

VB

    Public Sub Page_Load(sender As Object, e As EventArgs)
        Dim u As MembershipUser = Membership.FindUsersByName("Username")("Username")
        u.UnlockUser()
        u.ChangePassword(u.ResetPassword(), "newpassword")
    End Sub

Just delete the page when done.

Update (8 July 2009): If a question and answer is required when you create a user, you have to pass on the answer to u.ResetPassword, e.g. u.ChangePassword(u.ResetPassword("answer"), "newpassword"), otherwise ResetPassword won’t work.

Get ListControl values (CheckBoxList, RadioButtonList, DropDownList, ListBox) from a Repeater the easy way (ASP.NET C#)

Building on Get TextBox values from a Repeater the easy way (ASP.NET C#), here is a function that will get the selected values from WebControls that inherit from ListControl (CheckBoxList, RadioButtonList, DropDownList and ListBox)

It returns null if the ListControl matching the given ID does not exist in the repeater or an empty string array if nothing is selected.

public string[] ListControlValues(RepeaterItem itm, string controlId)
{
 string[] output = null;
 ListControl t = itm.FindControl(controlId) as ListControl;
 if (t != null)
 {
  ArrayList ar = new ArrayList();
  foreach (ListItem li in t.Items)
  {
   if (li.Selected) ar.Add(li.Value);
  }
  output = (string[])ar.ToArray(typeof(string));
 }
 return output;
}

Use in Repeater ItemCommand

protected void MyRepeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
 switch (e.CommandName.ToString())
 {
  case "Save":
   int recordID = Convert.ToInt32(e.CommandArgument);
   string[] listBoxValues = ListControlValues("ListBox1");
   if(listBoxValues != null)
   {
     foreach(string s in listBoxValues)
     {
      
     }
   }
   string[] dropDownValues = ListControlValues("DropDown1");
   if(dropDownValues != null)
   {
    // since dropdown can only have one item selected...
    string dropDownValue = dropDownValues[0];
   }
   ....
   
   break;
  default:
   break;
 }
}

Manga I’ve Bought

Just went into Waterstones one day a while and decided to check out some Manga – mostly due to watching lots of Anime – so wanting to check out the comics. First I tried Ragnarok, which is based on Norse Mythology, but in Manga (or rather, Manwha – Korean comics) style. Found out I liked it, so got all the volumes available – unfortunately it is an unfinished series – up to volume 10 (November 2003, UK).

Also have Ghost In the Shell, which was also very good and volume 1 of Black Cat. Wondering whether I should get the rest of Black Cat or check out something else.

Get TextBox values from a Repeater the easy way (ASP.NET C#)

The asp:Repeater control allows you to attach an ItemCommand event to it, for instance, updating a record in a database.

<asp:Repeater ID="MyRepeater" DataSource='<%# MyData %>' runat="server" 
 OnItemCommand="MyRepeater_ItemCommand">
 <HeaderTemplate><ul></HeaderTemplate>
 <ItemTemplate><li>
 Url: <asp:TextBox ID="Urdl" Text='<%# Eval("Url") %>' runat="server" />
 Text: <asp:TextBox ID="Text" Text='<%# Eval("Text") %>' runat="server" />
 <asp:Button ID="SaveButton" CommandName="Save" CommandArgument='<%# Eval("RecordID") %>' Text="Save" runat="server" />
 </li></ItemTemplate>
 <FooterTemplate></ul></FooterTemplate>
</asp:Repeater>

MyRepeater_ItemCommand is then defined:

protected void MyRepeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
 switch (e.CommandName.ToString())
 {
  case "Save":
   int recordID = Convert.ToInt32(e.CommandArgument);
   TextBox url = e.Item.FindControl("Url") as TextBox;
   TextBox text = e.Item.FindControl("Text") as TextBox;
   
   ....
   
   break;
  default:
   break;
 }
}

However this has several downsides:

  1. If you mistype the control id, you get a NullReferenceException
  2. The code can get cluttered and harder to understand as more TextBox‘s are added.

To help mitigate this, this function gets the value of the TextBox, or null if the TextBox is not found.

public string TextBoxValue(RepeaterItem itm, string controlId)
{
 string output = null;
 TextBox t = itm.FindControl(controlId) as TextBox;
 if (t != null)
 {
  output = t.Text;
 }
 return output;
}

Then you can get the value without an exception occurring:

string url = TextBoxValue(e.Item, "Url");
string text = TextBoxValue(e.Item, "Text");
if(url != null)
{
    // update url in record
}
if(text == null)
{
    // update text in record
}

The code could then be used in a class and used on multiple pages, so if a page doesn’t have a TextBox with a certain ID, the corresponding data field is not updated (e.g. on one page you might want a user to update the URL, but on another more restricted page, you may only want them to change the text). Code behind would then just be:

protected void MyRepeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
 RepeaterMethods.MyRepeater_ItemCommand(sender, e);
}

And the class could be:

using System;
using System.Collections.Generic;
using System.Web;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

/// <summary>
/// Summary description for RepeaterMethods
/// </summary>
public class RepeaterMethods
{
 public RepeaterMethods()
 {
  //
  // TODO: Add constructor logic here
  //
 }

 public static void MyRepeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
 {
  switch (e.CommandName.ToString())
  {
   case "Save":
    string url = TextBoxValue(e.Item, "Url");
    string text = TextBoxValue(e.Item, "Text");
    if (url != null)
    {
     // update url in record
    }
    if (text == null)
    {
     // update text in record
    }
    break;
   default:
    break;
  }
 }

 public static string TextBoxValue(RepeaterItem itm, string controlId)
 {
  string output = null;
  TextBox t = itm.FindControl(controlId) as TextBox;
  if (t != null)
  {
   output = t.Text;
  }
  return output;
 }
}

Binding data to a Repeater using Lazy Loading (ASP.NET C#)

Lazy loading is a method of only loading data as and when you need it. Rather than loading it on page load, you can define a property that can then be bound to a WebControl.

For example, in the page is an asp:Repeater:

        <asp:Repeater ID="MyRepeater" DataSource='<%# MyData %>' runat="server">
            <HeaderTemplate><ul></HeaderTemplate>
            <ItemTemplate><li><a href="<%# Eval("Url") %>"><%# Eval("Text") %></a> (Record ID: <%# Eval("RecordID") %>)</li></ItemTemplate>
            <FooterTemplate></ul></FooterTemplate>
        </asp:Repeater>

MyData in the DataSource attribute of asp:Repeater is a property defined in the CodeBehind page:

    private DataTable _MyData;
    public DataTable MyData
    {
        get
        {
            if (_MyData == null)
            {
                _MyData = LoadMyData();
            }
            return _MyData;
        }
    }

LoadMyData gets the data you want to show (normally it would be loaded from a database, rather than rows added in this case)

    private DataTable LoadMyData()
    {
        Trace.Write("LoadMyData");
        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("RecordID", Type.GetType("System.Int32")));
        dt.Columns.Add(new DataColumn("Text", Type.GetType("System.String")));
        dt.Columns.Add(new DataColumn("Url", Type.GetType("System.String")));

        DataRow row;
        int index = 1;

        // new row
        row = dt.NewRow();
        // populate row
        row["RecordID"] = index;
        row["Text"] = "Google";
        row["Url"] = "http://www.google.co.uk";
        // add row to table
        dt.Rows.Add(row);

        // increment index
        index++;

        // new row
        row = dt.NewRow();
        // populate row
        row["RecordID"] = index;
        row["Text"] = "Yahoo";
        row["Url"] = "http://www.yahoo.co.uk";
        // add row to table
        dt.Rows.Add(row);

        return dt;
    }

The Trace.Write is there to show that the data isn’t loaded if it is not bound to a WebControl in the page. This can be tested by turning on tracing (adding Trace="True" to <%@ Page) and removing DataSource='<%# MyData %>' from the Repeater.

You would then bind the page on load:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            DataBind();
        }
    }

LazyLoadRepeater.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="LazyLoadRepeater.aspx.cs" Inherits="LazyLoadRepeater" Trace="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Lazy Loading</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>Search Engines</h1>
        <asp:Repeater ID="MyRepeater" DataSource='<%# MyData %>' runat="server">
            <HeaderTemplate><ul></HeaderTemplate>
            <ItemTemplate><li><a href="<%# Eval("Url") %>"><%# Eval("Text") %></a> (Record ID: <%# Eval("RecordID") %>)</li></ItemTemplate>
            <FooterTemplate></ul></FooterTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

LazyLoadRepeater.aspx.cs:

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

public partial class LazyLoadRepeater : System.Web.UI.Page
{
    private DataTable _MyData;
    public DataTable MyData
    {
        get
        {
            if (_MyData == null)
            {
                _MyData = LoadMyData();
            }
            return _MyData;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            DataBind();
        }
    }

    private DataTable LoadMyData()
    {
        Trace.Write("LoadMyData");
        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("RecordID", Type.GetType("System.Int32")));
        dt.Columns.Add(new DataColumn("Text", Type.GetType("System.String")));
        dt.Columns.Add(new DataColumn("Url", Type.GetType("System.String")));

        DataRow row;
        int index = 1;

        // new row
        row = dt.NewRow();
        // populate row
        row["RecordID"] = index;
        row["Text"] = "Google";
        row["Url"] = "http://www.google.co.uk";
        // add row to table
        dt.Rows.Add(row);

        // increment index
        index++;

        // new row
        row = dt.NewRow();
        // populate row
        row["RecordID"] = index;
        row["Text"] = "Yahoo";
        row["Url"] = "http://www.yahoo.co.uk";
        // add row to table
        dt.Rows.Add(row);

        return dt;
    }
}