zoukankan      html  css  js  c++  java
  • EF+MVC+Bootstrap 项目实践 Day2

    一、初识系统

    1、一上来先看下路由规则Global.asax.cs

    routes.MapRoute(
                    "Default", // Route name
                    "{controller}/{action}/{id}", // URL with parameters
                    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
                );

    默认路由是homt/index,找到Controllers/HomeController.cs,发现指向Area的Account的Auth控制器的Index视图

    public ActionResult Index()
            {
                return RedirectToAction("Index", "Auth", new { Area = "Account"});
            }

    2、Index自动跳转Login

    虽然知道按惯例没登陆时会跳到登陆页,但不知道这份源码是靠什么判断的。以前做过的项目,要么是在js的ajax中去取认证,要么是asp.net后台判断Session。

    我把index.cshtml注释掉,还是会自动跳到Login。只是登陆后首页变空白了(因为被注释掉了)。下了断点,发现确实是没跳到index的,是跳转之前就有判断。

    找到AuthController.cs,注释掉,确实不会自动跳转了,会跳到http://localhost:4337/Account/Auth/Index,并报找不到页面

    3、原来是继承了基类

    public class AuthController : AdminControllerBase
    /// <summary>
            /// 方法执行前,如果没有登录就调整到Passport登录页面,没有权限就抛出信息
            /// </summary>
            /// <param name="filterContext"></param>
            protected override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                var noAuthorizeAttributes = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AuthorizeIgnoreAttribute), false);
                if (noAuthorizeAttributes.Length > 0)
                    return;
                
                base.OnActionExecuting(filterContext);
    
                if (this.LoginInfo == null)
                {
                    filterContext.Result = RedirectToAction("Login", "Auth", new { Area = "Account"});
                    return;
                }
        ...后面省略... }

    基类再继承自ControllerBase,重写了OnActionExecuting方法,在跳转时进行权限判断

    (基础知识薄弱呀,一开始登陆页就给个下马威)

    4、登陆页

    http://localhost:4337/Account/Auth/Login

     BootStrap风格,美观大方。

    <div class="alert alert-error hide">
        <button class="close" data-dismiss="alert"></button>
        <span>Enter any username and passowrd.</span>
    </div>
    <form class="form-vertical register-form" action="index.html">
          <h3 class="">Sign Up</h3>
          <p>Enter your account details below:</p>
          <div class="control-group">
            <label class="control-label visible-ie8 visible-ie9">Username</label>
            <div class="controls">
              <div class="input-icon left">
                <i class="icon-user"></i>
                <input class="m-wrap placeholder-no-fix" type="text" placeholder="Username" name="username"/>
              </div>
            </div>
          </div>
          <div class="control-group">
            <label class="control-label visible-ie8 visible-ie9">Password</label>
            <div class="controls">
              <div class="input-icon left">
                <i class="icon-lock"></i>
                <input class="m-wrap placeholder-no-fix" type="password" id="register_password" placeholder="Password" name="password"/>
              </div>
            </div>
          </div>
          <div class="control-group">
            <label class="control-label visible-ie8 visible-ie9">Re-type Your Password</label>
            <div class="controls">
              <div class="input-icon left">
                <i class="icon-ok"></i>
                <input class="m-wrap placeholder-no-fix" type="password" placeholder="Re-type Your Password" name="rpassword"/>
              </div>
            </div>
          </div>
          <div class="control-group">
            <!--ie8, ie9 does not support html5 placeholder, so we just show field title for that-->
            <label class="control-label visible-ie8 visible-ie9">Email</label>
            <div class="controls">
              <div class="input-icon left">
                <i class="icon-envelope"></i>
                <input class="m-wrap placeholder-no-fix" type="text" placeholder="Email" name="email"/>
              </div>
            </div>
          </div>
          <div class="control-group">
            <div class="controls">
              <label class="checkbox">
              <input type="checkbox" name="tnc"/> I agree to the <a href="#">Terms of Service</a> and <a href="#">Privacy Policy</a>
              </label>  
              <div id="register_tnc_error"></div>
            </div>
          </div>
          <div class="form-actions">
            <button id="register-back-btn" type="button" class="btn">
            <i class="m-icon-swapleft"></i>  Back
            </button>
            <button type="submit" id="register-submit-btn" class="btn green pull-right">
            Sign Up <i class="m-icon-swapright m-icon-white"></i>
            </button>            
          </div>
        </form>

    这两段代码访问不到,不知何故,上面一段是英文提示输入用户名密码的,下面那一大段是注册新用户的,把类名去掉就会显示。

    不知是不了解BootStrap还是不了解MVC,或是源码本身Bug,总之在界面上点来点去就是不会出现这两段代码内容

    二、模仿

    没想到一个小小登陆页也这么多名堂。以往以验告诉自已,别人的代码看上去都会,真要自已做时马上无从下手,现在就从第一个页面开始做起。

    1、把自已那个空的MVC翻出来,清空,从头弄起。

    在Controllers上右键,新建控制器Home,再建视图Index.cshtml。

    public ActionResult Index()
            {
                return RedirectToAction("Index", "Auth", new { Area = "Account"});
            }

    发现示例中有new { Area = "Account"}),有个文件夹叫Areas,还以为是新建文件夹。但在项目上右建,发现有个新建区域,那就是这个了,建好后有MVC相应文件夹和 AreaRegistration。

    看来MVC里什么控制器、视图、区域,都要新建相应的,不要自已去建空文件夹和类库,而且在Areas上右键,会有新建区域,在其它地方右键就没有,MVC很看重文件夹和文件命名

    2、照猫画虎,建了Auth的Index和Login

    页面随便写几个字,能辨别是哪个页面就行

     

    3、公共基类

    源码有个Common文件夹,放了1个控制器基类和3个Context,不管怎样,照着来吧,先弄个控制器基类

    不知是MVC版本不同还是怎么着,它可以直接继承ControllerBase,我这不行,除非实现ExecuteCore或改成abstract

    关于四大修饰符virtual、override、sealed、abstract,至今没搞清楚。。。留着哪天查查资料整理一下吧

    还没完,它重写了OnActionExecuting,虽然不懂,但看名字就是执行Action的时候可以做一些操作,我这也要重写这方法,结果没有这方法可重写。。。

    public abstract class ControllerBase : GMS.Framework.Web.ControllerBase

    定睛一看,原来它这不是原始的ControllerBase,是自已又封装了一层,OnActionExecuting是自已的方法。。。

    源码里继承了Common文件夹里的ControllerBase,又继承自上一级GMS.Web的ControllerBase,又继承自另一文件夹的_Framework的GMS.Framework.Web的ControllerBase,最后才继承自Controller

    太多级绕晕了,我这里少一级吧。看它GMS.Web这一级里几个公共类库没什么特别的,和Common文件夹里合并就得了。

    4、特性

    它那边有个LoginInfo,现在还没弄这个,以前项目用的是Session,先随便写上Session的判断,但跳不到Login页,死循环了。因为想要跳转,就会执行OnActionExecuting,而这里面又是要跳转。。。

    研究了一下,发现源码里有使用个[AuthorizeIgnore]特性,字面意思就是忽略验证,然后在基类里判断

    var noAuthorizeAttributes = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AuthorizeIgnoreAttribute), false);
    if (noAuthorizeAttributes.Length > 0) return;
    [AuthorizeIgnore]
     public ActionResult Login()
     {
       return View();
     }

    不管三七二十一,在Login前加上,但是不认,因为这个也是源码自定义的特性。。。

    public class AuthorizeIgnoreAttribute : Attribute {}

    也可以使用.net自带的一些特性,根据特性判断,但试了下好像只有Authorize,没有AuthorizeIgnore之类的。好在可以继承Attribute,自定义特性。

    5、万里长征第一步

    经过一番折腾,总算进了登陆页了。。。一个简简单单的登陆页,用到了这么多知识,这份源码真是太好了,让我学到不少,感谢guozili(http://www.cnblogs.com/guozili/p/3496265.html)。

    明天继续把登陆页UI做出来。还要研究一下怎么映射数据库到实体。目前公司项目用的是T4模板,把表映射成实体,不知EF是怎么个映射法,教程有看过,还没动手实践过。而且也要研究一下它项目里是怎么映射的。

  • 相关阅读:
    三数之和
    罗马数字与整数
    Oracle 开启或关闭归档
    Oracle RMAN scripts to delete archivelog
    Oracle check TBS usage
    Oracle kill locked sessions
    场景9 深入RAC运行原理
    场景7 Data Guard
    场景4 Data Warehouse Management 数据仓库
    场景5 Performance Management
  • 原文地址:https://www.cnblogs.com/liuyouying/p/5037344.html
Copyright © 2011-2022 走看看