AddUser.aspx File

When the logon page cannot find the e-mail name in the Users.xml file, it redirects the request to the Add User page. When the user clicks the Add User button, the user name and password are added to the file.

To implement the Add User page

  1. Import the necessary namespaces.

    <%@ Page LANGUAGE="c#" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Web.Security " %>
    <%@ Import Namespace="System.IO" %>
    <html>
    <head>
    <title>Forms Authentication</title>
    
  2. Create a script section tag.

    <script runat=server>
    
  3. Implement a Page_Load function.

    private void Page_Load(Object Src, EventArgs e) 
    {
    
    1. Get the UserEmail and UserPassword strings from the request.

          String email = Request.QueryString["UserEmail"];
      
    2. If it is not null, fill the UserEmail text box with the user's e-mail name. UserEmail has already been validated by the RegularExpressionValidator control on the Logon.aspx page.

          if( null != email )
          UserEmail.Value = email;
          }
      
  4. Implement the AddUser_Click function. Note that an inherent race condition occurs if two clients call AddUser.aspx at approximately the same time. If the timing is right, it is possible that one client writes a copy of Users.xml with its new data and overwrites the file just written by the first client. If a race condition is a concern, you should institute some sort of synchronization mechanism in your application to ensure that clients don't execute AddUser.aspx at the same time. That mechanism could be as simple as an application variable that acts as a mutex that every client exclusively claims just before executing the code in the AddUser_Click event.

    private void AddUser_Click(Object sender, EventArgs e) 
    {
    
    1. If the page is not valid, tell the user.

          if( !Page.IsValid ) 
          {
              Msg.Text = "Some required fields are invalid.";
              return;    
          }
      
    2. Create an instance of DataSet named ds.

          DataSet ds = new DataSet();
      
    3. Initialize a string named userFile with the path to the Users.xml file.

          String userFile = "../users.xml";
      
    4. Read in the XML file to the ds DataSet created in step b.

          FileStream fs = new FileStream(Server.MapPath(userFile), 
              FileMode.Open,FileAccess.Read);
          StreamReader reader = new StreamReader(fs);
          ds.ReadXml(reader);
          fs.Close();
      
    5. Hash the password and add the new name and hashed password to the ds DataSet.

      string hashedpwd =    
          FormsAuthentication.HashPasswordForStoringInConfigFile
              (UserPass.Value, "SHA1");
          DataRow newUser = ds.Tables[0].NewRow();
          newUser["UserEmail"] = UserEmail.Value;
          newUser["UserPassword"] = hashedpwd;
          ds.Tables[0].Rows.Add(newUser);
          ds.AcceptChanges();
      
    6. Write the new DataSet with the new name and password to the XML file.

          fs = new FileStream(Server.MapPath(userFile), FileMode.Create, 
              FileAccess.Write|FileAccess.Read);
          StreamWriter writer = new StreamWriter(fs);
          ds.WriteXml(writer);
          writer.Close();
          fs.Close();
      
    7. Redirect the request back to the originally requested resource (Default.aspx) and start the log on process over again. With the exception of the button name, the following form is identical to the one described for the Logon.aspx file.

          Response.Redirect("../Default.aspx");
      }
      </script>
      <body>
      <form runat=server>
          <div style="background:#ccccff">
              <h3><font face="Verdana">Add New User</font></h3>
          </div>
      
      <table>
        <tr>
            <td>Name:</td>
            <td><input id="UserEmail" type="text" runat=server/></td>
            <td><ASP:RequiredFieldValidator 
                 ControlToValidate="UserEmail" 
                 Display="Static"
                 ErrorMessage="*"
                 runat=server/>
            </td>
            <td><asp:RegularExpressionValidator id="RegexValidator" 
                 ControlToValidate="UserEmail"
                 ValidationExpression="^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"
                 EnableClientScript="false"
                 Display="Static"
                 ErrorMessage="Invalid format for e-mail address."
                 runat="server"/>
            </td>
        </tr>
        <tr>    
            <td>Password:</td>
            <td><input id="UserPass" type=password runat=server/></td>
            <td><ASP:RequiredFieldValidator 
                 ControlToValidate="UserPass" 
                 Display="Static"
                 ErrorMessage="*"
                 runat=server/>
            </td>
        </tr>
        <tr>
            <td>Persistent Forms:</td>
            <td><ASP:CheckBox id=Persist runat="server"
                              autopostback="true"/>
            </td>
        </tr>
    </table>



   < input type="submit" OnServerClick="AddUser_Click" Value="Add User" 
           runat="server"/><p>
    <asp:Label id="Msg" ForeColor="red" Font-Name="Verdana" 
               Font-Size="10" runat=server/>
</form>
</body>
</html>

See Also

ASP.NET Web Application Security | Forms Authentication Using an XML Users File