背景 我已经使用 oracle 11g 配置了 asp.net 成员资格。IIS 和 Oracle 11g express 配置在同一台机器上。一切正常,直到我在 IIS6 上部署应用程序。我的应用程序停止识别数据库中已经存在的用户。寻找解决方案让我想到了这个解决方案。我在我的客户端计算机上更新了 Visual Studio 2010 中的 web.config,并将 applicationName 设置为与 IIS 上的匹配,并从数据库中删除了所有现有角色和用户记录。然后,我使用 WSAT 添加了一个管理员角色和用户,因为我还在另一个表“UserDetails”中为用户保留了一些附加信息,所以我在 oracle sql developer 中运行以下查询以添加管理员详细信息
insert into UserDetails (userid, usertypeid) VALUES('BC3008FFFAD24BB995C21E80A4870ABA', 1);
其中成功添加了记录。我为应用程序构建了部署包并将其部署到 IIS。浏览了 Web 应用程序,输入了用户凭据,但应用程序再次拒绝让我进入。
我在客户端上从 VS 运行应用程序(不做任何更改)。这是我的登录页面逻辑
登录.aspx:
Username: <br />
<asp:TextBox runat="server" ID="txtUserName"></asp:TextBox>
<br />
Password: <br />
<asp:TextBox runat="server" ID="txtPassword" TextMode="Password"></asp:TextBox>
<br />
<asp:Button runat="server" ID="btnLogin" Text="Login" onclick="btnLogin_Click"
style="height: 26px" />
登录.aspx.cs:
protected void btnLogin_Click(object sender, EventArgs e)
{
if (Membership.ValidateUser(username, password))
{
MembershipUser user = Membership.GetUser(username);
FormsAuthentication.SetAuthCookie(username, false);
Guid guserid = new Guid(user.ProviderUserKey.ToString());
string userid = Helpers.TranslateOraceEndianUserID(guserid);
int usertype = UserDetailsBAL.GetUserType(userid);
if (usertype == 1)
{
Response.Redirect("~/Dashboard.aspx");
}
else
{
Response.Redirect("Login.aspx?error");
}
}
else
{
Response.Redirect("Login.aspx?error");
}
}
在里面放断点if(Membership.ValidateUser ...
显示用户正在验证,实际问题是UserDetailsBAL.GetUserType(userid);
问题
步入 GetUserType
public static int GetUserType(string userid)
{
DataTable dt = new DataTable();
string q = string.Format("SELECT usertypeid from userdetails where userid='{0}'", userid);
dt = OraDAL.Select(q);
int usertype = -1;
if (dt.Rows.Count != 0)
{
DataRow dr = dt.Rows[0];
usertype = int.Parse(dr[0].ToString());
}
return usertype;
}
然后是 OraDAL.Select(q)
public static DataTable Select(string query)
{
DataTable dt = new DataTable();
OracleDataAdapter da = new OracleDataAdapter(query, OpenConn());
da.Fill(dt);
return dt;
}
private static string connString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.2)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=xe)));User Id=...;Password=...";
private static OracleConnection conn;
public static OracleConnection OpenConn()
{
if (conn==null)
{
conn = new OracleConnection(connString);
}
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
return conn;
}
我注意到查询没有填充 dt。对我来说一切都很好,我在 sql developer 中执行了相同的查询,它确实返回了一行
为了跟踪问题,可能需要检查哪些区域?
编辑
我跳过了GetUserType
forusertype= 1
以允许管理员登录该站点并创建 usertype=2 的其他用户。现在 usertype=2 的用户可以登录网站,GetUserType
代码运行顺利返回用户类型。我对 login.aspx.cs 中的代码进行了更改:
Guid guserid = new Guid(user.ProviderUserKey.ToString());
string userid = Helpers.TranslateOraceEndianUserID(guserid);
int usertype = UserDetailsBAL.GetUserType(userid);
if (usertype == 2)
{
Response.Redirect("~/Dashboard.aspx");
}
编辑2
现在我在数据库中有用户类型为 2 的用户,我再次更改了上面的代码以查看它是否再次为 usertype=1 提供错误
string userid = Helpers.TranslateOraceEndianUserID(guserid);
int usertype = UserProfilesBAL.GetUserType(userid);
if (usertype == 1)
{
Response.Redirect("~/Admin/Dashboard.aspx");
}
else if (usertype == 2)
{
Response.Redirect("~/Dashboard.aspx");
}
现在,当我为类型 1 的用户输入凭据时,让我更加沮丧的是,GetUserType 什么也不返回,当我使用用户类型 2 的凭据登录时,GetUserType 确实返回用户类型。
这两者之间的唯一区别是,对于 usertype=1,我使用 oracle sql developer 在 userdetails 表中手动输入了记录,对于 usertype=2,当我在后面使用 create user form 创建 usertype 2 的用户时,我的代码会添加记录结尾。
以下是我如何创建用户并进入 userdetails
MembershipCreateStatus createStatus;
MembershipUser newUser = Membership.CreateUser(txtUserName.Text, txtUserPass.Text, null, null, null, true, out createStatus);
if (newUser != null)
{
string userid = Helpers.TranslateOraceEndianUserID(new Guid(newUser.ProviderUserKey.ToString()));
UserDetailsBAL.AddUserDetails(userid, 2)
}
在 AddUserDetails 中,我只是在用户详细信息表中插入记录。
最糟糕的部分是OraDAL.Select
我之前在帖子中提到的方法中生成的查询。在 asp.net 中运行时的相同查询为 usertype 1 返回 null,当我将其从query
变量(如上面的屏幕截图所示)复制粘贴到 sql developer 时返回一行。