在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
上篇的菜鸟去重复之Sql的问题还没有得到满意的答案。如果哪位大哥有相关的资料解释,能够分享给我,那就太谢谢了。 以后每发表一篇博文我都会将以前遗留的问题在前言里指出,直到解决为止。 本文主要在于探讨一下Asp.net Mvc4默认生成的权限的详细内容。 介绍在VS2012中创建一个默认的带有权限的MVC4 Internet项目,如下图。 生成项目后点运行,在浏览器里点登陆。然后观察项目,此刻生成了数据库,如下。 本文就是针对这样的模版项目里的已有权限全面的分析,希望大家能够从中学到一些东西,如果有问题,请指出。PS:欢迎大家共同讨论进步。 有趣的Attribute上图中有三个ActionFilter,不清楚ActionFilter的童鞋请点击这里。 AuthorizeAttribute:表示一个特性,该特性用于限制调用方对操作方法的访问。 AuthorizeAttribute 的控制器和操作。 InitializeSimpleMembershipAttribute:这个特性是来初始化数据库成员关系的,后面会讲到。 Authorize这个Attribute是用来对用户角色权限限制的,大家应该都清楚,此处就不多说了。 AllowAnonymous这个Attribute似乎是MVC4才加进去的。大致意思看一下上面的解释应该也了解了。其实就是微软团队在Authorize的实现里面加了对AllowAnonymous的判断,如果方法上有这个Attribute就不限制。 12行。 1 public virtual void OnAuthorization(AuthorizationContext filterContext) 2 { 3 if (filterContext == null) 4 { 5 throw new ArgumentNullException("filterContext"); 6 } 7 if (OutputCacheAttribute.IsChildActionCacheActive(filterContext)) 8 { 9 throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache); 10 } 11 bool inherit = true; 12 if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit) && !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)) 13 { 14 if (this.AuthorizeCore(filterContext.HttpContext)) 15 { 16 HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache; 17 cache.SetProxyMaxAge(new TimeSpan(0L)); 18 cache.AddValidationCallback(new HttpCacheValidateHandler(this.CacheValidateHandler), null); 19 } 20 else 21 { 22 this.HandleUnauthorizedRequest(filterContext); 23 } 24 } 25 }
下面就到了主要的关于默认权限的关键Attribute。 InitializeSimpleMembership我们先来看下它的实现 1 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 2 public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute 3 { 4 private static SimpleMembershipInitializer _initializer; 5 private static object _initializerLock = new object(); 6 private static bool _isInitialized; 7 8 public override void OnActionExecuting(ActionExecutingContext filterContext) 9 { 10 // Ensure ASP.NET Simple Membership is initialized only once per app start 11 LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock); 12 } 13 14 private class SimpleMembershipInitializer 15 { 16 public SimpleMembershipInitializer() 17 { 18 Database.SetInitializer<UsersContext>(null); 19 20 try 21 { 22 using (var context = new UsersContext()) 23 { 24 if (!context.Database.Exists()) 25 { 26 // Create the SimpleMembership database without Entity Framework migration schema 27 ((IObjectContextAdapter)context).ObjectContext.CreateDatabase(); 28 } 29 } 30 WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true); 31 } 32 catch (Exception ex) 33 { 34 throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex); 35 } 36 } 37 } 38 } 这个Atrribute里面实现了创建我们起初见到的数据库。 现在让我们来看看具体是如何实现的。这个创建数据库的方式还是和以前使用Code First有点出入的。 4-12行 主要是定义了几个变量并重写OnActionExcuting,实现了确保Asp.net成员关系只初始化一次。我们可以料到,必然在LazyInitializer.EnsureInitialized函数里面实例化了SimpleMembershipInitializer。 只初始化一次就意味着不会调用SimpleMembershipInitializer的构造函数两次。其实看代码我们应该也大致能猜到,这个构造函数里面主要做的就是创建数据库的功能,当然最好只实现一次。 22-29行 主要就是调用方法创建UsersContext的数据库,相关代码如下 public class UsersContext : DbContext { public UsersContext() : base("DefaultConnection") { } public DbSet<UserProfile> UserProfiles { get; set; } } [Table("UserProfile")] public class UserProfile { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } public string UserName { get; set; } } 我们从上面可以了解到UsersContext继承DbContext,并以DefaultConnection字符串为连接字符串,有一张表UserProfile。 那这时我们就会有疑问了,在文章开头介绍里的那几个标出来的表是如何生成的呢。先别急,我们继续往下看 WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true); 这句话的字面意思一看就猜到了。初始化数据库连接使用连接字符串Default,表UserProfile,字段UserId,UserName,自动创建表。 可是我们之前已经使用UserContext的CreateDatabase()创建过数据库和表了。难道再重新创建一次!!?好吧!还是让我们看看MSDN的解释吧!
下面是方法的五个参数解释: connectionStringName 包含用户信息的数据库的连接字符串的名称。如果使用的是 SQL Server Compact,此名称可以是一个不带 .sdf 文件扩展名的数据库文件(.sdf 文件)的名称。 userTableName 包含用户配置文件信息的数据库表的名称。 userIdColumn 包含用户 ID 的数据库列的名称。此列必须以整数 (int) 形式键入。 userNameColumn 包含用户名的数据库列的名称。此列用于匹配用户配置文件数据与成员资格帐户数据。 autoCreateTables 若为 true,则指示应创建用户配置文件表和成员资格表(如果它们不存在)。若为 false,则指示不应自动创建这些表。虽然可以自动创建成员资格表,但数据库本身必须已经存在。
至此,我们已经大致知道起初见到的那几个数据表是如何生成的了。对,就是webSecurity.InitializeDatabaseConnection方法里自动实现的。 小结本来打算把默认生成权限的这部分内容尽可能的在一篇里面说完,但写本篇博客的过程中发现需要写的有点多。 奈何我本是菜鸟,内容稍微多了点,就越发感觉脑子有点乱,所以打算分成两篇来写。 呵呵!目前还没有实力写长篇,那得需要思维足够清晰,我还需要锻炼啊! 下篇我打算写一下WebSecurity,SimpleMemberShip,RoleProvider之间的关系,以及它们的使用场合Asp.net Mvc4默认权限详细(下),希望有兴趣的童鞋继续关注! 最后,如果本文有什么问题,还请指出。如果对您有帮助,请帮忙推荐给我更多动力!
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论