前面第一篇开了头个,现在想先从登陆写起,但感觉还有很多东西应该放在前面写,比如
1、MVC及Web API的Route配置,Web API的Route配置如何支持命名空间
2、如何配置Filters(实现安全验证、错误处理等等)
3、自定义Filters、HttpRouteConstraint、ModelBinder及HttpParameterBinding等
这些问题在我开发过程中都有碰到,但感觉每一点都要说太多了。如果有需要到时候再回过头来写。
需求
还是老样子,我们先要明白要登陆实现哪些东西:
1、登陆页面(用户名、密码、记住我、登陆按钮、重置按钮)
2、消息显示(比如 错误时显示某某错误,登陆时显示正在登陆,登陆成功显示正在跳转等)
3、登陆处理(验证、登陆、正在登陆时禁用表单、更新用户登陆次数及时间、添加登陆履历其中要包括用户的内网IP外网IP还有所在城市、其它业务处理)
4、成功跳转
实现效果
在实现之前我们先看看实现出来的效果截图
登陆页面
跳转页面
登陆履历
需求分析及实现
需求中基本都好实现,只有登陆履历中要记录内外网IP及所在城市要考虑一下。在asp.NET中取得客户端内外网IP还是比较麻烦的,而要取得所在城市就基本不可能了,所以我们只好考虑借助第三方api去实现了。
1、内网IP直接在后台取
2、外网IP可以通过新浪API 取得,原来也可以返回城市的,后台不知道什么原因,只能返回IP了
3、所在城市通过百度API =取得,但是这个不会返回外网IP所以我就两个一起用了,挺蛋疼的。
以上在客户端去访问相应的API又存在一个跨域的问题,通过调查发现百度API支持JSONP,可以很好的解决跨域的问题,新浪API不支持但它返回一个变量,我们可以直接把新浪API写在页面srcipt中即可取得相应变量。
技术都应该没问题了,那我们开始写吧。
具体实现
第一步:在MVC中新建LoginController添加如下代码
using System; using System.Web.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Zephyr.Core; using Zephyr.Models; using Zephyr.Web.Areas.Mms.Common; namespace Zephyr.Controllers { [AllowAnonymous] public class LoginController : Controller { public ActionResult Index() { ViewBag.CnName = "建筑材料管理系统"; ViewBag.EnName = "Engineering Material Mangange System"; return View(); } } }
类要用AllowAnonymous属性修饰,才能保证未登陆也能够访问。
第二步:添加对应的View,添加~/Views/Login/Index.cshtml,代码如下
@{ ViewBag.Title = "登录系统"; Layout = null; } <!doctype html> <html> <head> <title>@ViewBag.Title</title> <link href="https://www.jb51.net/~/Content/css/page/login.css" type="text/css" /> <script src="https://www.jb51.net/~/Content/js/jquery/jquery-1.8.1.min.js"></script> <script src="https://www.jb51.net/~/Content/js/core/json2.js"></script> <script src="https://www.jb51.net/~/Content/js/core/knockout-2.2.1.js"></script> <script src="https://www.jb51.net/~/Content/js/viewModel/login.js"></script> <script src="https://counter.sina.com.cn/ip"></script> </head> <body> <div> <form data-bind="submit:loginClick"> <div><img src="https://www.jb51.net/Content/images/login/logo.png" alt="" /></div> <div>@ViewBag.CnName</div> <div>@ViewBag.EnName</div> <div data-bind="html:message"></div> <table> <tr> <td>用户名:</td> <td colspan="2"><input type="text" data-bind="value:form.usercode" /></td> </tr> <tr> <td>密码:</td> <td colspan="2"><input type="password" data-bind="value:form.password" /></td> </tr> <tr> <td></td> <td colspan="2"><input type="checkbox" data-bind="checked:form.remember" /><span>系统记住我</span></td> </tr> <tr> <td colspan="3"> <input type="submit" value="登录" /> <input type="button" value="重置" data-bind="click:resetClick" /> </td> </tr> </table> </form> </div> </body> </html>
1、脚本的最后一个即添加新浪API获取外网IP信息,它返回的数据格式为
var ILData = new Array("117.30.94.103","保留地址", "", "", ""); if (typeof(ILData_callback) != "undefined") { ILData_callback(); }
它其实也有一个callback函数,和JSONP类似,但函数名是固定的,并且没有传递数据。我们可以直接访问ILData[0]取得外网IP。
2、上面html中的data-bind=””写法为knouckoutjs的写法,用于绑定到viewModel的属性
第三步:创建ViewModel