• MVC中关于Membership类跟数据库的问题


    Membership它们用的是ASPNETDB这个数据库,但我们可以使用我们自定义的数据库,然而除非我们自定义的数据库有着跟这个ASPNETDB一样的模式,否则ASP.NET提供的默认的SqlMembershipProvider将无法被使用。
    也就是说,如果我们还要用ASP.NET提供的SqlMembershipProvider,我们就必须ASPNETDB这个数据库文件或是它的拷贝。明显,这不是我们要的。
    为此,若我们使用了自定义的数据库(而非ASPNETDB的拷贝),那么我们就必须写自己的MembershipProvider。步骤如下。
    1,定义好自己的数据库,此例中为TestDB01。在我的TestDB01下有一表UserInfo,其下有字段UserID,UserName,UserAge。
    2,写自己的MembershipProvider,这个类继承自命名空间System.Web.Security下的MembershipProvider类。这一步很简单,创建一个空类,举例名为MyMembershipProvider,技术上说我们可以把它放在应用程序的任何位置,但我把它放在了项目下的一个名为Infrastructure(自己加的)的文件夹下。
    这一步的初始代码形式大概如下:
    namespace MvcApplication5.Infrastructure
    {
     public class MyMembershipProvider : System.Web.Security.MembershipProvider/*我把命名空间写这了*/
     {
     }

    当然,它是空的,它需要我们往里面再加一些东西。。
    此时我们把光标放到“System.Web.Security.MembershipProvider”上并右击鼠标,在弹出的下拉框上我们可以看到“实现虚拟类”(我用的是英文版,我不知道有没有翻译对,原内容是“Emplement Abstract Class”),单击这一选项我们的MyMembershipProvider这个类顿时多了N多个方法,此时它的形式如下(我只截了一部分):
        public class MyMembershipProvider : System.Web.Security.MembershipProvider
        {
            public override string ApplicationName
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }

            public override bool ChangePassword(string username, string oldPassword, string newPassword)
            {
                throw new NotImplementedException();
            }
     
     //...

     public override bool ValidateUser(string username, string password)
            {
                throw new NotImplementedException();
            }
        }
    可以看到,这些方法什么都没做,除了抛出一个NotImplementedException异常。当然,这不是我们希望的,这些方法需要我们自己去填充,要不然怎么叫“自定义”呢。。
    呃,现在先把我们先不管别的方法,只看最后的这个ValidateUser()方法。顾名思义,这个正是我们用来验证用户的方法,对其修改如下:
            public override bool ValidateUser(string username, string password)
            {
                SqlConnection sqlconn = new SqlConnection("Data Source=HCNG-PC;Initial Catalog=TestDB01;Integrated Security=True");/*用你的数据源名替换HCNG-PC,且TestDB01是我用来测试的自定义数据库*/
                SqlCommand sqlcmd = new SqlCommand("select UserID, UserName from [UserInfo] where UserName = @userName and UserAge = @userAge", sqlconn);/*这些相信你都明白,若有不明,请补充问题*/

                try
                {
                    sqlconn.Open();

                    sqlcmd.Parameters.Add(new SqlParameter("@userName", SqlDbType.NVarChar, 50));
                    sqlcmd.Parameters["@userName"].Value = username.Trim();
                    sqlcmd.Parameters.Add(new SqlParameter("@userAge", SqlDbType.SmallInt, 2));
                    sqlcmd.Parameters["@userAge"].Value = password;

                    SqlDataReader sqlRd = sqlcmd.ExecuteReader();
                    if (sqlRd.HasRows)
                    {
                        return true;
                    }

                    return false;
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }
    至此,我们的自定义MembershipProvider算是完成。
    3,配置web.config。把此配置文件下的<system.web>节点下的默认的<membership>节点换成如下:
    <system.web>
       <membership defaultProvider="MyMembershipProvider">
        <providers>
         <clear/>
         <add name="MyMembershipProvider" <!--前三行要用到的名字。。-->type="MvcApplication5.Infrastructure.MyMembershipProvider"/><!--注意不要漏了命名空间的名字。。-->
        </providers>
       </membership>
    4,工作基本完成,只剩查看效果了。
    在项目下加一个Default1Controller,在此Default1Controller下加如下action:
            [HttpPost]
            public ActionResult Index(string username, string password)
            {
                if (Membership.ValidateUser(username, password))
                {
                    ViewData["message"] = "OK";
                }
                else
                {
                    ViewData["message"] = "NO";
                }

                return View();
            }
    发现了吧,用个Membership.ValidateUser()就行了。

    相信同时你也发现了,这样的自定义MembershipProvider似乎实在是没起到什么特别的作用,至少我是这么认为的。。
    而且在MVC中最好不用登录控件,所以我们若在MVC中自定义MembershipProvider跟写自己的会员管理逻辑已没什么差别。。

    如果你确实要使用自定义的MembershipProvider的话,那么以上代码显然是不够的,比如System.Web.Security.MembershipProvider的第一个方法ChangePassword(),它用来更改用户密码,这需要我们自己写的代码来实现它的逻辑。。
    然后是第二个方法ChangePasswordQuestionAndAnswer()用来为用户提供更改问题答案功能,第三个方法CreateUser()来用创建新用户。。

    以上是MembershipProvider,接下来还有RoleProvider,下面是一个自定义RoleProvider的一部分:
    public class MyRoleProvider : RoleProvider
    {
    public override string[] GetRolesForUser(string username)
    {
    if (username == "Steve")
    return new string[] { "ApprovedMember", "CommentsModerator" };
    else
    return new string[] { };
    }
    /* 被省略的部分 */
    }
    当然,有关RoleProvider,要说的还有它的web.config节点配置,希望你上网查查,如果你还是确定你要用它的话。。

    还有就是自定义ProfileProvider,跟前二者差不多,同样如果你确定想用它的话。。

    至于为什么我们能如此简单地自定义这些Provider,有兴趣看看设计模式中的“策略模式”吧。

  • 相关阅读:
    抱歉,我不接私单了
    MySQL大小写补坑记
    Go 系列教程 —— 第 15 部分:指针
    Go 系列教程 —— 14. 字符串
    Go 系列教程 —— 13. Maps
    Go 系列教程 —— 12. 可变参数函数
    Go 系列教程 —— 11. 数组和切片
    Go 系列教程 — 10. switch 语句
    Go 系列教程 — 9. 循环
    Go 系列教程 —— 8. if-else 语句
  • 原文地址:https://www.cnblogs.com/eagle-xie/p/4497144.html
Copyright © 2020-2023  润新知