显示登录用户的名称
Showing the name of logged user
我有一个具体情况。我的主页如下所示:
我需要做的是在登录时显示用户名,但是对于我的作业,我必须 class User
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Windows.Forms;
using System.Data;
namespace WebApplication5
{
public class User
{
public string Username
{
get;
set;
}
public string Password
{
get;
set;
}
public void getAll()
{
DataSet1 dataSet1 = new DataSet1();
DataSet1TableAdapters.usersTableAdapter usersTableAdapters = new DataSet1TableAdapters.usersTableAdapter();
DataSet1.usersDataTable usersDataTable = new DataSet1.usersDataTable();
usersDataTable = usersTableAdapters.GetData();
return;
}
public void checkUser()
{
DataSet1 dataSet1 = new DataSet1();
SqlConnection con = new SqlConnection(@"data source=JOVAN-PC;database=aukcija_jovan_gajic;integrated security=true;");
con.Open();
SqlCommand cmd = new SqlCommand("select * from users where name='" + Username + "'and password='" + Password + "'", con);
cmd.CommandType = CommandType.Text;
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
DataSet dataSet = new DataSet();
adapter.Fill(dataSet);
if (dataSet.Tables[0].Rows.Count > 0)
{
string user = dataSet.Tables[0].Rows[0]["Name"].ToString();
}
else
{
Environment.Exit(Environment.ExitCode);
}
con.Close();
}
}
}
然后将其连接到 Login
页面:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Windows.Forms;
namespace WebApplication5
{
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
TextBox1.Focus();
}
protected void Button1_Click(object sender, EventArgs e)
{
if (TextBox1.Text.Length == 0)
{
MessageBox.Show("Please enter your username.");
TextBox1.Focus();
}
else if (TextBox2.Text.Length == 0)
{
MessageBox.Show("Please enter your password.");
TextBox2.Focus();
}
else
{
string username = TextBox1.Text;
string password = TextBox2.Text;
User u = new User();
u.Username = username;
u.Password = password;
u.checkUser();
MessageBox.Show("Log in succesfull!");
Response.Redirect("http://localhost:11424/Home.aspx");
}
}
}
现在,我想我应该在 string user = dataSet.Tables[0].Rows[0]["Name"].ToString();
之后在 User
class 中写一些东西,但我不知道。
你的问题有太多的错误,很难知道从哪里开始。但让我们分解一下。
你有 using System.Windows.Forms;
。在 ASP.NET 应用程序中,您实际上永远不需要 Windows Forms 命名空间。摆脱那条线。
你有一个功能User.getAll()
。在成员名称前加上动词 "get" 通常表示它将 return 某事。但是您已将该方法声明为无效。它应该是 return usersDataTable
对象,签名应该是 public DataTable GetAllUsersDataTable()
.
说到这里,您的示例从未显示 User.getAll()
被调用。所以不要将它包含在你的问题中。包含它违反了提供 Minimal, Complete, Verifiable example.
的 "minimal" 部分
您的 User.checkUser
方法的名称暗示它只是检查用户是否有效。因此,它不应该也让用户登录。这就是所谓的单一职责原则。所以最简单的做法是将签名更改为 public bool IsLoginValid()
并让方法 return 一个布尔值,指示登录尝试是否成功。
User.checkUser
也应该是一个静态方法,而不是利用 username/password 的属性,它应该接受它们作为参数。
在 User.checkUser
函数中,您误用了 SqlConnection。 SqlConnection
实现了 IDisposable
接口,因此您需要确保它得到正确处理,以便连接不会保持打开状态。稍后在代码中简单地调用 SqlConnection.Close
是不够的,因为您需要确保到达该方法。如果您使用 using
语句,它将确保为您调用关闭方法。
using(var connection = new SqlConnection(arguments etc))
{
//Use the connection in here
}
您的数据库以明文形式存储密码。在学术环境中这很好,因为不会泄露真人的密码。但这是一个非常糟糕的习惯。密码应该是单向散列和加盐的。这使得坏人很难取回用户的真实密码。这可能是一个学术环境,但安全是您 必须 认真对待的事情,如果您在现实世界中继续这样做的话。
另一个巨大的安全问题,在 User.checkUser
中,您正在将字符串连接到数据库查询中。这让你极易受到 SQL Injection attack. Programmers that get in this bad habit are one the reasons this attack is so prevalent in the real world. The defense against that in .NET is to parameterize your database commands.
的攻击
在 User.checkUser
函数中,如果数据库查找失败,则调用 Environment.Exit(Environment.ExitCode);
。我不确定 ASP.NET 中的效果是什么,但我猜它会使服务器崩溃。不好。相反,就像我之前提到的那样,该方法应该 return 一个布尔值,指示登录是否成功。那将是 return false;
.
的好地方
现在进入您的登录页面。同样,您是 using System.Windows.Forms
。不要那样做。您正在使用的 MessageBox
class 会在服务器 上打开一个消息框 。虽然当客户端和服务器相同时这很好,但在本地测试之外几乎从来没有这种情况。现在不要养成坏习惯。学习使用JavaScript在客户端弹出对话框。用这样的东西替换你所有的 MessageBox
调用:
ClientScriptManager.RegisterStartupScript(this.GetType(),
"unique key identifying the script",
"alert('Message here!');",
true);
就像我之前说的,User.checkUser
应该 return 一个布尔值,表示登录成功与否。所以现在我们应该在我们的登录页面中处理它。将 u.checkUser();
更改为如下内容:
bool successfulLogin = u.checkUser();
if(successfulLogin)
{
Response.Redirect("~/Home.aspx"); //notice we do root relative, so that if the host changes we don't have to change the string
}
else
{
ClientScript.RegisterStartupScript(this.GetType(),
"loginFailure",
"alert('Invalid login attempt!');",
true);
}
现在直接回答你的问题。您需要一种将会话与正确用户相关联的方法。最好的存储位置是 Session
变量。
Session["Username"] = username;
毕竟,我已经按照我给出的大部分建议创建了您的代码的清理版本。从用户 class.
开始
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Data;
namespace WebApplication5
{
public class UserManager
{
public static bool IsLoginValid(string username, string password)
{
var dataSet1 = new DataSet1();
var cmd = new SqlCommand("select * from users where name=@Username and password=@Password");
cmd.Parameters.AddWithValue("Username", username);
cmd.Parameters.AddWithValue("Password", password);
var adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
var dataSet = new DataSet();
using(var connection = new SqlConnection("data source=JOVAN-PC;database=aukcija_jovan_gajic;integrated security=true;"))
{
cmd.Connection = connection;
connection.Open();
adapter.Fill(dataSet);
}
if (dataSet.Tables[0].Rows.Count > 0)
{
return true;
}
else
{
return false;
}
}
}
}
以及登录页面:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication5
{
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
UsernameTB.Focus();
}
}
protected void LoginBtn_Click(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(UsernameTB.Text))
{
AddStartupAlert("MissingUsername", "Please enter your username.");
UsernameTB.Focus();
}
else if (String.IsNullOrEmpty(PasswordTB.Text))
{
AddStartupAlert("MissingPassword", "Please enter your password.");
PasswordTB.Focus();
}
else
{
var valid = UserManager.IsLoginValid(UsernameTB.Text, PasswordTB.Text);
if(valid)
{
Session["Username"] = UsernameTB.Text;
Response.Redirect("~/Home.aspx?message=" + UrlEncode("Login Successful!"));
}
else
{
AddStartupAlert("Login attempt unsuccessful.");
}
}
}
private void AddStartupAlert(string key, string message)
{
ClientScriptManager.RegisterStartupScript(this.GetType(),
key,
"alert('" + message + "');",
true);
}
}
}
在您的 ~/Home.aspx
上,您应该从会话变量中检索用户名,并将其显示给用户。假设您重复使用 AddStartupAlert
(可能想将其移至助手 class),您可以这样做:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
var username = Session["Username"];
AddStartupAlert("WelcomeMessage", String.Format("Welcome to the site, {0}", username));
}
}
我有一个具体情况。我的主页如下所示:
我需要做的是在登录时显示用户名,但是对于我的作业,我必须 class User
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Windows.Forms;
using System.Data;
namespace WebApplication5
{
public class User
{
public string Username
{
get;
set;
}
public string Password
{
get;
set;
}
public void getAll()
{
DataSet1 dataSet1 = new DataSet1();
DataSet1TableAdapters.usersTableAdapter usersTableAdapters = new DataSet1TableAdapters.usersTableAdapter();
DataSet1.usersDataTable usersDataTable = new DataSet1.usersDataTable();
usersDataTable = usersTableAdapters.GetData();
return;
}
public void checkUser()
{
DataSet1 dataSet1 = new DataSet1();
SqlConnection con = new SqlConnection(@"data source=JOVAN-PC;database=aukcija_jovan_gajic;integrated security=true;");
con.Open();
SqlCommand cmd = new SqlCommand("select * from users where name='" + Username + "'and password='" + Password + "'", con);
cmd.CommandType = CommandType.Text;
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
DataSet dataSet = new DataSet();
adapter.Fill(dataSet);
if (dataSet.Tables[0].Rows.Count > 0)
{
string user = dataSet.Tables[0].Rows[0]["Name"].ToString();
}
else
{
Environment.Exit(Environment.ExitCode);
}
con.Close();
}
}
}
然后将其连接到 Login
页面:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Windows.Forms;
namespace WebApplication5
{
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
TextBox1.Focus();
}
protected void Button1_Click(object sender, EventArgs e)
{
if (TextBox1.Text.Length == 0)
{
MessageBox.Show("Please enter your username.");
TextBox1.Focus();
}
else if (TextBox2.Text.Length == 0)
{
MessageBox.Show("Please enter your password.");
TextBox2.Focus();
}
else
{
string username = TextBox1.Text;
string password = TextBox2.Text;
User u = new User();
u.Username = username;
u.Password = password;
u.checkUser();
MessageBox.Show("Log in succesfull!");
Response.Redirect("http://localhost:11424/Home.aspx");
}
}
}
现在,我想我应该在 string user = dataSet.Tables[0].Rows[0]["Name"].ToString();
之后在 User
class 中写一些东西,但我不知道。
你的问题有太多的错误,很难知道从哪里开始。但让我们分解一下。
你有 using System.Windows.Forms;
。在 ASP.NET 应用程序中,您实际上永远不需要 Windows Forms 命名空间。摆脱那条线。
你有一个功能User.getAll()
。在成员名称前加上动词 "get" 通常表示它将 return 某事。但是您已将该方法声明为无效。它应该是 return usersDataTable
对象,签名应该是 public DataTable GetAllUsersDataTable()
.
说到这里,您的示例从未显示 User.getAll()
被调用。所以不要将它包含在你的问题中。包含它违反了提供 Minimal, Complete, Verifiable example.
您的 User.checkUser
方法的名称暗示它只是检查用户是否有效。因此,它不应该也让用户登录。这就是所谓的单一职责原则。所以最简单的做法是将签名更改为 public bool IsLoginValid()
并让方法 return 一个布尔值,指示登录尝试是否成功。
User.checkUser
也应该是一个静态方法,而不是利用 username/password 的属性,它应该接受它们作为参数。
在 User.checkUser
函数中,您误用了 SqlConnection。 SqlConnection
实现了 IDisposable
接口,因此您需要确保它得到正确处理,以便连接不会保持打开状态。稍后在代码中简单地调用 SqlConnection.Close
是不够的,因为您需要确保到达该方法。如果您使用 using
语句,它将确保为您调用关闭方法。
using(var connection = new SqlConnection(arguments etc))
{
//Use the connection in here
}
您的数据库以明文形式存储密码。在学术环境中这很好,因为不会泄露真人的密码。但这是一个非常糟糕的习惯。密码应该是单向散列和加盐的。这使得坏人很难取回用户的真实密码。这可能是一个学术环境,但安全是您 必须 认真对待的事情,如果您在现实世界中继续这样做的话。
另一个巨大的安全问题,在 User.checkUser
中,您正在将字符串连接到数据库查询中。这让你极易受到 SQL Injection attack. Programmers that get in this bad habit are one the reasons this attack is so prevalent in the real world. The defense against that in .NET is to parameterize your database commands.
在 User.checkUser
函数中,如果数据库查找失败,则调用 Environment.Exit(Environment.ExitCode);
。我不确定 ASP.NET 中的效果是什么,但我猜它会使服务器崩溃。不好。相反,就像我之前提到的那样,该方法应该 return 一个布尔值,指示登录是否成功。那将是 return false;
.
现在进入您的登录页面。同样,您是 using System.Windows.Forms
。不要那样做。您正在使用的 MessageBox
class 会在服务器 上打开一个消息框 。虽然当客户端和服务器相同时这很好,但在本地测试之外几乎从来没有这种情况。现在不要养成坏习惯。学习使用JavaScript在客户端弹出对话框。用这样的东西替换你所有的 MessageBox
调用:
ClientScriptManager.RegisterStartupScript(this.GetType(),
"unique key identifying the script",
"alert('Message here!');",
true);
就像我之前说的,User.checkUser
应该 return 一个布尔值,表示登录成功与否。所以现在我们应该在我们的登录页面中处理它。将 u.checkUser();
更改为如下内容:
bool successfulLogin = u.checkUser();
if(successfulLogin)
{
Response.Redirect("~/Home.aspx"); //notice we do root relative, so that if the host changes we don't have to change the string
}
else
{
ClientScript.RegisterStartupScript(this.GetType(),
"loginFailure",
"alert('Invalid login attempt!');",
true);
}
现在直接回答你的问题。您需要一种将会话与正确用户相关联的方法。最好的存储位置是 Session
变量。
Session["Username"] = username;
毕竟,我已经按照我给出的大部分建议创建了您的代码的清理版本。从用户 class.
开始using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Data;
namespace WebApplication5
{
public class UserManager
{
public static bool IsLoginValid(string username, string password)
{
var dataSet1 = new DataSet1();
var cmd = new SqlCommand("select * from users where name=@Username and password=@Password");
cmd.Parameters.AddWithValue("Username", username);
cmd.Parameters.AddWithValue("Password", password);
var adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
var dataSet = new DataSet();
using(var connection = new SqlConnection("data source=JOVAN-PC;database=aukcija_jovan_gajic;integrated security=true;"))
{
cmd.Connection = connection;
connection.Open();
adapter.Fill(dataSet);
}
if (dataSet.Tables[0].Rows.Count > 0)
{
return true;
}
else
{
return false;
}
}
}
}
以及登录页面:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication5
{
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
UsernameTB.Focus();
}
}
protected void LoginBtn_Click(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(UsernameTB.Text))
{
AddStartupAlert("MissingUsername", "Please enter your username.");
UsernameTB.Focus();
}
else if (String.IsNullOrEmpty(PasswordTB.Text))
{
AddStartupAlert("MissingPassword", "Please enter your password.");
PasswordTB.Focus();
}
else
{
var valid = UserManager.IsLoginValid(UsernameTB.Text, PasswordTB.Text);
if(valid)
{
Session["Username"] = UsernameTB.Text;
Response.Redirect("~/Home.aspx?message=" + UrlEncode("Login Successful!"));
}
else
{
AddStartupAlert("Login attempt unsuccessful.");
}
}
}
private void AddStartupAlert(string key, string message)
{
ClientScriptManager.RegisterStartupScript(this.GetType(),
key,
"alert('" + message + "');",
true);
}
}
}
在您的 ~/Home.aspx
上,您应该从会话变量中检索用户名,并将其显示给用户。假设您重复使用 AddStartupAlert
(可能想将其移至助手 class),您可以这样做:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
var username = Session["Username"];
AddStartupAlert("WelcomeMessage", String.Format("Welcome to the site, {0}", username));
}
}