Microsoft.NET Framework directory locations

Since there are directories all over the place for the Microsoft.NET Framework, I have decided to compile a list of some of the key ones used.

Compilers, GACUtil, ASP.NET Register IIS/SQL, Assemblies etc.

.NET 1.0: C:WindowsMicrosoft.NETFrameworkv1.0.3705

.NET 1.1: C:WindowsMicrosoft.NETFrameworkv1.1.4322

.NET 2.0: C:WindowsMicrosoft.NETFrameworkv2.0.50727

After 2.0, more directories were added, the build number was also omitted from the directory name. Some key utilities (for Global Assembly Cache (GAC), ASP.NET, Code Access Security Policy Tool (caspol.exe)) weren’t part of future versions, so, as a result, .NET 2.0 is required by them.

.NET 3.0 uses .NET 2.0 compiler. New directories:

  • C:WindowsMicrosoft.NETFrameworkv3.0Windows Communication Foundation
  • C:WindowsMicrosoft.NETFrameworkv3.0Windows Workflow Foundation (only SQL scripts in here)
  • C:WindowsMicrosoft.NETFrameworkv3.0WPF (Windows Presentation Foundation)
  • C:Program FilesReference AssembliesMicrosoftFrameworkv3.0 (for reference when compiling / developing)

.NET 3.5

  • C:WindowsMicrosoft.NETFrameworkv3.5 (compiler, WPF, MSBuild)
  • C:Program FilesReference AssembliesMicrosoftFrameworkv3.5 (for reference when compiling / developing)

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;
 }
}

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;
    }
}

Code generation with jQuery

Update: changed post title (content still same)

Sometimes, when you are developing in javascript, you need to reference many form inputs on a page, which can be time consuming (typing each one out). With jQuery, you can reduce the time by using jQuery to write the code (which you then copy and paste). For example (simplified, as you probably would not have fields named field1, field2, field3 etc):

var $field1 = $("[name='field1']");
var $field2 = $("[name='field2']");
var $field3 = $("[name='field3']");
var $field4 = $("[name='field4']");
var $field5 = $("[name='field5']");
var $field6 = $("[name='field6']");
var $field7 = $("[name='field7']");
var $field8 = $("[name='field8']");
var $field9 = $("[name='field9']");

This simple script can be used to create the aforementioned code. Includes an ASP.NET fix (if you don’t want names like $ctl00$Content1$Field1)

$(
 function()
 {
  var $inputs = $(":input");
  var $textarea = $("<textarea>").css({width: "100%", height: "200px"});
  $inputs.each(
   function()
   {
    // $textarea.append("var $" + this.name + " = $("[name='" + this.name + "']");n");
    // ASPNET fix to get the name as set server side
    $textarea.append("var $" + ASPNETFix(this.name) + " = $("[name$='" + ASPNETFix(this.name) + "']");n");
   }
  );
  $("body").append($textarea);
 }
)

function ASPNETFix(name)
{
 return name.split("$").pop();
}

Simply save this into a separate JavaScript file (tweaking as needed), include on your page, then copy the text generated in the textarea at the bottom of the page.

This could also save time in other languages, as you control the output (could be C#, VB.NET, PHP, Python etc).