Sunday, August 14, 2011

ASP.NET Membership service usage my own database with Entity framwork DbContext

ASP.NET -нэгэн шинэ технологи болох EntityFramwork ийн DbContext болон Membership Service ийг хэрхэн ашиглах вэ?
Эхлээд эхлээд өөрийн MVC 3 Project үүсгэ. Тэгээд өгөгдлийн сангаа DbContext ашиглан ( өмнөх сэдвүүдийг хараарай ) автоматаар үүсгэнэ. Дараа нь

1. ctrl + R дараад CMD г ажиллуулна.
2. > C:\Windows\Microsoft.NET\Framework\v4.0.30319>aspnet_regsql.exe ажиллуул
3. Доорхи цонх гарч ирнэ.
4. Next
5. Next
За энд нэг зүйлийг хэлэхэд DemoUser гэсэн хэсэгт анхаарвал, анх MVC project үүсгэж байхад Web.config файл дотор default нэг connection үүсдэг. Түүний нэр нь aspnetdb гэсэн байдаг. Тэр connectionString г өөрийнхөөрөө дураараа солиж болно. Жишээ нь минийх нэг иймэрхүү::::
<connectionStrings>
    <clear/>
    <add name="MyDbContext"
         connectionString="data source=.;Database=MyDbName;User ID=sa;Password=password;Persist Security Info=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
  </connectionStrings>

Энэ зурган дээр орлуулт тавибал DemoUser -ний оронд MyDbName гэж бичих болно гэсэн үг.
Харин MyDbContext нэр бол class MyDbContext : DbContext {  } байх болно. Ингэж Entity FrameWork 4 тэй хамт Membership  Service тэй хамт ашиглах боломжтой болно.

  
6. Next
7. Next 
Энэ үед өгөгдлийн санд нэмэлт өөрчлөлт орно. Энэ нь өгөгдлийн санг Membership service д зориулан өөрчлөн шинэчиж байгаа.


8. үр дүнд нь сонгосон өгөгдлий сан доорхи маягийн бүтцээр шинэчлэгдсэн байх болно.

aspnet_Applications
aspnet_Membership - хэрэглэгч нэвтрэхтэй холбоотой мэдээлэл байна
aspnet_Paths
aspnet_PersonalizationAllUsers
aspnet_PersonalizationPerUser
aspnet_Profile         - энд програмчин өөрийн хүссэнээр property нэмж болно
aspnet_Roles           - эрхүүдийн мэдээлэл
aspnet_SchemaVersions
aspnet_Users               - Хэрэглэгчийн нэвтрэх нэр, нууцлагдсан Id
aspnet_UsersInRoles     - Эрхүүдэд хамаарах хэрэглэгчийг холбосон мэдээлэл бий
aspnet_WebEvent_Events

гэсэн Table үүд шинээр үүснэ.

9. үүсгэсэн MVC project ийнхоо Web.config дээр

<authentication mode="Forms" />
    <membership defaultProvider="SqlMembershipProvider" hashAlgorithmType="SHA1">
      <providers>
        <clear />
        <add
          type = "System.Web.Security.SqlMembershipProvider"
          name = "SqlMembershipProvider"
          connectionStringName = "MyDbContext"
          applicationName = "/"
          enablePasswordRetrieval = "false"       - нууц үгийг код дотор харах боломжгүй
          enablePasswordReset = "true"              - нууц үгийг шинэчилж болно
          requiresQuestionAndAnswer = "false" - бүртгүүлж байхад заавал нэхэхгүй
          requiresUniqueEmail = "true"               - майл хаягийг ялгаатай бүртгэнэ
          passwordFormat = "Hashed"                 - нууц үг нууцлэгдан орно ( Clear бол энгийн )
          maxInvalidPasswordAttempts = "5"
          minRequiredPasswordLength = "6"
          minRequiredNonalphanumericCharacters = "0" - нууц үгэнд тусгай тэмдэгт байхгүй
          passwordAttemptWindow = "10" />
      </providers>
    </membership>
    <profile>
      <providers>
        <clear />
        <add type="System.Web.Profile.SqlProfileProvider"
             name="SqlProfileProvider"
             connectionStringName = "MyDbContext"
             applicationName="/" />
      </providers>
    </profile>
    <roleManager enabled="true" defaultProvider="SqlRoleProvider">
      <providers>
        <clear />
        <add type = "System.Web.Security.SqlRoleProvider"
             name = "SqlRoleProvider"
             connectionStringName = "MyDbContext"
             applicationName = "/" />
      </providers>
    </roleManager>
    <!--<authorization>
      <allow roles="SYSTEM,ADMIN,USER" />
      <deny users="*" />
    </authorization>-->

мөрүүдийг нэмж өгнө байвал хэрэггүй.

10. энэ блогийн өмнөх жишээнүүдийг хараарай ! Entity framwork DbContext той Membership зэрэг ажиллаж болно. Нэг зөвхөн хэрэглэгч нууцлалтай холбоотой асуудлыг, нөгөө нь өгөгдлөөр хангаж Model ийг агуулна.

public class InitializerMyDbContext : DropCreateDatabaseIfModelChanges<MyDbContext>
    {
        protected override void Seed(MyDbContext context)
        {
            base.Seed(context);
        }
    }

    public class MyDbContext : DbContext
    {
        public DbSet<ArtistInfo> ArtistInfoes { get; set; }
        public DbSet<AudioInfo> AudioInfoes { get; set; }
        public DbSet<ProductInfo> ProductInfoes { get; set; }
.....................
гэх мэт кодын хэсэг байж таараа

11. энэ бол хамгийн чухал хэсэг ( 9 ) дүгээрт бичсэн тохиргоор нь ASP.NET web ажиллах үед Membership.Provider - Class - г автоматаар дүүргэх ба шууд ашиглах боломжтой. За би програмистууддаа зориулж өөрийнхөө үүсгэсэн шууд ашиглаж болох Class г энд тавъя доорхи кодыг нэг бүрчлэн маш сайн хараарай

public class MembershipServiceHelper
    {
        private MembershipProvider Provider = null;

        public MembershipServiceHelper()
        {
// Membership.Provider системээр үүсгэгдсэн class
            Provider = Membership.Provider;
        }

        public MembershipCreateStatus CreateUser(string userName, string password, string email, bool isApproved)
        {
            InitRoot();
// Provider.ApplicationName = WebSites.Current.Name бол олон веб сайтад тус тусд нь захиран зарцуулах боломжийг олгох зорилготой зохиомол код. энгийн үед Provider.ApplicationName ийг өөрчлөх шаардлага бараг байдаггүй.
            Provider.ApplicationName = WebSites.Current.Name;
            if (isCreatedAnyUser(userName))
            {
                return MembershipCreateStatus.DuplicateUserName;
            }
            if (isCreatedAnyEmail(email))
            {
                return MembershipCreateStatus.DuplicateEmail;
            }
            MembershipCreateStatus status;
            MembershipUser user = Membership.CreateUser(userName, password, email, null, null, isApproved, out status);
            return status;
        }

        public bool ValidateUser(string userName, string password)
        {
            Provider.ApplicationName = WebSites.Current.Name;
            return Membership.ValidateUser(userName, password);
        }

        public bool ChangePassword(string userName, string oldPassword, string newPassword)
        {
            Provider.ApplicationName = WebSites.Current.Name;
            MembershipUser user = Membership.GetUser(userName);
            return user.ChangePassword(oldPassword, newPassword);
        }

        public bool ResetPassword(string email, string question, string answer)
        {
            Provider.ApplicationName = WebSites.Current.Name;
            MembershipUser user = Membership.GetUser(email);
            if (user.PasswordQuestion.Equals(question))
            {
                string newPassword = user.ResetPassword(answer);
                if (newPassword != null && newPassword.Length > 0)
                {
                    return resetPasswordSuccess(user, newPassword);
                }
            }
            return false;
        }

        public bool ResetPassword(string email)
        {
            Provider.ApplicationName = WebSites.Current.Name;
            string userName = Membership.GetUserNameByEmail(email);
            if (userName != null && userName.Length > 0)
            {
                MembershipUser user = Membership.GetUser(userName);
                string newPassword = user.ResetPassword();
                if (newPassword != null && newPassword.Length > 0)
                {
                    return resetPasswordSuccess(user, newPassword);
                }
            }
            return false;
        }

        public bool UpdateUser(MembershipUser user)
        {
            Provider.ApplicationName = WebSites.Current.Name;
            Membership.UpdateUser(user);
            return true;
        }

        public MembershipUser GetUser(string userName, bool isOnline)
        {
            Provider.ApplicationName = WebSites.Current.Name;
            return Membership.GetUser(userName, isOnline);
        }

        public string GetUserName(string email)
        {
            Provider.ApplicationName = WebSites.Current.Name;
            return Membership.GetUserNameByEmail(email);
        }
       
        private bool resetPasswordSuccess(MembershipUser user, string newPassword)
        {
            string body = string.Format(HtmlMailResources.ResetPassword, newPassword, WebSites.Current.FullName);

            string[] roles = Roles.GetRolesForUser(user.UserName);
            if (roles.Length == 0)
            {
                roles = new string[] { SystemConstants.DbSystemRole };
            }
            if (roles.Contains(SystemConstants.DbSystemRole)
                || roles.Contains(SystemConstants.DbAdminRole)
                || roles.Contains(SystemConstants.DbOperatorRole))
            {
                MailUtil.systemMailSend(user.Email, WebSites.Current.Name, body);
            }
            else
            {
                MailUtil.siteMailSend(user.Email, WebSites.Current.Name, body, null);
            }
            return true;
        }

        private bool InitRoot()
        {
            if (!isCreatedRootUser())
            {
                InitSystemRole();

                Provider.ApplicationName = WebSites.Current.Name;
                MembershipCreateStatus status;
                Membership.CreateUser(SystemConstants.DbSystemUser
                    , Membership.GeneratePassword(Membership.MinRequiredPasswordLength, Membership.MinRequiredNonAlphanumericCharacters)
                    , SystemConstants.RootUserEmail, ".", ".", false, out status);
                return (status == MembershipCreateStatus.Success);
            }
            return false;
        }

        private void InitSystemRole()
        {
            Provider.ApplicationName = WebSites.Current.Name;
            Roles.CreateRole(SystemConstants.DbSystemRole);
            Roles.CreateRole(SystemConstants.DbAdminRole);
            Roles.CreateRole(SystemConstants.DbOperatorRole);
            Roles.CreateRole(SystemConstants.DbUserRole);
            Roles.CreateRole(SystemConstants.DbClientRole);
        }

        private bool isCreatedAnyUser(string userName)
        {
            Provider.ApplicationName = WebSites.Current.Name;
            return (Membership.GetUser(userName) != null);
        }

        private bool isCreatedRootUser()
        {
            Provider.ApplicationName = WebSites.Current.Name;
            return (Membership.GetUser(SystemConstants.DbSystemUser) != null);
        }

        private bool isCreatedAnyEmail(string email)
        {
            Provider.ApplicationName = WebSites.Current.Name;
            return (Membership.GetUserNameByEmail(email) != null);
        }
    }

12. За одоо энэ class ийг ашигласан Controller - ийн кодыг доор тавъя
default аар үүсгэсэн AccountController -г жаахан өөрчлөөд өөртөө зориулаад нэг иймэрхүү::::

MembershipServiceHelper helper = new MembershipServiceHelper();
        //Cms1DbContextHelper helper = Cms1DbContextHelper.Current;
// би хуучин AuthenticationService ашиглаж байлаа харин одоо Membership service ашиглаж байгаа.

        [HttpPost]
        public ActionResult ResetPassword(ResetPasswordModel model, string returnUrl)
        {
            if (helper.ResetPassword(model.Email))
            {
                ViewBag.Status = "OK";
                return View("~/Views/Admin/Login/ResetPassword.cshtml");
                //Redirect("~/Admin/Login/ResetPassword");
            }
            else
            {
                ModelState.AddModelError("", "Хэрэглэгчийн нэр майл хаягаа зөв оруулна уу.");
                return View("~/Views/Admin/Login/ForgetPassword.cshtml");
            }
        }

        [HttpPost]
        public ActionResult Login(LogOnModel model, string Return_Url)
        {
            if (ModelState.IsValid)
            {
                if (helper.ValidateUser(model.UserName, model.Password))
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(Return_Url) && Return_Url.Length > 1 && Return_Url.StartsWith("/")
                        && !Return_Url.StartsWith("//") && !Return_Url.StartsWith("/\\"))
                    {
                        return Redirect(Return_Url);
                    }
                    else
                    {
                        return Redirect("~/Admin/Home");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "Хэрэглэгчийн нэр эсвэл нууц үг буруу байна.");
                    return View("~/Views/Admin/Login/Index.cshtml");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/LogOn

        public ActionResult LogOn()
        {
            return View();
        }

        //
        // POST: /Account/LogOn

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string Return_Url)
        {
            if (ModelState.IsValid)
            {
                if (helper.ValidateUser(model.UserName, model.Password))
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(Return_Url) && Return_Url.Length > 1 && Return_Url.StartsWith("/")
                        && !Return_Url.StartsWith("//") && !Return_Url.StartsWith("/\\"))
                    {
                        return Redirect(Return_Url);
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "Хэрэглэгчийн нэр эсвэл нууц үг буруу байна.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/LogOff

        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();

            return RedirectToAction("Index", "Home");
        }

        //
        // GET: /Account/Register

        public ActionResult Register()
        {
            return View();
        }

        //
        // POST: /Account/Register

        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus;
                createStatus = helper.CreateUser(model.UserName, model.Password, model.Email, false);
               
                if (createStatus == MembershipCreateStatus.Success)
                {
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    ModelState.AddModelError("", ErrorCodeToString(createStatus));
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/ChangePassword

        [Authorize]
        public ActionResult ChangePassword()
        {
            return View();
        }

        //
        // POST: /Account/ChangePassword

        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {

                // ChangePassword will throw an exception rather
                // than return false in certain failure scenarios.
                bool changePasswordSucceeded;
                try
                {
                    MembershipUser currentUser = helper.GetUser(User.Identity.Name, true /* userIsOnline */);
                    changePasswordSucceeded = helper.ChangePassword(currentUser.UserName, model.OldPassword, model.NewPassword);
                }
                catch (Exception)
                {
                    changePasswordSucceeded = false;
                }

                if (changePasswordSucceeded)
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "Хуучин нүүц үг буруу эсвэл шинэ нууц үг буруу алдаатай байна.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/ChangePasswordSuccess

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }


ДҮГНЭЛТ

Хамгийн гол нь сонгосон өгөгдлийн сангаа Membership Service аар баяжуулаад Web.config оо түүнд зориулж жаахан өөрчлөөд бараг болж байгаа. Web.config тэр хэсгийг сайн ойлговол гар код бичихэд хялбар байх болно. За амжилт

No comments: