今天在ASP.NET MVC项目中,实现一个小功能,就是记录浏览者客户端的一些信息。比如浏览者的IP,访问了哪些页面,以及浏览器相关的信息。
在数据库中创建一张表[VisitData]:
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[VisitData]( [VisitData_nbr] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY, [IP] [varchar](20) NOT NULL, [Controller] [varchar](30) NULL, [Action] [varchar](30) NULL, [Browser] [varchar](30) NULL, [Version] [varchar](10) NULL, [Platform] [nvarchar](30) NULL, [Languages] [nvarchar](30) NULL, [UserAgent] [nvarchar](300) NULL, [RecordDate] [datetime] NOT NULL DEFAULT (getdate()), [CreatedBy] [nvarchar](30) NOT NULL DEFAULT (suser_sname()), [UpdatedBy] [nvarchar](30) NOT NULL DEFAULT (suser_sname()), [CreateDate] [datetime] NOT NULL DEFAULT (getdate())) GOSource Code
既然有数据库,那我们还需要写一个存储过程[dbo].[usp_VisitData_Insert]:
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[usp_VisitData_Insert] ( @IP VARCHAR(20), @Controller VARCHAR(30), @Action VARCHAR(30), @Browser VARCHAR(30), @Version VARCHAR(10), @Languages NVARCHAR(30), @Platform NVARCHAR(30), @UserAgent NVARCHAR(300) ) AS INSERT INTO [dbo].[VisitData]([IP],[Controller],[Action],[Browser],[Version],[Languages],[Platform],[UserAgent]) VALUES (@IP,@Controller,@Action,@Browser,@Version,@Languages,@Platform,@UserAgent) GOSource Code
在数据库方法,我们就做这些,接下来我们需要转到ASP.NET MVC项目中,创建一个Model:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Insus.NET.Models { public class VisitData { public string IP { get; set; } public string Controller { get; set; } public string Action { get; set; } public string Browser { get; set; } public string Version { get; set; } public string Languages { get; set; } public string Platform { get; set; } public string UserAgent { get; set; } } }Source Code
创建完model之后,还需要创建一个Entity,这个实体就是数据与数据库之相关联:
using Insus.NET.DataBases; using Insus.NET.Models; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Insus.NET.Entities { public class VisitDataEntity { BizSP sp = new BizSP(); public void Insert(VisitData vd) { List<Parameter> param = new List<Parameter>() { new Parameter("@IP", SqlDbType.VarChar, -1, vd.IP), new Parameter("@Controller", SqlDbType.VarChar, -1, vd.Controller), new Parameter("@Action", SqlDbType.VarChar, -1, vd.Action), new Parameter("@Browser", SqlDbType.VarChar, -1,vd.Browser ), new Parameter("@Version", SqlDbType.VarChar, -1,vd.Version ), new Parameter("@Languages", SqlDbType.VarChar, -1, vd.Languages), new Parameter("@Platform", SqlDbType.VarChar, -1,vd.Platform ), new Parameter("@UserAgent", SqlDbType.NVarChar, -1, vd.UserAgent) }; sp.ConnectionString = DB.ConnectionString; sp.Parameters = param; sp.ProcedureName = "usp_VisitData_Insert"; sp.Execute(); } } }Source Code
下面,我们考虑,只是浏览访问首页时,我们就去获取客户端的信息:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Insus.NET; using Insus.NET.Attributes; using Insus.NET.Models; using Insus.NET.Utilities; using Insus.NET.Entities; namespace Insus.NET.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { VisitData vd = new VisitData(); vd.IP = NetUtility.GetClientIP(); vd.Controller = this.ControllerContext.RouteData.Values["controller"].ToString(); //"Home"; vd.Action = this.ControllerContext.RouteData.Values["action"].ToString(); //"Index"; HttpBrowserCapabilities bc = System.Web.HttpContext.Current.Request.Browser; vd.Browser = bc.Browser; vd.Version = bc.Version; vd.Languages = System.Web.HttpContext.Current.Request.UserLanguages[0]; vd.Platform = bc.Platform; vd.UserAgent = System.Web.HttpContext.Current.Request.UserAgent; VisitDataEntity vie = new VisitDataEntity(); vie.Insert(vd); return View(); } } }Source Code
浏览网站首页,去数据库查询记录的情况:
我们需要的数据已经拿到了。
到现在为止,还有一个问题,我们需要记录浏览者访问了哪一个页面的记录,我们需要把上面那段代码粘贴至所在控制器的操作(Action)中。如果这样多,另一个问题又来了,一个ASP.NET MVC项目这样多。那上一个很可的事情,特别是在维护的时候,就知道它的利弊了。
写一个静态的Utility吧,然后每一个操作中使用这个方法名即可。嗯,想法不错。
不过,在ASP.NET MVC中,有一个更好的方法,就是过滤(filter).
using Insus.NET.Entities; using Insus.NET.Models; using Insus.NET.Utilities; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; namespace Insus.NET.Attributes { public class VisitActionFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { VisitData vd = new VisitData(); vd.IP = NetUtility.GetClientIP(); //vd.Controller = this.ControllerContext.RouteData.Values["controller"].ToString(); //"Home"; //vd.Action = this.ControllerContext.RouteData.Values["action"].ToString(); //"Index"; vd.Controller = filterContext.RouteData.Values["controller"].ToString(); vd.Action = filterContext.RouteData.Values["action"].ToString(); HttpBrowserCapabilities bc = System.Web.HttpContext.Current.Request.Browser; vd.Browser = bc.Browser; vd.Version = bc.Version; vd.Languages = System.Web.HttpContext.Current.Request.UserLanguages[0]; vd.Platform = bc.Platform; vd.UserAgent = System.Web.HttpContext.Current.Request.UserAgent; VisitDataEntity vie = new VisitDataEntity(); vie.Insert(vd); } } }Source Code
接下来简单的事情,就是在每一个控制器添加上面这个特性,如: