C# 从SQL Server数据库获取字符串值

C# 从SQL Server数据库获取字符串值,c#,asp.net,sql-server,login,C#,Asp.net,Sql Server,Login,我正在开发一个使用asp.net和SQL Server数据库的登录系统。我还没有添加安全部分,这只是一个用于测试的登录,所以这不是我目前关心的问题 我在数据库中有一个帐户表,其中有username、password和acc_type列。在登录期间,我想要的是,如果凭据正确,则需要检查帐户类型,并且根据帐户类型,用户将被重定向到其相应的页面 以下是我目前的代码: protected void LoginButton_Click(object sender, EventArgs e) { S

我正在开发一个使用asp.net和SQL Server数据库的登录系统。我还没有添加安全部分,这只是一个用于测试的登录,所以这不是我目前关心的问题

我在数据库中有一个帐户表,其中有username、password和acc_type列。在登录期间,我想要的是,如果凭据正确,则需要检查帐户类型,并且根据帐户类型,用户将被重定向到其相应的页面

以下是我目前的代码:

protected void LoginButton_Click(object sender, EventArgs e)
{
    SqlConnection con = new SqlConnection();
    con.ConnectionString = "Data Source=AA-PC\\SQLSERVER2012;Initial     Catalog=oncf;Integrated Security=True";

    con.Open();

    string query = "SELECT count(*) FROM Account where acc_username=@username and acc_password=@password";

    SqlCommand cmd = new SqlCommand(query, con);
    cmd.Parameters.AddWithValue("@username", TextBox1.Text); 
    cmd.Parameters.AddWithValue("@password", TextBox2.Text);

    int count= Convert.ToInt32(cmd.ExecuteScalar());

    if(count==1) 
    {
        string query2 = " SELECT acc_type FROM Account where acc_username=@username and acc_password=@password";

        SqlCommand cmd2 = new SqlCommand(query2, con);
        cmd2.Parameters.AddWithValue("@username", TextBox1.Text);
        cmd2.Parameters.AddWithValue("@password", TextBox2.Text);

        DataTable dt = new DataTable();

        SqlDataAdapter da = new SqlDataAdapter(cmd2);
        da.Fill(dt);

        string userType = dt.Rows[0]["acc_type"].ToString();

        if (userType == "LandAsset")
        {
            Response.Redirect("ManageLines.aspx");
        }
        else
        {
            Response.Redirect("MainAdmin.aspx");
        }
    }
    else {
        Label2.Visible = true;
    }

    con.Close();
}
我有一个外部的if-else条件来检查凭证是否正确,如果是这样,那么我们就有逻辑来检查它是哪种类型的帐户

但是,每当我尝试登录时,无论用户是什么类型,我总是被重定向到同一MainAdmin.aspx页面


有人能帮忙吗?

你这样做太复杂了

基本上,如果您的用户及其密码确实存在于表中,您的第二个查询将返回他的帐户类型-反之亦然,如果该用户不存在,或者密码错误,则不会返回任何值或NULL-只需检查一下即可。另外:由于只返回一行、一列,因此可以使用更简单的.ExecuteScalar,而不是填充数据表,然后在其中搜索以查找所需的信息

因此,基本上,这段代码也应该这样做:

protected void LoginButton_Click(object sender, EventArgs e)
{
    // set up your connection string and query as strings
    string connectionString = "Data Source=AA-PC\\SQLSERVER2012;Initial Catalog=oncf;Integrated Security=True";
    string query = "SELECT acc_type FROM dbo.Account WHERE acc_username = @username and acc_password = @password;"

    // set up your connection and command in "using" blocks
    using (SqlConnection con = new SqlConnection(connectionString))
    using (SqlCommand cmd2 = new SqlCommand(query, con))
    {
        // define and set parameters
        cmd2.Parameters.Add("@username", SqlDbType.VarChar, 100).Value = TextBox1.Text);
        cmd2.Parameters.Add("@password", SqlDbType.VarChar, 100).Value = TextBox2.Text);

        // open connection, execute command, close connection
        con.Open();

        object result = cmd.ExecuteScalar();

        con.Close();

        // if nothing was returned -> user/password are not valid
        if (result == null) {
            Label2.Visible = true;
        }
        else  
        {
            string accountType = result.ToString();

            if (accountType == "LandAsset")
            {
                 Response.Redirect("ManageLines.aspx");
            }
            else
            {
                 Response.Redirect("MainAdmin.aspx");
            }
        }
    }
}

你这样做太复杂了

基本上,如果您的用户及其密码确实存在于表中,您的第二个查询将返回他的帐户类型-反之亦然,如果该用户不存在,或者密码错误,则不会返回任何值或NULL-只需检查一下即可。另外:由于只返回一行、一列,因此可以使用更简单的.ExecuteScalar,而不是填充数据表,然后在其中搜索以查找所需的信息

因此,基本上,这段代码也应该这样做:

protected void LoginButton_Click(object sender, EventArgs e)
{
    // set up your connection string and query as strings
    string connectionString = "Data Source=AA-PC\\SQLSERVER2012;Initial Catalog=oncf;Integrated Security=True";
    string query = "SELECT acc_type FROM dbo.Account WHERE acc_username = @username and acc_password = @password;"

    // set up your connection and command in "using" blocks
    using (SqlConnection con = new SqlConnection(connectionString))
    using (SqlCommand cmd2 = new SqlCommand(query, con))
    {
        // define and set parameters
        cmd2.Parameters.Add("@username", SqlDbType.VarChar, 100).Value = TextBox1.Text);
        cmd2.Parameters.Add("@password", SqlDbType.VarChar, 100).Value = TextBox2.Text);

        // open connection, execute command, close connection
        con.Open();

        object result = cmd.ExecuteScalar();

        con.Close();

        // if nothing was returned -> user/password are not valid
        if (result == null) {
            Label2.Visible = true;
        }
        else  
        {
            string accountType = result.ToString();

            if (accountType == "LandAsset")
            {
                 Response.Redirect("ManageLines.aspx");
            }
            else
            {
                 Response.Redirect("MainAdmin.aspx");
            }
        }
    }
}

为了回答您的第一个问题,如果安全是一个问题,我不建议您这样做

我看到的这个系统的主要缺陷是,所有经过身份验证的用户都可以轻松地在他们之间共享链接,或者在他们的浏览器中键入ManageLines.aspx,并访问应用程序的未授权区域


要回答您的第二个问题,但像这样登录最常用的方式是什么?我可以推荐asp.net角色管理吗

我成功地使用了它,它工作得很好。与ASP的许多领域一样,大部分工作已经为您完成

此链接将为您提供一般概述:

使用aspnet_regsql.exe实用程序在SQL server中配置所有必要的表和存储过程:

然后在SQL中,在应用程序表中创建一条记录,即该应用程序的角色,将成员添加到角色中。这一切都是在SQL中通过regsql提供的存储过程完成的

接下来,修改web.config以包含角色提供程序。然后,可以使用存储过程将用户添加到角色

<roleManager 
     defaultProvider="SQL"
     enabled="true" 
     cacheRolesInCookie="true" >
</roleManager>
然后,您可以创建名为LANDASSET的子文件夹和另一个名为ADMIN的子文件夹,并将相应的文件粘贴在其中,然后在web.config中添加:

然后在方法中添加:

    string username = TextBox1.Text;

        if (Roles.GetRolesForUser(username) == "LANDASSET")
        {
             Response.Redirect("ManageLines.aspx");
        }
        else
        {
             Response.Redirect("MainAdmin.aspx");
        }
这可能需要一些额外的阅读来完成,但这些是基础


希望这有帮助

回答您的第一个问题,如果安全是一个问题,我不建议您这样做

我看到的这个系统的主要缺陷是,所有经过身份验证的用户都可以轻松地在他们之间共享链接,或者在他们的浏览器中键入ManageLines.aspx,并访问应用程序的未授权区域


要回答您的第二个问题,但像这样登录最常用的方式是什么?我可以推荐asp.net角色管理吗

我成功地使用了它,它工作得很好。与ASP的许多领域一样,大部分工作已经为您完成

此链接将为您提供一般概述:

使用aspnet_regsql.exe实用程序在SQL server中配置所有必要的表和存储过程:

然后在SQL中,在应用程序表中创建一条记录,即该应用程序的角色,将成员添加到角色中。这一切都是在SQL中通过regsql提供的存储过程完成的

接下来,修改web.config以包含角色提供程序。然后,可以使用存储过程将用户添加到角色

<roleManager 
     defaultProvider="SQL"
     enabled="true" 
     cacheRolesInCookie="true" >
</roleManager>
然后,您可以创建名为LANDASSET的子文件夹和另一个名为ADMIN的子文件夹,并将相应的文件粘贴在其中,然后在web.config中添加:

然后在方法中添加:

    string username = TextBox1.Text;

        if (Roles.GetRolesForUser(username) == "LANDASSET")
        {
             Response.Redirect("ManageLines.aspx");
        }
        else
        {
             Response.Redirect("MainAdmin.aspx");
        }
这可能需要一些额外的阅读来完成,但这些是基础


希望这有帮助

不要将密码存储在数据库中,而是对它们进行加密和散列。是的,我已经准备好了一个函数,但我没有将其包含在这里。这只是一个用于测试的登录部分。通常,如果您开始使用DebuggerYou Debug并查看字符串UserType是什么,这些问题很容易解决

当它越过那条线时,你会收到什么?在我看来,你永远无法收回土地资产。。。。这就是你被重定向的原因。我该怎么做?我认为代码很好,没有什么看起来不对劲的地方,它通常应该得到Landasset。不要将密码存储在数据库中,而是对它们进行salt和散列。是的,我已经准备好了一个函数,但我不在这里包括它。这只是一个用于测试的登录部分。通常,如果您开始使用DebuggerYou Debug并查看当它超过该行时实际接收到的字符串UserType,这些问题很容易解决?在我看来,你永远无法收回土地资产。。。。这就是你被重定向的原因。我该怎么做?我认为代码是好的,没有什么看起来不对劲的,它通常应该得到LandAssetYes,我将更改datatable并使用executeScalar。但是为什么在这段代码中只使用一个命令呢?您还同时使用了cmd和cmd2。@simon:我只使用cmd2比只使用您拥有的更容易-我的代码只使用一个查询来实现您想要实现的目标。但是,像这样登录最常用的方式是什么?我遇到的问题是,无论用户的类型如何,我总是被重定向到同一个页面is@simon:然后您需要调试代码,查看从数据库表返回的值,以及它在代码中的使用方式。。。。例如,从数据库返回的值中可能有一个尾随空格,因此它将是LandAsset。表中的列是什么数据类型??如果它是一个字符20或类似的东西,那么在我的示例中,它将被填充为定义长度为20个字符的空格-一定有什么地方出错了-但这与这里的查询无关!非常感谢,成功了!问题确实是数据库中的列大小。LandAsset包含9个字符,而我将该列的大小设置为10,因此,即使来自DB的字符串gotte是LandAsset,它也与我没有比较的字符串不同。是的,我将更改datatable并使用executeScalar。但是为什么在这段代码中只使用一个命令呢?您还同时使用了cmd和cmd2。@simon:我只使用cmd2比只使用您拥有的更容易-我的代码只使用一个查询来实现您想要实现的目标。但是,像这样登录最常用的方式是什么?我遇到的问题是,无论用户的类型如何,我总是被重定向到同一个页面is@simon:然后您需要调试代码,查看从数据库表返回的值,以及它在代码中的使用方式。。。。例如,从数据库返回的值中可能有一个尾随空格,因此它将是LandAsset。表中的列是什么数据类型??如果它是一个字符20或类似的东西,那么在我的示例中,它将被填充为定义长度为20个字符的空格-一定有什么地方出错了-但这与这里的查询无关!非常感谢,成功了!问题确实是数据库中的列大小。LandAsset包含9个字符,而我将该列的大小设置为10,因此,即使DB中的gotte字符串是LandAsset,它也与我没有比较的字符串不同。感谢您的帮助!谢谢你的帮助!