你的位置:首页 > ASP.net教程

[ASP.net教程]mvc5+ef6+Bootstrap 项目心得


最近和朋友完成了一个大单子架构是mvc5+ef6+Bootstrap,用的是vs2015,数据库是sql server2014。朋友做的架构,项目完成后觉得很多值得我学习,在这里总结下一些心得。

创建项目一开始删掉App_Start目录下的IdentityConfig.cs和Startup.Auth.cs文件;清空Modle文件夹,Controller文件夹和相应的View; 删除目录下的ApplicationInsights.config文件和Startup.cs文件

修改web.config文件(添加<add key="owin:AutomaticAppStartup" value="false"/>不使用Startup.cs文件来启动项目)

<appSettings>  <add key="webpages:Version" value="3.0.0.0" />  <add key="webpages:Enabled" value="false" />  <add key="ClientValidationEnabled" value="true" />  <add key="UnobtrusiveJavaScriptEnabled" value="true" />  <add key="owin:AutomaticAppStartup" value="false"/> <!--去掉创建项目初的Startup.cs文件的设置--> </appSettings>

(不用他们是因为自带的这些内容太冗余)

去掉冗余内容正式开始,首先介绍数据库这一块,数据库我们是配置的可以手动生成和修改的

1.在项目目录想创建Migrations文件夹,里面添加Configuration.cs文件

internal sealed class Configuration : DbMigrationsConfiguration<AccountContext>  {    public Configuration()    {      AutomaticMigrationsEnabled = true;      ContextKey = "UserProject.DAL.AccountContext";    }    protected override void Seed(AccountContext context)    {      //base.Seed(context);    }  }

在Modle文件夹下添加AccountContext.cs文件

public class AccountContext:DbContext  {    public AccountContext():base("AccountContext") {    }    public DbSet<User> Users { get; set; }    protected override void OnModelCreating(DbModelBuilder modelBuilder)    {      modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();    }  }

<connectionStrings>  <add name="AccountContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\UserProject.mdf;Initial Catalog=UserProject;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>

然后 使用vs2015里面的工具-NuGet包管理器-程序包管理控制平台

输入add-migration Initial 按回车,在输入update-database按回车。在App_Data文件夹下就会看到AccountContext数据库了。

2.在Modle文件夹下添加User.css文件

public class User  {    public int ID { get; set; }    public string UserName { get; set; }    public string Password { get; set; }    public Role Role { get; set; }  }

public enum Role//角色枚举
{ 管理员 = 0, 员工 = 1, 经理 = 2, 总经理 = 3, 董事长 = 4 }

在ViewModle文件夹中添加Account.cs文件

public class Account  {    [Required]    public string Name { get; set; }    [Required]    public string Password { get; set; }    public string RePassword { get; set; }  }

这里推荐创建BaseController之后的Controller就继承它来使用

public class BaseController : Controller  {    public string UserName => User.Identity.Name;    public AccountContext db = new AccountContext();    private User _userInfo = null;    public User CurrentUserInfo    {      get      {        if (_userInfo == null)        {          var user = db.Users.SingleOrDefault(u => u.UserName == UserName);//此处为了不每次访问用户表可以做一个静态类,里面存放用户表信息.          _userInfo = user == null ? null : new User()          {            ID = user.ID,            UserName = user.UserName,            Role = user.Role          };        }        return _userInfo;      }    }
    //验证角色:获取Action的CustomAttributes,过滤角色 protected override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); var authRoleAtt = filterContext.ActionDescriptor.GetCustomAttributes(false).SingleOrDefault(att => att is AuthorizeRoleAttribute) as AuthorizeRoleAttribute; if (authRoleAtt == null && CurrentUserInfo != null) return; if (!authRoleAtt.Roles.Contains(CurrentUserInfo.Role)) { filterContext.Result = View("NoPermission", "_Layout", "您没有权限访问此功能!"); } }
//这里是记log用 protected override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); var msg = $"用户: {CurrentUserInfo?.UserName}, 链接: {Request.Url}"; if (Request.HttpMethod == "POST") msg += $", 数据: {HttpUtility.UrlDecode(Request.Form.ToString())}"; //Log.Debug(msg); } }

AdminController继承BaseController

[Authorize]    public ActionResult Index()    {      return View(db.Users.ToList());    }        [Authorize, AuthorizeRole(Role.管理员)]    public ActionResult Details(int? id)    {      if (id == null)      {        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);      }      User user = db.Users.Find(id);      if (user == null)      {        return HttpNotFound();      }      return View(user);    }

 

登录页面:

@model UserProject.ViewModels.Account@{  ViewBag.Title = "Login";}@using (Html.BeginForm("Login", "Admin",FormMethod.Post, new { @class = "form-horizontal", role = "form" })) {  @Html.AntiForgeryToken()  <hr />        @Html.ValidationSummary(true, "", new { @class = "text-danger" })        <div class="form-group">          @Html.LabelFor(m => m.Name, new { @class = "col-md-2 control-label" })          <div class="col-md-10">            @Html.TextBoxFor(m => m.Name, new { @class = "form-control" })            @Html.ValidationMessageFor(m => m.Name, "", new { @class = "text-danger" })          </div>        </div>        <div class="form-group">          @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })          <div class="col-md-10">            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })            @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })          </div>        </div>        <div class="form-group">          <div class="col-md-offset-2 col-md-10">            <input type="submit" value="登录" class="btn btn-primary" />          </div>        </div>}

登录的Action:

[AllowAnonymous]    public ActionResult Login()    {      return View();    }    [HttpPost, AllowAnonymous]    public ActionResult Login(Account model)    {      if (ModelState.IsValid)      {        var user = db.Users.SingleOrDefault(t => t.UserName == model.Name && t.Password == model.Password);        if (user != null)        {          FormsAuthentication.SetAuthCookie(model.Name, false);//将用户名放入Cookie中          return RedirectToAction("Index");        }        else        {          ModelState.AddModelError("Name", "用户名不存在!");        }      }      return View(model);    }    public ActionResult LogOff()    {      FormsAuthentication.SignOut();      return RedirectToAction("Login");    }

按照以上方式 访问Details这个Action的时候必须是管理员角色。

 如果有什么不懂,或者其它问题,联系我。