public ActionResult UserLogin()
        {
            string validateCode = Session["session_verifycode"] != null ? Session["session_verifycode"].ToString() : string.Empty;
            if (string.IsNullOrEmpty(validateCode))
            {
                return Content("no:验证码错误!!");
            }
            Session["session_verifycode"] = null;
            string txtCode = Md5Helper.Encrypt(Request["vCode"].ToLower(), 16);//输入验证码加密
            if (!validateCode.Equals(txtCode, StringComparison.InvariantCultureIgnoreCase))
            {
                return Content("no:验证码错误!!");
            }
            string userName = Request["LoginCode"];
            string userPwd = Request["LoginPwd"];
            var userInfo = UserInfoService.Select(u => u.UName == userName && u.UPwd == userPwd).FirstOrDefault();//根据用户名找用户
            if (userInfo != null)
            {
                Model.UserInfoDto userInfoDto = new Model.UserInfoDto
                {
                    Id = userInfo.Id,
                    UName = userInfo.UName,
                    UPwd = userInfo.UPwd
                };

                // Session["userInfo"] = userInfo;
                //产生一个GUID值作为RedisString的键., DateTime.Now.AddMinutes(30)
                string sessionId = Guid.NewGuid().ToString();

                //将登录用户信息存储到RedisString中。直接存userInfo对象,如果存userInfo的json字符串时会存在\转义字符导致序列化失败。
                //延迟加载和Redis string数据类型中存储对象序列化为字符串类型不能很好地混合,
                //如果不小心,只是因为启用了延迟加载,最终就可以对整个数据库进行查询。 大多数序列化程序通过访问类型实例上的每个属性来工作。 属性访问会触发延迟加载,因此会序列化更多的实体。 写入redis string时卡死现象
                //在这些实体上,将访问这些实体的属性,甚至还会加载更多实体。 在对实体进行序列化之前,最好关闭延迟加载。或新建临时实体对象
                //cache.Write<Model.UserInfo>(sessionId, userInfo, DateTime.Now.AddMinutes(30));
                cache.Write<Model.UserInfoDto>(sessionId, userInfoDto, DateTime.Now.AddMinutes(30));
                Response.Cookies["sessionId"].Value = sessionId;//将RedisString中登录用户信息的key以Cookie的形式返回给浏览器。

                return Content("ok:登录成功");
            }
            else
            {

                return Content("no:登录失败");
            }
        }
        /// <summary>
        /// 执行控制器中的方法之前先执行该方法
        /// </summary>
        /// <param name="filterContext"></param>
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);

            #region 登录验证
            bool isSucess = false;
            if (Request.Cookies["sessionId"] != null)
            {
                string sessionId = Request.Cookies["sessionId"].Value;
                //根据sessionId key值查RedisString
                //Model.UserInfo userInfoTemp = cache.Read<Model.UserInfo>(sessionId);//userInfo对象字符串
                Model.UserInfoDto userInfoDto = cache.Read <Model.UserInfoDto>(sessionId);//userInfo对象字符串
                if (userInfoDto != null)
                {
                    LoginUserDto = userInfoDto;
                    isSucess     = true;
                    //cache.Write<Model.UserInfo>(sessionId, userInfoTemp, DateTime.Now.AddMinutes(30));//模拟出滑动过期时间.
                    cache.Write <Model.UserInfoDto>(sessionId, userInfoDto, DateTime.Now.AddMinutes(30));//模拟出滑动过期时间.

                    ////留一个后门,测试方便。发布的时候一定要删除该代码。
                    //if (LoginUser.UName == "itcast")
                    //{
                    //    return;
                    //}


                    ////完成权限校验。
                    ////获取用户请求的URL地址.
                    //string url = Request.Url.AbsolutePath.ToLower();
                    ////获取请求的方式.
                    //string httpMehotd = Request.HttpMethod;
                    ////根据获取的URL地址与请求的方式查询权限表。
                    //IApplicationContext ctx = ContextRegistry.GetContext();
                    //IBLL.IActionInfoService ActionInfoService = (IBLL.IActionInfoService)ctx.GetObject("ActionInfoService");
                    //var actionInfo = ActionInfoService.LoadEntities(a => a.Url == url && a.HttpMethod == httpMehotd).FirstOrDefault();

                    ////判断用户是否具有所访问的地址对应的权限
                    //IUserInfoService UserInfoService = (IUserInfoService)ctx.GetObject("UserInfoService");
                    //var loginUserInfo = UserInfoService.LoadEntities(u => u.ID == LoginUser.ID).FirstOrDefault();
                    ////1:可以先按照用户权限这条线进行过滤。
                    //var isExt = (from a in loginUserInfo.R_UserInfo_ActionInfo
                    //             where a.ActionInfoID == actionInfo.ID
                    //             select a).FirstOrDefault();
                    //if (isExt != null)
                    //{
                    //    if (isExt.IsPass)
                    //    {
                    //        return;
                    //    }
                    //    else
                    //    {
                    //        filterContext.Result = Redirect("/Error.html");
                    //        return;
                    //    }

                    //}
                    ////2:按照用户角色权限这条线进行过滤。
                    //var loginUserRole = loginUserInfo.RoleInfo;
                    //var count = (from r in loginUserRole
                    //             from a in r.ActionInfo
                    //             where a.ID == actionInfo.ID
                    //             select a).Count();
                    //if (count < 1)
                    //{
                    //    filterContext.Result = Redirect("/Error.html");
                    //    return;
                    //}
                }



                //  filterContext.HttpContext.Response.Redirect("/Login/Index");
            }
            if (!isSucess)
            {
                filterContext.Result = Redirect("/Login/Index");//注意.
            }
            #endregion
        }