Asp.Net MVC Identity without email

Đôi khi chúng ta không dùng đến trường email trong đăng ký người dùng, mặc định trường này bắt buộc phải nhập và UNIQUE trong Asp.Net MVC Identity.

Để cho phép người dùng đăng ký tài khoản không dùng đến địa chỉ email, bạn làm cách sau:

Mở IdentityConfig.cs và thay đổi giá trị thiết lập RequireUniqueEmail = false theo dưới đây

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
 {
 var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
 // Configure validation logic for usernames
 manager.UserValidator = new UserValidator<ApplicationUser>(manager)
 {
 AllowOnlyAlphanumericUserNames = false,
 RequireUniqueEmail = false
 };
...

Lưu lại và chạy kiểm tra kết quả.

 

Advertisements

Host không hỗ trợ Friendly Url

Lỗi:

Khi ASP.NET Web server không hỗ trợ chế độ FriendlyUrl

Khắc phục:

Comment tất cả các dòng trong RegisterRoutes(…) phương thức của lớp RouteConfig.cs

public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
//var settings = new FriendlyUrlSettings();
//settings.AutoRedirectMode = RedirectMode.Permanent;
//routes.EnableFriendlyUrls(settings);
}
}

Maximum request length exceeded

Lỗi: 

Maximum request length exceeded 

Nguyên nhân:

ASP.NET web server cấu hình mặc định cho phép upload tối đa 4096 KB (4MB), khi upload quá kích thức thì xảy ra lỗi trên

Khắc phục:

<configuration>
    <system.web>
        <httpRuntime maxRequestLength="1048576" />
    </system.web>
</configuration>

Hoặc nếu là IIS lớn hơn phiên bản 7.0

<system.webServer>
   <security>
      <requestFiltering>
         <requestLimits maxAllowedContentLength="1073741824" />
      </requestFiltering>
   </security>
 </system.webServer>

Lỗi khi đưa lên host của nhà cung câp – Unrecognized attribute ‘targetFramework’

Khi đưa lên host của nhà cung cấp, với lỗi thường gặp sau

Unrecognized attribute ‘targetFramework’. Note that attribute names are case-sensitive.

Nguyên nhân và cách khắc phục

  • Nguyên nhân

Website đang được thiết lập cấu hình mặc định là AppPool ASP.NET 2.0

  • Khắc phục

Chuyển AppPool qua ASP.NET 4.0

Error: The OwinStartup attribute discovered in assembly

Khi gặp lỗi sau:

The OwinStartup attribute discovered in assembly ‘eNoteBookApp’ referencing startup type ‘eNoteBookApp.Startup’ conflicts with the attribute in assembly ‘eHandbook’ referencing startup type ‘eHandbook.Startup’ because they have the same FriendlyName ”. Remove or rename one of the attributes, or reference the desired type directly.
To disable OWIN startup discovery, add the appSetting owin:AutomaticAppStartup with a value of “false” in your web.config.
To specify the OWIN startup Assembly, Class, or Method, add the appSetting owin:AppStartup with the fully qualified startup class or configuration method name in your web.config

Hãy xử lý bằng cách:

Mở web.config và bổ sung key sau vào appSettings

<appSettings>
<add key=“owin:AutomaticAppStartup” value=“false”/>
</appSettings>

ASP.NET MVC Role manager Demo

Các bước dưới đây hướng dẫn cách tạo module để quản lý và phân quyền dựa trên vai trò người dùng (Role-based security)

  • Cấu hình web.config để chỉ đến cơ sở dữ liệu cần dùng

<add name=”DefaultConnection” connectionString=”Data Source=(local);Initial Catalog=DatTour;uid=sa;pwd=xxxxxx”
providerName=”System.Data.SqlClient” />

  • Tạo role và user admin mặc định

Mở file Startup.cs ngay trong thư mục gốc của ứng dụng, viết thêm đoạn mã sau

public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
createRolesandUsers();
}

// In this method we will create default User roles and Admin user for login
private void createRolesandUsers()
{
ApplicationDbContext context = new ApplicationDbContext();

var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
// In Startup iam creating first Admin Role and creating a default Admin User
if (!roleManager.RoleExists(“Admin”))
{

// first we create Admin rool
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = “Admin”;
roleManager.Create(role);

//Here we create a Admin super user who will maintain the website

var user = new ApplicationUser();
user.UserName = “khanhn”;
user.Email = “khanhdsp@gmail.com”;

string userPWD = “12121212”;

var chkUser = UserManager.Create(user, userPWD);

//Add default User to Role Admin
if (chkUser.Succeeded)
{
var result1 = UserManager.AddToRole(user.Id, “Admin”);

}
}

// creating Creating Manager role
if (!roleManager.RoleExists(“Manager”))
{
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = “Manager”;
roleManager.Create(role);

}

// creating Creating Employee role
if (!roleManager.RoleExists(“Employee”))
{
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = “Employee”;
roleManager.Create(role);

}
}
}

Bây giờ chạy ứng dụng có thể kiểm tra được role và user được tạo ra trong csdl

  • Customize form đăng ký (Register)

Bổ sung thêm 2 đoạn code highlight dưới đây vào view Register.cshtml

@model shanuMVCUserRoles.Models.RegisterViewModel   
@{   
    ViewBag.Title = "Register";   
}   
<h2>@ViewBag.Title.</h2>   
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))   
{   
    @Html.AntiForgeryToken()   
    <h4>Create a new account.</h4>   
    <hr />   
    @Html.ValidationSummary("", new { @class = "text-danger" })   
    
 class="form-group"           @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })            
 class="col-md-10"               @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })            
        </div>        
 class="form-group"           @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })            
 class="col-md-10"               @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })            
        </div>        
 class="form-group"           @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })            
 class="col-md-10"               @Html.PasswordFor(m => m.Password, new { @class = "form-control" })            
        </div>        
 class="form-group"           @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })            
 class="col-md-10"               @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })            
        </div>        
 class="form-group"           @Html.Label("user Role", new { @class = "col-md-2 control-label" })            
 class="col-md-10"               @*@Html.DropDownList("Name")*@                @Html.DropDownList("UserRoles", (SelectList)ViewBag.Name, " ")            
        </div>        
 class="form-group"           
 class="col-md-offset-2 col-md-10"                type="submit" class="btn btn-default" value="Register" />            
        </div>    }    @section Scripts {        @Scripts.Render("~/bundles/jqueryval")    }
  • Thay đổi RegisterViewModel trong lớp AccountViewModel.cs
public class RegisterViewModel   
    {   
        [Required]   
        [Display(Name = "UserRoles")]   
        public string UserRoles { getset; }   
   
        [Required]   
        [EmailAddress]   
        [Display(Name = "Email")]   
        public string Email { getset; }   
   
        [Required]   
        [Display(Name = "UserName")]   
        public string UserName { getset; }   
   
        [Required]   
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]   
        [DataType(DataType.Password)]   
        [Display(Name = "Password")]   
        public string Password { getset; }   
   
        [DataType(DataType.Password)]   
        [Display(Name = "Confirm password")]   
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]   
        public string ConfirmPassword { getset; }   
    }
  • Thay đổi code sau trong AccountController.cs

ApplicationDbContext context;

public AccountController()
{
context = new ApplicationDbContext();
}

[AllowAnonymous]
public ActionResult Register()
{
ViewBag.Name = new SelectList(context.Roles.Where(u =>!u.Name.Contains(“Admin”)).ToList(), “Name”, “Name”);
return View();
}

  • Sửa lại mã trong Register method của AccountController.cs
// POST: /Account/Register   
        [HttpPost]   
        [AllowAnonymous]   
        [ValidateAntiForgeryToken]   
        public async Task<ActionResult> Register(RegisterViewModel model)   
        {   
            if (ModelState.IsValid)   
            {   
                var user = new ApplicationUser { UserName = model.UserName, Email = model.Email };   
                var result = await UserManager.CreateAsync(user, model.Password);   
                if (result.Succeeded)   
                {   
                    await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);   
   
                    // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771   
                    // Send an email with this link   
                    // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);   
                    // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);   
                    // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");   
                    //Assign Role to user Here      
                    await this.UserManager.AddToRoleAsync(user.Id, model.UserRoles);   
                    //Ends Here    
                    return RedirectToAction("Index""Users");   
                }   
                ViewBag.Name = new SelectList(context.Roles.Where(u => !u.Name.Contains("Admin"))   
                                          .ToList(), "Name""Name");   
                AddErrors(result);   
            }   
   
            // If we got this far, something failed, redisplay form   
            return View(model);   
        }
  • Customize Login.cshtml để đăng nhập bằng UserName thay cho Email
@using shanuMVCUserRoles.Models   
@model LoginViewModel   
@{   
    ViewBag.Title = "Log in";   
}   
   
<h2>@ViewBag.Title</h2>   
class="row">        
class="col-md-8">            
"loginForm">                @using (Html.BeginForm("Login""Account"new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))                {                    @Html.AntiForgeryToken()                    

Use a local account to log in.

                    
                    @Html.ValidationSummary(true""new { @class = "text-danger" })                    
class="form-group">                        @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })                        
class="col-md-10">                            @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })                            @Html.ValidationMessageFor(m => m.UserName, ""new { @class = "text-danger" })                        
                    </div>                    
class="form-group">                        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })                        
class="col-md-10">                            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })                            @Html.ValidationMessageFor(m => m.Password, ""new { @class = "text-danger" })                        
                    </div>                    
class="form-group">                        
class="col-md-offset-2 col-md-10">                            
class="checkbox">                                @Html.CheckBoxFor(m => m.RememberMe)                                @Html.LabelFor(m => m.RememberMe)                            
                        </div>                    </div>                    
class="form-group">                        
class="col-md-offset-2 col-md-10">                            "submit" value="Log in" class="btn btn-default" />                        
                    </div>                    <p>                        @Html.ActionLink("Register as a new user""Register")                    </p>                    @* Enable this once you have account confirmation enabled for password reset functionality                        <p>                            @Html.ActionLink("Forgot your password?""ForgotPassword")                        </p>*@    }            </section>        </div>        
class="col-md-4">            
"socialLoginForm">                @Html.Partial("_ExternalLoginsListPartial"new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl })            
        
    </div>        @section Scripts {        @Scripts.Render("~/bundles/jqueryval")    }
  • Sửa lại LoginViewModel
public class LoginViewModel   
    {   
        [Required]   
        [Display(Name = "UserName")]   
        public string UserName { getset; }   
 
        [Required]   
        [DataType(DataType.Password)]   
        [Display(Name = "Password")]   
        public string Password { getset; }   
   
        [Display(Name = "Remember me?")]   
        public bool RememberMe { getset; }   
    }
  • Sửa lại code của Login action method của AccountController.cs
// POST: /Account/Login   
        [HttpPost]   
        [AllowAnonymous]   
        [ValidateAntiForgeryToken]   
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)   
        {   
            if (!ModelState.IsValid)   
            {   
                return View(model);   
            }   
   
            // This doesn't count login failures towards account lockout   
            // To enable password failures to trigger account lockout, change to shouldLockout: true   
            var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);   
            switch (result)   
            {   
                case SignInStatus.Success:   
                    return RedirectToLocal(returnUrl);   
                case SignInStatus.LockedOut:   
                    return View("Lockout");   
                case SignInStatus.RequiresVerification:   
                    return RedirectToAction("SendCode"new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });   
                case SignInStatus.Failure:   
                default:   
                    ModelState.AddModelError("""Invalid login attempt.");   
                    return View(model);   
            }   
        }   
  • Tạo UsersController.cs và viết code cho Controller như sau

[Authorize]
public class UsersController : Controller
{
// GET: Users
public ActionResult Index()
{
if (User.Identity.IsAuthenticated)
{
var user = User.Identity;
ViewBag.Name = user.Name;

ViewBag.displayMenu = “No”;

if (isAdminUser())
{
ViewBag.displayMenu = “Yes”;
}
return View();
}
else
{
ViewBag.Name = “Not Logged IN”;
}
return View();
}
public Boolean isAdminUser()
{
if (User.Identity.IsAuthenticated)
{
var user = User.Identity;
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var s = UserManager.GetRoles(user.GetUserId());
if (s[0].ToString() == “Admin”)
{
return true;
}
else
{
return false;
}
}
return false;
}
}

  • Index.cshtml view của Users controller

@{
ViewBag.Title = “Index”;
}

@if (ViewBag.displayMenu == “Yes”)
{
<h1>Welcome Admin. Now you can create user Role.</h1>
<h3>
<li>@Html.ActionLink(“Manage Role”, “Index”, “Role”)</li>
</h3>
}
else
{
<h2> Welcome <strong>@ViewBag.Name</strong> 🙂 .We will add user module soon </h2>
}

  • Tạo Empty RoleController.cs và viết code như sau

[Authorize]
public class RoleController : Controller
{
ApplicationDbContext context;

public RoleController()
{
context = new ApplicationDbContext();
}
// GET: Role
public ActionResult Index()
{
if (User.Identity.IsAuthenticated)
{
if (!isAdminUser())
{
return RedirectToAction(“Index”, “Home”);
}
}
else
{
return RedirectToAction(“Index”, “Home”);
}
var Roles = context.Roles.ToList();
return View(Roles);
}

public Boolean isAdminUser()
{
if (User.Identity.IsAuthenticated)
{
var user = User.Identity;
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var s = UserManager.GetRoles(user.GetUserId());
if (s[0].ToString() == “Admin”)
{
return true;
}
else
{
return false;
}
}
return false;
}
/// <summary>
/// Create a New role
/// </summary>
/// <returns></returns>
public ActionResult Create()
{
if (User.Identity.IsAuthenticated)
{
if (!isAdminUser())
{
return RedirectToAction(“Index”, “Home”);
}
}
else
{
return RedirectToAction(“Index”, “Home”);
}
var Role = new IdentityRole();
return View(Role);
}

/// <summary>
/// Create a New Role
/// </summary>
/// <param name=”Role”></param>
/// <returns></returns>
[HttpPost]
public ActionResult Create(IdentityRole Role)
{
if (User.Identity.IsAuthenticated)
{
if (!isAdminUser())
{
return RedirectToAction(“Index”, “Home”);
}
}
else
{
return RedirectToAction(“Index”, “Home”);
}
context.Roles.Add(Role);
context.SaveChanges();
return RedirectToAction(“Index”);
}
}

  • Tạo Index view và create view cho RoleController như sau

Index.cshtml

@model IEnumerable<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>
@{
ViewBag.Title = “Add Role”;
}
<table style=” background-color:#FFFFFF; border: dashed 3px #6D7B8D; padding: 5px;width: 99%;table-layout:fixed;” cellpadding=”6″ cellspacing=”6″>
<tr style=”height: 30px; background-color:#336699 ; color:#FFFFFF ;border: solid 1px #659EC7;”>
<td align=”center” colspan=”2″>
<h2> Create User Roles</h2>
</td>

</tr>

<tr>
<td>
<table id=”tbrole” style=”width:100%; border:dotted 1px; background-color:gainsboro; padding-left:10px;”>

@foreach (var item in Model)
{
<tr>
<td style=”width:100%; border:dotted 1px;”>
@item.Name
</td>
</tr>}
</table>
</td>
<td align=”right” style=”color:#FFFFFF;padding-right:10;”>
<h3> @Html.ActionLink(“Click to Create New Role”, “Create”, “Role”) </h3>
</td>
</tr>
</table>

Create.cshtml

@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
@{
ViewBag.Title = “Add New Role”;
}
<h2>Add New User Role:</h2>

@using (Html.BeginForm())
{
<p> Enter User Role Name:</p>

@Html.EditorFor(m => m.Name)
<input type=”submit” value=”Create Role” />
}

Code hơi dài, hy vọng bạn thực hiện theo các bước thành công. Nếu không bạn có thể download mã nguồn ở link này

Source: bài viết có tham khảo demo của Micrsoft.