1, intranet IP directly in the background fetch
2, extranet IP can be obtained through the Sina API HTTP://COUNTER.SINA.COM.CN/IP, the original can also return to the city, backstage do not know what reason, can only return IP
3, the city through Baidu API Http://api.map.baidu.com/location/ip?ak=&ip= obtained, but this will not return to the extranet IP so I used the two together, very egg pain.
Above the client to access the corresponding API there is a cross-domain problem, through the survey found that Baidu API support JSONP, can be a good solution to the problem of Cross-domain, Sina API does not support but it returns a variable, we can directly in the Sina API written in the page srcipt can get the corresponding variables.
Technology should be all right, so let's start writing.
Concrete implementation
Step one: Create a new Logincontroller in MVC add the following code
The code is as follows |
Copy Code |
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 = "Building Material management system"; viewbag.enname = "Engineering Material Mangange System "; return View (); } } } |
Class to be decorated with the allowanonymous attribute to ensure that it is not logged in and can be accessed.
Step two: Add the corresponding view, add ~/views/login/index.cshtml, the code is as follows
The code is as follows |
Copy Code |
@{
Viewbag.title = "Login System";
Layout = null;
}
<!doctype html>
<html>
<head>
<title> @ViewBag .title</title>
<link href= "~/content/css/page/login.css" rel= "stylesheet" type= "Text/css"/>
<script src= "~/content/js/jquery/jquery-1.8.1.min.js" ></script>
<script src= "~/content/js/core/json2.js" ></script>
<script src= "~/content/js/core/knockout-2.2.1.js" ></script>
<script src= "~/content/js/viewmodel/login.js" ></script>
<script src= "HTTP://COUNTER.SINA.COM.CN/IP" ></script>
</head>
<body>
<div class= "Second_body" >
<form data-bind= "Submit:loginclick" >
<div class= "logo" ><img src= "/content/images/login/logo.png" alt= ""/></div>
<div class= "Title-zh" > @ViewBag .cnname</div>
<div class= "Title-en" style= "@ViewBag. Ennamestyle" > @ViewBag .enname</div>
<div class= "message" data-bind= "Html:message" ></div>
<table border= "0" style= "width:300px;" >
<tr>
<TD style= "padding-bottom:5px;width:55px;" > User name:</td>
<TD colspan= "2" ><input type= "text" class= "login" data-bind= "Value:form.usercode"/></td>
</tr>
<tr>
<TD class= "lable" style= "LETTER-SPACING:0.5EM; Vertical-align:middle "> Password:</td>
<TD colspan= "2" ><input type= "password" class= "login" data-bind= "Value:form.password"/></td>
</tr>
<tr>
<td></td>
<TD colspan= "2" ><input type= "checkbox" data-bind= "Checked:form.remember"/><span> system Remember me </span ></td>
</tr>
<tr>
<TD colspan= "3" style= "Text-align:center" >
<input type= "Submit" value= "Login" class= "Login_button"/>
<input type= "button" value= "reset" class= "Reset_botton" data-bind= "Click:resetclick"/>
</td>
</tr>
</table>
</form>
</div>
</body>
</html> |
1, the last of the script is to add the Sina API to obtain extranet IP information, it returns the data format
var ildata = new Array ("117.30.94.103", "Reserved Address", "", "", ""); if (typeof (Ildata_callback)!= "undefined") {Ildata_callback ();}
It actually has a callback function, similar to JSONP, but the function name is fixed and no data is passed. We can directly access ildata[0] to get the extranet IP.
2, the above HTML data-bind= "" is written as Knouckoutjs, used to bind to the ViewModel properties
Step Three: Create ViewModel
The code is as follows |
Copy Code |
var ViewModel = function () {
var self = this;
This.form = {
Usercode:ko.observable (),
Password:ko.observable (),
Remember:ko.observable (False),
Ip:null,
City:null
};
This.message = Ko.observable ();
This.loginclick = function (form) {
$.ajax ({
Type: "POST",
URL: "/login/doaction",
Data:ko.toJSON (Self.form),
DataType: "JSON",
ContentType: "Application/json",
Success:function (d) {
if (D.status = = ' success ') {
Self.message ("Login success is jumping, please wait ...");
Window.location.href = '/';
} else {
Self.message (D.message);
}
},
Error:function (e) {
Self.message (E.responsetext);
},
Beforesend:function () {
$ (form). Find ("Input"). attr ("Disabled", true);
Self.message ("Login processing, please wait ...");
},
Complete:function () {
$ (form). Find ("Input"). attr ("disabled", false);
}
});
}; This.resetclick = function () { Self.form.usercode (""); Self.form.password (""); Self.form.remember (FALSE); }; This.init = function () { Self.form.ip = ildata[0]; $.getjson ("http://api.map.baidu.com/location/ip?ak=F454f8a5efe5e577997931cc01de3974&callback=?", Function (d ) { self.form.city = d.content.address; }); if (top!= window) top.window.location = window.location; }; This.init (); }; $ (function () {ko.applybindings (New ViewModel ());}); |
Defines ViewModel, whose properties include from form information, message hint information, Loginclick login, ResetClick reset. The init part of it can actually not be put into the viewmodel.
1, $.getjson is the JSONP access, which plus the parameters Callback=?,jquery will automatically be processed into the current callback function, that is, cross-domain success automatically callback the current function and incoming data. We use the form.city in ViewModel to receive the city information in the requested data.
2, the last sentence ko.applybindings (new ViewModel ()) that is the implementation of the page and ViewModel binding, so far, the front desk complete. Next write login processing doaction, or put in Logincontroller, access address for/login/doaction.
Step Fourth: Add the Doaction method to the Logincontroller to return the JSON data. The code is as follows:
The code is as follows |
Copy Code |
Public Jsonresult doaction (Jobject request) { var usercode = Request. Value<string> ("Usercode"); var Password = Request. value<string> ("password"); if (String.IsNullOrEmpty (usercode) | | String.IsNullOrEmpty (Password)) Return Json (New {status= "error", message= "user name or password cannot be empty!) " }); var service = new Sys_userservice (); var result = service. Getmodel (Paramquery.instance () . Andwhere ("Usercode", Usercode) . Andwhere ("Password", Zencypt.md5 (Password)) . Andwhere ("Isenable", true); if (result = = NULL | | String.IsNullOrEmpty (result. Usercode)) Return Json (New {status= "error", message= "incorrect user name or password!) " }); var Loginer = new Loginerbase {Usercode = result. Usercode,username=result. UserName};
Formsauth.signin (Loginer. Usercode, Loginer, 60 * 8); Login mechanism in the call frame login time set to 8 hours
New Sys_loginhistoryservice (). Appendloginhistory (Request); Add login resume after landing
Service. Updateuserlogincountanddate (Usercode); Update user login times in time after landing
Mmsservice.loginhandler (this); Other business processes Return Json (New {status= "success", message= "landing success!") "},jsonrequestbehavior.denyget); } |
The receive parameters are defined as Jobject objects are more convenient to obtain request data, which used two data services, one for Sys_userservice and Sys_loginhistoryservice, the Getmodel in the data service is already in the service base class, But Appendloginhistory and Updateuserlogincountanddate to write their own code as follows
code is as follows |
copy code |
using System; using System.Collections.Generic; using System.Text; using Zephyr.core; Namespace Zephyr.models { public class Sys_userservice:servicebase<sys_user> { public void Updateuserlogincountanddate (string usercode) { DB. SQL (@ Update Sys_user Set logincount = IsNull (logincount,0) + 1 , lastlogindate = getdate () W Here Usercode = @0 " , Usercode). Execute (); } }} using System; using System.Collections.Generic; using System.Text; using Zephyr.core; using Zephyr.utils; Namespace Zephyr.models { public class Sys_loginhistoryservice:servicebase<sys_loginhistory> { public void Appendloginhistory (Jobject request) { var lanip = Zhttp.clientip; var hostName = Zhttp.islanip (Lanip)? ZHttp.ClientHostName:string. Empty; If the intranet is acquired, otherwise the error can not be obtained, and affect the efficiency var usercode = Request. Value<string> ("Usercode");
var UserName = Mmshelper.getusername (); var IP = Request. value<string> ("IP");
var city = Request. Value<string> ("City");
if (Ip!=lanip)
IP = string. Format ("{0}/{1}", IP, Lanip). Trim ('/'). Replace (":: 1", "localhost");//mosaic IP var item = new Sys_loginhistory ();
Item. Usercode = Usercode;
Item. UserName = UserName;
Item. HostName = HostName;
Item. HostIP = IP;
Item. logincity = City;
Item. Logindate = DateTime.Now; Db. Insert<sys_loginhistory> ("Sys_loginhistory", item). Automap (x=>x.id). Execute (); } }} |
It's done!