none
三层架构登录系统功能 RRS feed

  • 问题

  • 1.Model库类,新建一个userModel.代码如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace Model
    {
        public class userModel
        {
           string _name;
           string _pwd;

            public string UserName {
                get {
                    return this._name;
                }
                set {
                    this._name = value;
                }
            }

            public string UserPwd {
                get {
                    return this._pwd;
                }
                set {
                    this._pwd = value;
                }
            }

          

        }
    }

    2.配置文件的代码如下:

    </configSections>
        <appSettings>
            <add key="strconnection" value="server=(local);database=user_db;uid=sa;pwd=;"/>
        </appSettings>
        <connectionStrings/>

     

    3.BLL库类,创建一个userBll.代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Dll;
    using Model;

    namespace BLL
    {
        public class userBLL
        {
            Dll.userDll dl = new Dll.userDll();
            public bool login(Model.userModel user)
            {
              
                return dl.login(user);
               
            }
        }
    }

     

    4.DLL库类,创建一个userDll

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Configuration;
    using System.Data.SqlClient;
    using Model;


    namespace Dll
    {
        public class userDll
        {
            string conning = ConfigurationManager.AppSettings["strconnection"];

            public bool login(Model.userModel user) {
                SqlConnection con = new SqlConnection(conning);
                con.Open();
              
                string strcom = "select * from login_tb where userName='" +user.UserName+ "' and userPwd='" +user.UserPwd + "';";
                SqlCommand com = new SqlCommand(strcom, con);
                SqlDataReader sdr = com.ExecuteReader();
                if(sdr.Read())
                {
                    return true;
                }
                else {
                    return false;
                }            
            }

        }
    }

    5.数据库表login_tb

        userName varchar(20),

        userPwd varchar(20)

     

     

    出现的问题:不管是输入正确的账号和密码都提示成功!

    请各位高手帮帮忙,看下上面的代码,帮我解决这个问题,小弟不甚感激

     


    you are welcome
    2011年1月18日 6:39

答案

  • 读出成功也就是说你的login的return返回是 true 那么请检查你的  if(sdr.Read()) 也就是说他的返回值是成立的建议你在这里使用标准逻辑判断


    代码是缔造另一空间世界的艺术
    2011年1月18日 7:10
  • 您好,单看逻辑是否没什么问题,您可以在逻辑层上设个断点,单步跟踪一下,看看为什么错误的用户名和密码也会返回true。有必要的时候可以把strcom拷贝出来放到数据库上执行,看看结果。

    另,reader写的有问题,请参考:http://msdn.microsoft.com/zh-cn/library/9kcbe65k%28v=VS.80%29.aspx

    2011年1月18日 9:41
    版主
  • 正确的办法是:


    //检查用户是否存在
    string strcom = "select * from login_tb where userName='" +user.UserName+ "' ;";
    SqlCommand com = new SqlCommand(strcom, con);
    SqlDataReader sdr = com.ExecuteReader();
    //用户如果不在,返回false
    // 从结果中读取password字段
    //比较输入的password是否和存储的一致
    //返回结果


    family as water
    2011年1月18日 12:32
  • 这里不是比较了吗

      SqlConnection con = new SqlConnection(conning);
                con.Open(); 
                string strcom = "select * from login_tb where userName='" +user.UserName+ "' and userPwd='" +user.UserPwd + "';";
                SqlCommand com = new SqlCommand(strcom, con);
                SqlDataReader sdr = com.ExecuteReader();


    you are welcome
    2011年1月18日 12:45
  • public bool login(Model.userModel user) {
                SqlConnection con = new SqlConnection(conning);
                con.Open();
              
                string strcom = "select * from login_tb where userName='" +user.UserName+ "' and userPwd='" +user.UserPwd + "';";
                SqlCommand com = new SqlCommand(strcom, con);

                using(SqlDataReader sdr = com.ExecuteReader())

    {

                if(sdr.Read())
                {
                    return true;
                }
                else {
                    return false;
                }            

            }

    }

    这个问题主要还是通过调试来排错,另可以使用sql参数来防sql注入。这个问题就回答到这了。希望有帮助。

    2011年1月18日 13:40
    版主
  • 跟踪调试看看取得的值对不对

    Console.WriteLine(String.Format("{0}, {1}", _
                    sdr(0), sdr(1)))


    http://feiyun0112.cnblogs.com/
    2011年1月19日 1:06
    版主
  • ui代码问题吧

    if (bll.login(M)) //加个判断,登陆成功才输出 成功。


    family as water
    2011年1月19日 2:34
  • 嗯,UI代码的问题。两种方案:

    方案一修改UI的代码,如StoneZ所示。原来的代码根本没判断返回值,无论对错都执行成功。

    方案二修改数据库层代码,if(sdr.Read())
                {
                    throw new Exception("用户名或秘密错误!");
                }
                else {
                    return false;
                }    

     

    我上面改的代码,要问区别,请参考using的用法,http://msdn.microsoft.com/zh-cn/library/zhdeatwt%28VS.80%29.aspx 本例中是作为 语句 来使用。目的是为了关闭 SqlDataReader,释放资源。


    2011年1月19日 3:21
    版主
  • 从你反馈的情况看,说明数据库层的代码有问题,无论输入什么用户名和密码都是return false.

    刚才的代码应该改成:if(sdr.Read())
                {
                    return true;
                }
                else {
                   
    throw new Exception("用户名或秘密错误!");
                }    


    最重要的是要知道如何调试,并观测每个变量或方法的返回值!!!然后写相应的代码,这个需要您自己判断一下。该告诉您的都已经告诉您了。可以结贴了。如果您不知道如何调试,可以再发一个贴来问,以保证题目和答案一致。

    另,我回答了您很多问题,在适当的时候请结贴。这是精神奖励,结贴是一种美德,给答复者的精神奖励。毕竟大家都是无偿服务。同时也有助于后来者学习和查阅。

    如果觉得答案不是想要的,对有帮助的贴子最好也能投一票,这样大家会更积极的回答你的问题。

    2011年1月19日 6:17
    版主
  • 看了一下函数我明白了你的判断条件错了

    http://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqldatareader.read.aspx

    SqlDataReader.Read

    的判断  是在判断 你的这一行是否可读  也就是说 不论你的判断条件是对是错 他直接对数据库读取  只要可读 他就是  true

    这样你压根没有做到判断的效果。


    代码是缔造另一空间世界的艺术
    2011年1月19日 6:26
  • 正确的办法是:


    //检查用户是否存在
    string strcom = "select * from login_tb where userName='" +user.UserName+ "' ;";
    SqlCommand com = new SqlCommand(strcom, con);
    SqlDataReader sdr = com.ExecuteReader();
    //用户如果不在,返回false
    // 从结果中读取password字段
    //比较输入的password是否和存储的一致
    //返回结果


    family as water

    前面就写了这个伪代码

    你按照这个思路去编码实现就可以

    一个密码校验问题,没这么复杂哈


    family as water
    2011年1月19日 7:27
  • 有这么复杂么?

    最简单的方法 你返回结果到一个表

    然后判断表有几行,=1表示有用户,=0表示用户不存在(其他一般不会有的)

    =1的时候检查这个表的第一行的密码字段,和输入的密码匹配,如果有加密,加密后比较。

    相等 登录成功

    否则失败。

     


    family as water
    2011年1月19日 14:15
  • 有这么复杂么?

    最简单的方法 你返回结果到一个表

    然后判断表有几行,=1表示有用户,=0表示用户不存在(其他一般不会有的)

    =1的时候检查这个表的第一行的密码字段,和输入的密码匹配,如果有加密,加密后比较。

    相等 登录成功

    否则失败。

     


    family as water

    唉,是很晕菜。感觉这么说,估计楼主更晕,因为楼主现在连简单的int值都没搞定。

    hi 楼主,上面我强烈建议您调试 。(这也是我为什么把建议您调试的答案建议为答案。因为这里没有很难的技术问题,剩下的就是调试。)

    所谓调试,就是要设置断点,然后单步跟踪,观察返回值和变量值,剩下就是简单的逻辑判断。

    例如拿你的数据库层代码来说,

    int flag = (int)com.ExecuteScalar();
                if(flag>0)
                {
                    return true;
                }
                else {
                    return false;
                }
                con.Close();       
            }

    如果用户名和密码正确,那么就return true。因为flag>0。你就观查flag的值。如果无论用户名和密码是否正确都return false。那么就要看看sql是否在正确的Sql server环境中运行,就要检查数据库连接字符串或sql语句是否正确。等等。

    数据库层代码正确了,再观察界面层和业务逻辑层的代码,类似的步骤。最终就能判断出正确的逻辑。

    祝,早日成功!

    2011年1月19日 15:09
    版主

全部回复

  • 读出成功也就是说你的login的return返回是 true 那么请检查你的  if(sdr.Read()) 也就是说他的返回值是成立的建议你在这里使用标准逻辑判断


    代码是缔造另一空间世界的艺术
    2011年1月18日 7:10
  • 我也是这样子认为的.想不出方法来.你可以帮我修改下好吗?解决这个问题呢?十分感谢你
    you are welcome
    2011年1月18日 8:00
  • 您好,单看逻辑是否没什么问题,您可以在逻辑层上设个断点,单步跟踪一下,看看为什么错误的用户名和密码也会返回true。有必要的时候可以把strcom拷贝出来放到数据库上执行,看看结果。

    另,reader写的有问题,请参考:http://msdn.microsoft.com/zh-cn/library/9kcbe65k%28v=VS.80%29.aspx

    2011年1月18日 9:41
    版主
  • 那我应该怎么写这个代码呢?

    string conning = ConfigurationManager.AppSettings["strconnection"];

            public bool login(Model.userModel user) {
                SqlConnection con = new SqlConnection(conning);
                con.Open();
              
                string strcom = "select * from login_tb where userName='" +user.UserName+ "' and userPwd='" +user.UserPwd + "';";
                SqlCommand com = new SqlCommand(strcom, con);
                SqlDataReader sdr = com.ExecuteReader();
                if(sdr.Read())
                {
                    return true;
                }
                else {
                    return false;
                }            

            }


    you are welcome
    2011年1月18日 10:04
  • 正确的办法是:


    //检查用户是否存在
    string strcom = "select * from login_tb where userName='" +user.UserName+ "' ;";
    SqlCommand com = new SqlCommand(strcom, con);
    SqlDataReader sdr = com.ExecuteReader();
    //用户如果不在,返回false
    // 从结果中读取password字段
    //比较输入的password是否和存储的一致
    //返回结果


    family as water
    2011年1月18日 12:32
  • 这里不是比较了吗

      SqlConnection con = new SqlConnection(conning);
                con.Open(); 
                string strcom = "select * from login_tb where userName='" +user.UserName+ "' and userPwd='" +user.UserPwd + "';";
                SqlCommand com = new SqlCommand(strcom, con);
                SqlDataReader sdr = com.ExecuteReader();


    you are welcome
    2011年1月18日 12:45
  • public bool login(Model.userModel user) {
                SqlConnection con = new SqlConnection(conning);
                con.Open();
              
                string strcom = "select * from login_tb where userName='" +user.UserName+ "' and userPwd='" +user.UserPwd + "';";
                SqlCommand com = new SqlCommand(strcom, con);
                SqlDataReader sdr = com.ExecuteReader();
                if(sdr.Read())
                {
                    return true;
                }
                else {
                    return false;
                }            

            }
    you are welcome
    2011年1月18日 12:46
  • public bool login(Model.userModel user) {
                SqlConnection con = new SqlConnection(conning);
                con.Open();
              
                string strcom = "select * from login_tb where userName='" +user.UserName+ "' and userPwd='" +user.UserPwd + "';";
                SqlCommand com = new SqlCommand(strcom, con);

                using(SqlDataReader sdr = com.ExecuteReader())

    {

                if(sdr.Read())
                {
                    return true;
                }
                else {
                    return false;
                }            

            }

    }

    这个问题主要还是通过调试来排错,另可以使用sql参数来防sql注入。这个问题就回答到这了。希望有帮助。

    2011年1月18日 13:40
    版主
  • 如果是那样子的话 using(SqlDataReader sdr = com.ExecuteReader())

    {

                if(sdr.Read())
                {
                    return true;
                }
                else {
                    return false;
                }            

            }

     

    那跟这样子写    if(sdr.Read())
                {
                    return true;
                }
                else {
                    return false;
                }            

     

    有什么区别呢?


    you are welcome
    2011年1月18日 14:52
  • 那样子要怎么写才好呢?
    you are welcome
    2011年1月18日 14:53
  • 这个问题我琢磨了很久,希望你可以帮下忙,解决下


    you are welcome
    2011年1月19日 0:41
  • 跟踪调试看看取得的值对不对

    Console.WriteLine(String.Format("{0}, {1}", _
                    sdr(0), sdr(1)))


    http://feiyun0112.cnblogs.com/
    2011年1月19日 1:06
    版主
  • 加了这句话,调试了一下,还是提示成功!

     Console.WriteLine(String.Format("{0}, {1}", sdr[0], sdr[1]));

     

    后来我也修改了一下:代码如下

     if(sdr.Read())
                {
                    return false ;
                }
                else {
                    return true;
                }
                con.Close();       
            }

     

    还是提示:成功

     

    那是不是UI层有问题呢

    UI层的代码如下:

     protected void btnLogin_Click(object sender, EventArgs e)
        {
            Model.userModel M = new userModel();
            M.UserName = this.userName.ToString();
            M.UserPwd = this.userPwd.ToString(); ;
            BLL.userBLL bll = new userBLL();
            try
            {
                bll.login(M);
               
                Response.Write("成功");
            }
            catch {
                Response.Write("失败");
            }
           


    you are welcome
    2011年1月19日 1:51
  • 补充一下,UI层的代码如下

     

     protected void btnLogin_Click(object sender, EventArgs e)
        {
            Model.userModel M = new userModel();
            M.UserName = this.userName.ToString();
            M.UserPwd = this.userPwd.ToString(); ;
            BLL.userBLL bll = new userBLL();
            try
            {
                bll.login(M);
               
                Response.Write("成功");
            }
            catch {
                Response.Write("失败");
            }
           
           


    you are welcome
    2011年1月19日 1:53
  • ui代码问题吧

    if (bll.login(M)) //加个判断,登陆成功才输出 成功。


    family as water
    2011年1月19日 2:34
  • 嗯,UI代码的问题。两种方案:

    方案一修改UI的代码,如StoneZ所示。原来的代码根本没判断返回值,无论对错都执行成功。

    方案二修改数据库层代码,if(sdr.Read())
                {
                    throw new Exception("用户名或秘密错误!");
                }
                else {
                    return false;
                }    

     

    我上面改的代码,要问区别,请参考using的用法,http://msdn.microsoft.com/zh-cn/library/zhdeatwt%28VS.80%29.aspx 本例中是作为 语句 来使用。目的是为了关闭 SqlDataReader,释放资源。


    2011年1月19日 3:21
    版主
  •  1.对于第一方法我试过了,我加了一个if语句.不管是输入正确用户名和密码,都是提示,失败.

    protected void btnLogin_Click(object sender, EventArgs e)

        {
            Model.userModel M = new userModel();
            M.UserName = this.userName.ToString();
            M.UserPwd = this.userPwd.ToString(); ;
            BLL.userBLL bll = new userBLL();
            try
            {
                if (bll.login(M))
                {
                    Response.Write("成功");
                }
                else {
                    Response.Write("失败");
                  }
               
              
            }
            catch {
                Response.Write("系统程序出错");
            }   
        }

     

    2. 方案二修改数据库层代码,if(sdr.Read())
                {
                    throw new Exception("用户名或秘密错误!");
                }
                else {
                    return false;
                }    

    不修改方案一的代码,还是显示成功!


    you are welcome
    2011年1月19日 5:58
  • 从你反馈的情况看,说明数据库层的代码有问题,无论输入什么用户名和密码都是return false.

    刚才的代码应该改成:if(sdr.Read())
                {
                    return true;
                }
                else {
                   
    throw new Exception("用户名或秘密错误!");
                }    


    最重要的是要知道如何调试,并观测每个变量或方法的返回值!!!然后写相应的代码,这个需要您自己判断一下。该告诉您的都已经告诉您了。可以结贴了。如果您不知道如何调试,可以再发一个贴来问,以保证题目和答案一致。

    另,我回答了您很多问题,在适当的时候请结贴。这是精神奖励,结贴是一种美德,给答复者的精神奖励。毕竟大家都是无偿服务。同时也有助于后来者学习和查阅。

    如果觉得答案不是想要的,对有帮助的贴子最好也能投一票,这样大家会更积极的回答你的问题。

    2011年1月19日 6:17
    版主
  • 十分感谢您们
    you are welcome
    2011年1月19日 6:20
  • 突然间,我感到很兴奋  多谢各位的帮助

    if(sdr.Read())
                {
                    return true;
                }
                else {
                    return false;
                }

    这样判断永远都为true啊,试下这样

    while (rdr.Read())
    {
      if(!string.IsNullOrEmpty(rdr["ContactName"])
       {
           return true;
       }
    }


    you are welcome
    2011年1月19日 6:22
  • 看了一下函数我明白了你的判断条件错了

    http://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqldatareader.read.aspx

    SqlDataReader.Read

    的判断  是在判断 你的这一行是否可读  也就是说 不论你的判断条件是对是错 他直接对数据库读取  只要可读 他就是  true

    这样你压根没有做到判断的效果。


    代码是缔造另一空间世界的艺术
    2011年1月19日 6:26
  • 如果能读取到当前的字段和数据字段的文字一样就可以啊.但是也不是不行啊.

     

    如果你用string conning = ConfigurationManager.AppSettings["strconnection"];

                public bool login(Model.userModel user) {
                SqlConnection con = new SqlConnection(conning);
                con.Open();
              
                string strcom = "select count(*) from login_tb where userName='" +user.UserName+ "' and userPwd='" +user.UserPwd + "';";
                SqlCommand com = new SqlCommand(strcom, con);
                int flag = (int)com.ExecuteScalar();
                if(flag>0)
                {
                    return true;
                }
                else {
                    return false;
                }
                con.Close();       
            }

     

    这样子还是不行的.多谢


    you are welcome
    2011年1月19日 7:22
  • 正确的办法是:


    //检查用户是否存在
    string strcom = "select * from login_tb where userName='" +user.UserName+ "' ;";
    SqlCommand com = new SqlCommand(strcom, con);
    SqlDataReader sdr = com.ExecuteReader();
    //用户如果不在,返回false
    // 从结果中读取password字段
    //比较输入的password是否和存储的一致
    //返回结果


    family as water

    前面就写了这个伪代码

    你按照这个思路去编码实现就可以

    一个密码校验问题,没这么复杂哈


    family as water
    2011年1月19日 7:27
  • 多谢了,那我先试试看看
    you are welcome
    2011年1月19日 9:04
  • 折磨了很久还是想不出怎么方法来.
    you are welcome
    2011年1月19日 11:57
  • 有这么复杂么?

    最简单的方法 你返回结果到一个表

    然后判断表有几行,=1表示有用户,=0表示用户不存在(其他一般不会有的)

    =1的时候检查这个表的第一行的密码字段,和输入的密码匹配,如果有加密,加密后比较。

    相等 登录成功

    否则失败。

     


    family as water
    2011年1月19日 14:15
  • 有这么复杂么?

    最简单的方法 你返回结果到一个表

    然后判断表有几行,=1表示有用户,=0表示用户不存在(其他一般不会有的)

    =1的时候检查这个表的第一行的密码字段,和输入的密码匹配,如果有加密,加密后比较。

    相等 登录成功

    否则失败。

     


    family as water

    唉,是很晕菜。感觉这么说,估计楼主更晕,因为楼主现在连简单的int值都没搞定。

    hi 楼主,上面我强烈建议您调试 。(这也是我为什么把建议您调试的答案建议为答案。因为这里没有很难的技术问题,剩下的就是调试。)

    所谓调试,就是要设置断点,然后单步跟踪,观察返回值和变量值,剩下就是简单的逻辑判断。

    例如拿你的数据库层代码来说,

    int flag = (int)com.ExecuteScalar();
                if(flag>0)
                {
                    return true;
                }
                else {
                    return false;
                }
                con.Close();       
            }

    如果用户名和密码正确,那么就return true。因为flag>0。你就观查flag的值。如果无论用户名和密码是否正确都return false。那么就要看看sql是否在正确的Sql server环境中运行,就要检查数据库连接字符串或sql语句是否正确。等等。

    数据库层代码正确了,再观察界面层和业务逻辑层的代码,类似的步骤。最终就能判断出正确的逻辑。

    祝,早日成功!

    2011年1月19日 15:09
    版主
  • 多谢各位的帮助,谢谢
    you are welcome
    2011年1月20日 11:39