ASP.NET Lab

The Best Web, The Best Future

博客园 首页 新随笔 订阅 管理

本文中的这个代码范例说明了一个 ASP.NET 档案提供者的实现。关于如何编译这个代码并且使用提供者的信息,请参考:[建立并且运行档案提供者范例]。

范例

using System.Web.Profile;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System;
using System.Data;
using System.Data.Odbc;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Collections;

/*

这个提供者操作下列用户数据表结构。

CREATE TABLE Profiles
(
  UniqueID AutoIncrement NOT NULL PRIMARY KEY,
  Username Text (255) NOT NULL,
  ApplicationName Text (255) NOT NULL,
  IsAnonymous YesNo, 
  LastActivityDate DateTime,
  LastUpdatedDate DateTime,
    CONSTRAINT PKProfiles UNIQUE (Username, ApplicationName)
)

CREATE TABLE StockSymbols
(
  UniqueID Integer,
  StockSymbol Text (10),
    CONSTRAINT FKProfiles1 FOREIGN KEY (UniqueID)
      REFERENCES Profiles
)

CREATE TABLE ProfileData
(
  UniqueID Integer,
  ZipCode Text (10),
    CONSTRAINT FKProfiles2 FOREIGN KEY (UniqueID)
      REFERENCES Profiles
)

*/


namespace Samples.AspNet.Profile
{

 public sealed class OdbcProfileProvider: ProfileProvider
 {
  //
  // 全局连接字符串、常规异常消息,事件日志信息。
  //

  private string eventSource = "OdbcProfileProvider";
  private string eventLog = "Application";
  private string exceptionMessage = "An exception occurred. Please check the event log.";
  private string connectionString;


  //
  // 如果是 false,会把异常抛给调用者。
  // 如果是 true,异常会被写入到事件日志。
  //

  private bool pWriteExceptionsToEventLog;

  public bool WriteExceptionsToEventLog
  {
    get { return pWriteExceptionsToEventLog; }
    set { pWriteExceptionsToEventLog = value; }
  }



  //
  // System.Configuration.Provider.ProviderBase.Initialize 方法
  //

  public override void Initialize(string name, NameValueCollection config)
  {

    //
    // 初始化 web.config 中的值。
    //

    if (config == null)
      throw new ArgumentNullException("config");

    if (name == null || name.Length == 0)
      name = "OdbcProfileProvider";

    if (String.IsNullOrEmpty(config["description"]))
    {
      config.Remove("description");
      config.Add("description", "Sample ODBC Profile provider");
    }

    // 初始化抽象基类。
    base.Initialize(name, config);


    if (config["applicationName"] == null || config["applicationName"].Trim() == "")
    {
      pApplicationName = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;
    }
    else
    {
      pApplicationName = config["applicationName"];
    }


    //
    // 初始化连接字符串。
    //

    ConnectionStringSettings pConnectionStringSettings = ConfigurationManager.
        ConnectionStrings[config["connectionStringName"]];

    if (pConnectionStringSettings == null || 
        pConnectionStringSettings.ConnectionString.Trim() == "")
    {
      throw new ProviderException("Connection string cannot be blank.");
    }

    connectionString = pConnectionStringSettings.ConnectionString;
  }


  //
  // System.Configuration.SettingsProvider.ApplicationName
  //

  private string pApplicationName;

  public override string ApplicationName
  {
    get { return pApplicationName; }
    set { pApplicationName = value; }
  } 



  //
  // System.Configuration.SettingsProvider 方法。
  //

  //
  // SettingsProvider.GetPropertyValues
  //

  public override SettingsPropertyValueCollection 
        GetPropertyValues(SettingsContext context,
              SettingsPropertyCollection ppc)
  {
    string username = (string)context["UserName"];
    bool isAuthenticated = (bool)context["IsAuthenticated"];

    // serializeAs 特性将在这个提供者的实现中被忽略。

    SettingsPropertyValueCollection svc = 
        new SettingsPropertyValueCollection();

    foreach (SettingsProperty prop in ppc)
    {
      SettingsPropertyValue pv = new SettingsPropertyValue(prop);

      switch (prop.Name)
      {
        case "StockSymbols":
          pv.PropertyValue = GetStockSymbols(username, isAuthenticated);
          break;
        case "ZipCode":
          pv.PropertyValue = GetZipCode(username, isAuthenticated);
          break;
        default:
          throw new ProviderException("Unsupported property.");
      }

      svc.Add(pv);
    }

    UpdateActivityDates(username, isAuthenticated, true);

    return svc;
  }



  //
  // SettingsProvider.SetPropertyValues
  //

  public override void SetPropertyValues(SettingsContext context,
                 SettingsPropertyValueCollection ppvc)
  {
    // serializeAs 特性将在这个提供者的实例中被忽略。

    string username = (string)context["UserName"];
    bool isAuthenticated = (bool)context["IsAuthenticated"];
    int uniqueID = GetUniqueID(username, isAuthenticated, false);
    if (uniqueID == 0)
      uniqueID = CreateProfileForUser(username, isAuthenticated);

    foreach (SettingsPropertyValue pv in ppvc)
    {
      switch (pv.Property.Name)
      {
        case "StockSymbols":
          SetStockSymbols(uniqueID, (ArrayList)pv.PropertyValue);
          break;
        case "ZipCode":
          SetZipCode(uniqueID, (string)pv.PropertyValue);
          break;
        default:
          throw new ProviderException("Unsupported property.");
      }
    }

    UpdateActivityDates(username, isAuthenticated, false);
  }


  //
  // UpdateActivityDates
  // 在通过 GetPropertyValues 与 SetPropertyValues 方法来访问档案属性的时候更新 LastActivityDate 与 LastUpdatedDate 的值。
  // 把 activityOnly 参数值设置成 true 将只会更新 LastActivityData。
  //

  private void UpdateActivityDates(string username, bool isAuthenticated, bool activityOnly)
  {
    DateTime activityDate = DateTime.Now;

    OdbcConnection conn = new OdbcConnection(connectionString);
    OdbcCommand cmd = new OdbcCommand();
    cmd.Connection = conn;

    if (activityOnly)
    {
      cmd.CommandText = "UPDATE Profiles Set LastActivityDate = ? " + 
            "WHERE Username = ? AND ApplicationName = ? AND IsAnonymous = ?";
      cmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = activityDate;
      cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username;
      cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = ApplicationName;
      cmd.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = !isAuthenticated;
      
    }
    else
    {
      cmd.CommandText = "UPDATE Profiles Set LastActivityDate = ?, LastUpdatedDate = ? " + 
            "WHERE Username = ? AND ApplicationName = ? AND IsAnonymous = ?";
      cmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = activityDate;
      cmd.Parameters.Add("@LastUpdatedDate", OdbcType.DateTime).Value = activityDate;
      cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username;
      cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = ApplicationName;
      cmd.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = !isAuthenticated;
    }

    try
    {
      conn.Open();

      cmd.ExecuteNonQuery();
    }
    catch (OdbcException e)
    {
      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "UpdateActivityDates");
        throw new ProviderException(exceptionMessage);
      }
      else
      {
        throw e;
      }
    }
    finally
    {
      conn.Close();
    }
  }


  //
  // GetStockSymbols
  //   在调用 GetpropertyValues 的时候从数据库中获取储蓄符号。
  //

  private ArrayList GetStockSymbols(string username, bool isAuthenticated)
  {
    OdbcConnection conn = new OdbcConnection(connectionString);
    OdbcCommand cmd = new 
      OdbcCommand("SELECT StockSymbol FROM Profiles " +
        "INNER JOIN StockSymbols ON Profiles.UniqueID = StockSymbols.UniqueID " +
        "WHERE Username = ? AND ApplicationName = ? And IsAnonymous = ?", conn);
    cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username;
    cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = ApplicationName;
    cmd.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = !isAuthenticated;

    ArrayList outList = new ArrayList();

    OdbcDataReader reader = null;

    try
    {
      conn.Open();

      reader = cmd.ExecuteReader();

      while (reader.Read())
      {
          outList.Add(reader.GetString(0));
      }
    }
    catch (OdbcException e)
    {
      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "GetStockSymbols");
        throw new ProviderException(exceptionMessage);
      }
      else
      {
        throw e;
      }
    }
    finally
    {
      if (reader != null) { reader.Close(); }

      conn.Close();
    }

    return outList;
  }



  //
  // SetStockSymbols
  // 在调用 SetPropertyValues 的时候把储蓄符号值插入到数据库中。
  //

  private void SetStockSymbols(int uniqueID, ArrayList stocks)
  {
    OdbcConnection conn = new OdbcConnection(connectionString);
    OdbcCommand cmd = new OdbcCommand("DELETE FROM StockSymbols WHERE UniqueID = ?", conn);
    cmd.Parameters.Add("@UniqueID", OdbcType.Int).Value = uniqueID;

    OdbcCommand cmd2 =  new OdbcCommand("INSERT INTO StockSymbols (UniqueID, StockSymbol) " +
               "Values(?, ?)", conn);
    cmd2.Parameters.Add("@UniqueID", OdbcType.Int).Value = uniqueID;
    cmd2.Parameters.Add("@StockSymbol", OdbcType.VarChar, 10);

    OdbcTransaction tran = null;

    try
    {
      conn.Open();
      tran = conn.BeginTransaction();
      cmd.Transaction = tran;
      cmd2.Transaction = tran;

      // 删除任何现有的值;
      cmd.ExecuteNonQuery();    
      foreach (object o in stocks)
      {
        cmd2.Parameters["@StockSymbol"].Value = o.ToString();
        cmd2.ExecuteNonQuery();
      }

      tran.Commit();
    }
    catch (OdbcException e)
    {
      try
      {
        tran.Rollback();
      }
      catch
      {
      }

      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "SetStockSymbols");
        throw new ProviderException(exceptionMessage);
      }
      else
      {
        throw e;
      }
    }
    finally
    {
      conn.Close();
    }
  }

  //
  // GetZipCode
  // 在调用 GetPropertyValues 的时候从数据库中获取 ZipCode 的值。
  //

  private string GetZipCode(string username, bool isAuthenticated)
  {
    string zipCode = "";

    OdbcConnection conn = new OdbcConnection(connectionString);
    OdbcCommand cmd = new OdbcCommand("SELECT ZipCode FROM Profiles " +
          "INNER JOIN ProfileData ON Profiles.UniqueID = ProfileData.UniqueID " +
          "WHERE Username = ? AND ApplicationName = ? And IsAnonymous = ?", conn);
    cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username;
    cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = ApplicationName;
    cmd.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = !isAuthenticated;

    try
    {
      conn.Open();
      
      zipCode = (string)cmd.ExecuteScalar();
    }
    catch (OdbcException e)
    {
      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "GetZipCode");
        throw new ProviderException(exceptionMessage);
      }
      else
      {
        throw e;
      }
    }
    finally
    {
      conn.Close();
    }

    return zipCode;
  }

  //
  // SetZipCode
  // 在调用 SetPropertyValues 的时候把邮政编码的值插入到数据库中。
  //

  private void SetZipCode(int uniqueID, string zipCode)
  {
    if (zipCode == null) { zipCode = String.Empty; }

    OdbcConnection conn = new OdbcConnection(connectionString);
    OdbcCommand cmd = new OdbcCommand("DELETE FROM ProfileData WHERE UniqueID = ?", conn);
    cmd.Parameters.Add("@UniqueID", OdbcType.Int).Value = uniqueID;

    OdbcCommand cmd2 = new OdbcCommand("INSERT INTO ProfileData (UniqueID, ZipCode) " +
               "Values(?, ?)", conn);
    cmd2.Parameters.Add("@UniqueID", OdbcType.Int).Value = uniqueID;
    cmd2.Parameters.Add("@ZipCode", OdbcType.VarChar, 10).Value = zipCode;

    OdbcTransaction tran = null;

    try
    {
      conn.Open();
      tran = conn.BeginTransaction();
      cmd.Transaction = tran;
      cmd2.Transaction = tran;
      
      // 删除任何现有的值。
      cmd.ExecuteNonQuery();    
      cmd2.ExecuteNonQuery();

      tran.Commit();
    }
    catch (OdbcException e)
    {
      try
      {
        tran.Rollback();
      }
      catch
      {
      }

      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "SetZipCode");
        throw new ProviderException(exceptionMessage);
      }
      else
      {
        throw e;
      }
    }
    finally
    {
      conn.Close();
    }
  }


  //
  // GetUniqueID
  // 从数据库中获取当前用户的 uniqueID 与应用程序的 uniqueID。
  //

  private int GetUniqueID(string username, bool isAuthenticated, bool ignoreAuthenticationType)
  {
    OdbcConnection conn = new OdbcConnection(connectionString);
    OdbcCommand cmd = new OdbcCommand("SELECT UniqueID FROM Profiles " +
            "WHERE Username = ? AND ApplicationName = ?", conn);
    cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username;
    cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = ApplicationName;

    if (!ignoreAuthenticationType)
    {
      cmd.CommandText += " AND IsAnonymous = ?";
      cmd.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = !isAuthenticated;
    }

    int uniqueID = 0;
    OdbcDataReader reader = null;

    try
    {
      conn.Open();

      reader = cmd.ExecuteReader(CommandBehavior.SingleRow);
      if (reader.HasRows)
        uniqueID = reader.GetInt32(0);
    }
    catch (OdbcException e)
    {
      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "GetUniqueID");
        throw new ProviderException(exceptionMessage);
      }
      else
      {
        throw e;
      }
    }
    finally
    {
      if (reader != null) { reader.Close(); }
      conn.Close();
    }

    return uniqueID;
  }


  //
  // CreateProfileForUser
  // 如果数据库中不存在当前用户,那么在调用私有方法 GetUniqueID 的时候将会创建一条用户记录。
  //

  private int CreateProfileForUser(string username, bool isAuthenticated)
  {
    // 检查有效的用户名称。

    if (username == null)
      throw new ArgumentNullException("User name cannot be null.");
    if (username.Length > 255)
      throw new ArgumentException("User name exceeds 255 characters.");
    if (username.IndexOf(",") > 0)
      throw new ArgumentException("User name cannot contain a comma (,).");


    OdbcConnection conn = new OdbcConnection(connectionString);
    OdbcCommand cmd = new OdbcCommand("INSERT INTO Profiles (Username, " +
            "ApplicationName, LastActivityDate, LastUpdatedDate, " +
            "IsAnonymous) Values(?, ?, ?, ?, ?)", conn);
    cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username;
    cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = ApplicationName;
    cmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = DateTime.Now;
    cmd.Parameters.Add("@LastUpdatedDate", OdbcType.VarChar).Value = DateTime.Now;
    cmd.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = !isAuthenticated;

    OdbcCommand cmd2 = new OdbcCommand("SELECT @@IDENTITY", conn);

    int uniqueID = 0;

    try
    {
      conn.Open();

      cmd.ExecuteNonQuery();

      uniqueID = (int)cmd2.ExecuteScalar();
    }
    catch (OdbcException e)
    {
      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "CreateProfileForUser");
        throw new ProviderException(exceptionMessage);
      }
      else
      {
        throw e;
      }
    }
    finally
    {
      conn.Close();
    }

    return uniqueID;
  }


  //
  // ProfileProvider.DeleteProfiles(ProfileInfoCollection)
  //

  public override int DeleteProfiles(ProfileInfoCollection profiles)
  {
    int deleteCount = 0;

    OdbcConnection  conn = new OdbcConnection(connectionString);
    OdbcTransaction tran = null;

    try
    {
      conn.Open();
      tran = conn.BeginTransaction();
    
      foreach (ProfileInfo p in profiles)
      {
        if (DeleteProfile(p.UserName, conn, tran))
          deleteCount++;
      }

      tran.Commit();
    }
    catch (Exception e)
    {
      try
      {
        tran.Rollback();
      }
      catch
      {
      }

      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "DeleteProfiles(ProfileInfoCollection)");
        throw new ProviderException(exceptionMessage);
      }
      else
      {
        throw e;
      }  
    }
    finally
    {
      conn.Close();
    }

    return deleteCount;
  }


  //
  // ProfileProvider.DeleteProfiles(string[])
  //

  public override int DeleteProfiles(string[] usernames)
  {
    int deleteCount = 0;

    OdbcConnection  conn = new OdbcConnection(connectionString);
    OdbcTransaction tran = null;

    try
    {
      conn.Open();
      tran = conn.BeginTransaction();
    
      foreach (string user in usernames)
      {
        if (DeleteProfile(user, conn, tran))
          deleteCount++;
      }

      tran.Commit();
    }
    catch (Exception e)
    {
      try
      {
        tran.Rollback();
      }
      catch
      {
      }

      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "DeleteProfiles(String())");
        throw new ProviderException(exceptionMessage);
      }
      else
      {
        throw e;
      }  
    }
    finally
    {
      conn.Close();
    }

    return deleteCount;
  }



  //
  // ProfileProvider.DeleteInactiveProfiles
  //

  public override int DeleteInactiveProfiles(
    ProfileAuthenticationOption authenticationOption,
    DateTime userInactiveSinceDate)
  {
    OdbcConnection conn = new OdbcConnection(connectionString);
    OdbcCommand cmd = new OdbcCommand("SELECT Username FROM Profiles " +
            "WHERE ApplicationName = ? AND " +
            " LastActivityDate <= ?", conn);
    cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = ApplicationName;
    cmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = userInactiveSinceDate;

    switch (authenticationOption)
    {
      case ProfileAuthenticationOption.Anonymous:
        cmd.CommandText += " AND IsAnonymous = ?";
        cmd.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = true;
        break;
      case ProfileAuthenticationOption.Authenticated:
        cmd.CommandText += " AND IsAnonymous = ?";
        cmd.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = false;
        break;
      default:
        break;
    }

    OdbcDataReader reader = null;
    string usernames = "";

    try
    {
      conn.Open();

      reader = cmd.ExecuteReader();

      while (reader.Read())
      {
        usernames += reader.GetString(0) + ",";
      }
    }
    catch (OdbcException e)
    {
      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "DeleteInactiveProfiles");
        throw new ProviderException(exceptionMessage);
      }
      else
      {
        throw e;
      }
    }
    finally
    {
      if (reader != null) { reader.Close(); }

      conn.Close();
    }

    if (usernames.Length > 0)
    {
      // 删除多余的逗号。
      usernames = usernames.Substring(0, usernames.Length - 1);
    }


    // 删除档案。

    return DeleteProfiles(usernames.Split(','));
  }


  //
  // DeleteProfile
  // 从数据库中删除被指定了用户名称的档案数据。
  //

  private bool DeleteProfile(string username, OdbcConnection conn, OdbcTransaction tran)
  {
    // 检查有效的用户名称。
    if (username == null)
      throw new ArgumentNullException("User name cannot be null.");
    if (username.Length > 255)
      throw new ArgumentException("User name exceeds 255 characters.");
    if (username.IndexOf(",") > 0)
      throw new ArgumentException("User name cannot contain a comma (,).");


    int uniqueID = GetUniqueID(username, false, true);

    OdbcCommand cmd1 = new OdbcCommand("DELETE * FROM ProfileData WHERE UniqueID = ?", conn);
    cmd1.Parameters.Add("@UniqueID", OdbcType.Int).Value = uniqueID;
    OdbcCommand cmd2 = new OdbcCommand("DELETE * FROM StockSymbols WHERE UniqueID = ?", conn);
    cmd2.Parameters.Add("@UniqueID", OdbcType.Int).Value = uniqueID;
    OdbcCommand cmd3 = new OdbcCommand("DELETE * FROM Profiles WHERE UniqueID = ?", conn);
    cmd3.Parameters.Add("@UniqueID", OdbcType.Int).Value = uniqueID;

    cmd1.Transaction = tran;
    cmd2.Transaction = tran;
    cmd3.Transaction = tran;

    int numDeleted = 0;

    // 异常将通过方法的调用而被捕获。
    numDeleted += cmd1.ExecuteNonQuery();
    numDeleted += cmd2.ExecuteNonQuery();
    numDeleted += cmd3.ExecuteNonQuery();

    if (numDeleted == 0)
      return false;
    else
      return true;
  }


  //
  // ProfileProvider.FindProfilesByUserName
  //

  public override ProfileInfoCollection FindProfilesByUserName(
    ProfileAuthenticationOption authenticationOption,
    string usernameToMatch,
    int pageIndex,
    int pageSize,
    out int totalRecords)
  {
    CheckParameters(pageIndex, pageSize);

    return GetProfileInfo(authenticationOption, usernameToMatch, 
        null, pageIndex, pageSize, out totalRecords);
  }


  //
  // ProfileProvider.FindInactiveProfilesByUserName
  //

  public override ProfileInfoCollection FindInactiveProfilesByUserName(
    ProfileAuthenticationOption authenticationOption,
    string usernameToMatch,
    DateTime userInactiveSinceDate,
    int pageIndex,
    int pageSize,
    out int totalRecords)
  {
    CheckParameters(pageIndex, pageSize);

    return GetProfileInfo(authenticationOption, usernameToMatch, userInactiveSinceDate, 
          pageIndex, pageSize, out totalRecords);
  }


  //
  // ProfileProvider.GetAllProfiles
  //

  public override ProfileInfoCollection GetAllProfiles(
    ProfileAuthenticationOption authenticationOption,
    int pageIndex,
    int pageSize,
    out int totalRecords)
  {
    CheckParameters(pageIndex, pageSize);

    return GetProfileInfo(authenticationOption, null, null, 
          pageIndex, pageSize, out totalRecords);
  }


  //
  // ProfileProvider.GetAllInactiveProfiles
  //

  public override ProfileInfoCollection GetAllInactiveProfiles(
    ProfileAuthenticationOption authenticationOption,
    DateTime userInactiveSinceDate,
    int pageIndex,
    int pageSize,
    out int totalRecords)
  {
    CheckParameters(pageIndex, pageSize);

    return GetProfileInfo(authenticationOption, null, userInactiveSinceDate, 
          pageIndex, pageSize, out totalRecords);
  }



  //
  // ProfileProvider.GetNumberOfInactiveProfiles
  //

  public override int GetNumberOfInactiveProfiles(
    ProfileAuthenticationOption authenticationOption,
    DateTime userInactiveSinceDate)
  {
    int inactiveProfiles = 0;

    ProfileInfoCollection profiles = 
      GetProfileInfo(authenticationOption, null, userInactiveSinceDate, 
          0, 0, out inactiveProfiles);

    return inactiveProfiles;
  }



  //
  // CheckParameters
  // 核实被输入的分页尺寸属性以及分页索引属性。
  // 并且通过 GetAllProfiles、GetAllInactiveProfiles、FindProfilesByUserName,以及 FindInactiveProfilesByUserName 而被调用。
  //

  private void CheckParameters(int pageIndex, int pageSize)
  {
    if (pageIndex < 0)
      throw new ArgumentException("Page index must 0 or greater.");
    if (pageSize < 1)
      throw new ArgumentException("Page size must be greater than 0.");
  }


  //
  // GetProfileInfo
  // 获取档案的总数并且从数据库的档案数据中创建一个 ProfileInfoCollection。
  // 并且通过 GetAllProfiles、GetAllInactiveProfiles、FindProfilesByUserName、FindInactiveProfilesByUserName,以及 GetNumberOfInactiveProfiles 而被调用。
  // 使用指定为 0 的 pageIndex 来获取结果总数。
  //

  private ProfileInfoCollection GetProfileInfo(
    ProfileAuthenticationOption authenticationOption,
    string usernameToMatch,
    object userInactiveSinceDate,
    int pageIndex,
    int pageSize,
    out int totalRecords)
  {
    OdbcConnection conn = new OdbcConnection(connectionString);


    // 获取总数的命令。

    OdbcCommand cmd = new OdbcCommand("SELECT COUNT(*) FROM Profiles WHERE ApplicationName = ? ", conn);
    cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = ApplicationName;


    // 获取档案数据的命令。

    OdbcCommand cmd2 = new OdbcCommand("SELECT Username, LastActivityDate, LastUpdatedDate, " +
            "IsAnonymous FROM Profiles WHERE ApplicationName = ? ", conn);
    cmd2.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = ApplicationName;


    // 如果要搜索的用户名称已经找到,那么就添加命令文字与参数。

    if (usernameToMatch != null)
    {
      cmd.CommandText += " AND Username LIKE ? ";
      cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = usernameToMatch;
      
      cmd2.CommandText += " AND Username LIKE ? ";
      cmd2.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = usernameToMatch;
    }


    // 如果要搜索静止的档案,就添加命令文字与参数。

    if (userInactiveSinceDate != null)
    {
      cmd.CommandText += " AND LastActivityDate <= ? ";
      cmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = (DateTime)userInactiveSinceDate;
      
      cmd2.CommandText += " AND LastActivityDate <= ? ";
      cmd2.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = (DateTime)userInactiveSinceDate;
    }


    // 如果要搜索匿名档案或者已识别的档案,就添加命令文字与参数。

    switch (authenticationOption)
    {
      case ProfileAuthenticationOption.Anonymous:
        cmd.CommandText += " AND IsAnonymous = ?";
        cmd.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = true;
        cmd2.CommandText += " AND IsAnonymous = ?";
        cmd2.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = true;
        break;
      case ProfileAuthenticationOption.Authenticated:
        cmd.CommandText += " AND IsAnonymous = ?";
        cmd.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = false;
        cmd2.CommandText += " AND IsAnonymous = ?";
        cmd2.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = false;
        break;
      default:
        break;
    }


    // 获取数据。

    OdbcDataReader reader = null;
    ProfileInfoCollection profiles = new ProfileInfoCollection();

    try
    {
      conn.Open();
      // 获取档案总数。
      totalRecords = (int)cmd.ExecuteScalar();  
      // 没有找到档案。
      if (totalRecords <= 0) { return profiles; }  
      // 只计算档案总数。
      if (pageSize == 0) { return profiles; }    

      reader = cmd2.ExecuteReader();

      int counter = 0;
      int startIndex = pageSize * (pageIndex - 1);
      int endIndex = startIndex + pageSize - 1;

      while (reader.Read())
      {
        if (counter >= startIndex)
        {
          ProfileInfo p = GetProfileInfoFromReader(reader);
          profiles.Add(p);
        }

        if (counter >= endIndex)
        {
          cmd.Cancel();
          break;
        }

        counter++;
      }

    }
    catch (OdbcException e)
    {
      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "GetProfileInfo");
        throw new ProviderException(exceptionMessage);
      }
      else
      {
        throw e;
      }
    }
    finally
    {
      if (reader != null) { reader.Close(); }

      conn.Close();
    }

    return profiles;
  }

  //
  // GetProfileInfoFromReader
  //  从 OdbcDataReader 中获取当前数据行并且使用这些值来组装一个 ProfileInfo 对象。
  //

  private ProfileInfo GetProfileInfoFromReader(OdbcDataReader reader)
  {
    string username = reader.GetString(0);

    DateTime lastActivityDate = new DateTime();
    if (reader.GetValue(1) != DBNull.Value)
      lastActivityDate = reader.GetDateTime(1);

    DateTime lastUpdatedDate = new DateTime();
    if (reader.GetValue(2) != DBNull.Value)
      lastUpdatedDate = reader.GetDateTime(2);

    bool isAnonymous = reader.GetBoolean(3);
      
    // ProfileInfo.Size 当前并没有被实现。
    ProfileInfo p = new ProfileInfo(username,
        isAnonymous, lastActivityDate, lastUpdatedDate,0);  

    return p;
  }


  //
  // WriteToEventLog
  // 一个把异常的详细内容写入到事件日志中的帮手功能。
  // 把异常写入事件日志作为一个安全标准来防止私有的数据库细节被返回给浏览器。
  // 如果一个方法并没有返回一个状态或者 Boolean 值来表示当前运作是否已经被完成还是已经失败,那么调用者同样会抛出一个常规的异常。
  //

  private void WriteToEventLog(Exception e, string action)
  {
    EventLog log = new EventLog();
    log.Source = eventSource;
    log.Log = eventLog;

    string message = "An exception occurred while communicating with the data source.\n\n";
    message += "Action: " + action + "\n\n";
    message += "Exception: " + e.ToString();

    log.WriteEntry(message);
  }
 }
}
posted on 2007-02-17 20:08  Laeb  阅读(464)  评论(0编辑  收藏  举报