前言

上篇的菜鸟去重复之Sql的问题还没有得到满意的答案。如果哪位大哥有相关的资料解释,能够分享给我,那就太谢谢了。

以后每发表一篇博文我都会将以前遗留的问题在前言里指出,直到解决为止。

本文主要在于探讨一下Asp.net Mvc4默认生成的权限的详细内容。

介绍

在VS2012中创建一个默认的带有权限的MVC4 Internet项目,如下图。

生成项目后点运行,在浏览器里点登陆。然后观察项目,此刻生成了数据库,如下。

本文就是针对这样的模版项目里的已有权限全面的分析,希望大家能够从中学到一些东西,如果有问题,请指出。PS:欢迎大家共同讨论进步。

有趣的Attribute

上图中有三个ActionFilter,不清楚ActionFilter的童鞋请点击这里

AuthorizeAttribute:表示一个特性,该特性用于限制调用方对操作方法的访问。

AllowAnonymousAttribute:表示一个特性,该特性用于标记在授权期间要跳过 AuthorizeAttribute 的控制器和操作。

InitializeSimpleMembershipAttribute:这个特性是来初始化数据库成员关系的,后面会讲到。

Authorize

这个Attribute是用来对用户角色权限限制的,大家应该都清楚,此处就不多说了。

AllowAnonymous

这个Attribute似乎是MVC4才加进去的。大致意思看一下上面的解释应该也了解了。其实就是微软团队在Authorize的实现里面加了对AllowAnonymous的判断,如果方法上有这个Attribute就不限制。

真相在这里(反编译的),这个是Authorize的OnAuthorization方法,有兴趣的童鞋可以看看12行。

public virtual void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
{
throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
}
bool inherit = true;
if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit) && !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))
{
if (this.AuthorizeCore(filterContext.HttpContext))
{
HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
cache.SetProxyMaxAge(new TimeSpan(0L));
cache.AddValidationCallback(new HttpCacheValidateHandler(this.CacheValidateHandler), null);
}
else
{
this.HandleUnauthorizedRequest(filterContext);
}
}
}

下面就到了主要的关于默认权限的关键Attribute。

InitializeSimpleMembership

我们先来看下它的实现

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
{
private static SimpleMembershipInitializer _initializer;
private static object _initializerLock = new object();
private static bool _isInitialized; public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Ensure ASP.NET Simple Membership is initialized only once per app start
LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
} private class SimpleMembershipInitializer
{
public SimpleMembershipInitializer()
{
Database.SetInitializer<UsersContext>(null); try
{
using (var context = new UsersContext())
{
if (!context.Database.Exists())
{
// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
catch (Exception ex)
{
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);
}
}
}
}

这个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的解释吧!

InitializeDatabaseConnection()

通过连接到包含用户信息的数据库来初始化成员资格系统。

注释

在应用程序启动时调用此方法(在 _AppStart.cshtml 或 _AppStart.vbhtml 文件中),以初始化简单成员资格系统。此方法验证成员资格数据库是否存在。它还打开到用户配置文件表的连接,并在成员资格数据和用户配置文件数据之间建立 数据库关系。

如果希望使用包含用户配置文件信息(用户名、电子邮件地址等)的数据库表,则应指定成员资格系统用于连接到那些信息的连接字符串和表名称。如果不希望使用现有用户配置文件表,则可指定 InitializeDatabaseConnection() 方法应自动创建用户配置文件表。(用户配置文件表的数据库必须已经存在。)

下面是方法的五个参数解释:

connectionStringName

包含用户信息的数据库的连接字符串的名称。如果使用的是 SQL Server Compact,此名称可以是一个不带 .sdf 文件扩展名的数据库文件(.sdf 文件)的名称。

userTableName

包含用户配置文件信息的数据库表的名称。

userIdColumn

包含用户 ID 的数据库列的名称。此列必须以整数 (int) 形式键入。

userNameColumn

包含用户名的数据库列的名称。此列用于匹配用户配置文件数据与成员资格帐户数据。

autoCreateTables

若为 true,则指示应创建用户配置文件表和成员资格表(如果它们不存在)。若为 false,则指示不应自动创建这些表。虽然可以自动创建成员资格表,但数据库本身必须已经存在。

我的理解

这个方法会对已有的数据库进行分析,如果没有提前创建数据库,调用此方法会报错。

如果已经创建一个空的数据库并且不存在参数对应的userTableName表,设置autoCreateTables为true,会自动创建该参数名的表,字段与userIdColumn及userNameColumn一一对应,并创建其余的四个成员资格表。

如果设置autoCreateTables为false,不会自动创建任何表。

设置autoCreateTables为true,如果已经使用UserContext创建user表,要把表名与UserId、UserName的字段名作为参数赋给InitializeDatabaseConnection()方法作为参数,表名不一致,数据库会多创建一个User表,并以方法参数名的那个来使用webSecurity的方法。字段名不一致,使用webSecurity的方法时会报错。

至此,我们已经大致知道起初见到的那几个数据表是如何生成的了。对,就是webSecurity.InitializeDatabaseConnection方法里自动实现的。

小结

本来打算把默认生成权限的这部分内容尽可能的在一篇里面说完,但写本篇博客的过程中发现需要写的有点多。

奈何我本是菜鸟,内容稍微多了点,就越发感觉脑子有点乱,所以打算分成两篇来写。

呵呵!目前还没有实力写长篇,那得需要思维足够清晰,我还需要锻炼啊!

下篇我打算写一下WebSecurity,SimpleMemberShip,RoleProvider之间的关系,以及它们的使用场合Asp.net Mvc4默认权限详细(下),希望有兴趣的童鞋继续关注!

最后,如果本文有什么问题,还请指出。如果对您有帮助,请帮忙推荐给我更多动力!

http://www.cnblogs.com/fatbird/p/Mvc4_defaultAuthorize.html#n2

转:Asp.net Mvc4默认权限详细(上)的更多相关文章

  1. Asp.net Mvc4默认权限详细(上)

    Asp.net Mvc4默认权限详细(上) 前言 上篇的菜鸟去重复之Sql的问题还没有得到满意的答案.如果哪位大哥有相关的资料解释,能够分享给我,那就太谢谢了. 以后每发表一篇博文我都会将以前遗留的问 ...

  2. Asp.net Mvc4默认权限详细(下)

    前言 菜鸟去重复之Sql的问题还没有得到满意的答案.如果哪位大哥有相关的资料解释,能够分享给我,那就太谢谢了. 以后每发表一篇博文我都会将以前遗留的问题在前言里指出,直到解决为止. 本文主要在于探讨一 ...

  3. 【要什么自行车】ASP.NET MVC4笔记02:上传文件 uploadify 组件使用

    参考:http://www.cnblogs.com/luotaoyeah/p/3321070.html 1.下载 uploadify 组件,copy至 Content文件夹 <link href ...

  4. Asp.net MVC4 ExtJS权限管理系统源码 C#开发框架源码

    开发环境:VS2010或以上 数据库:SQL Server 2008 r2 MVC版本:Asp.net mvc 4.0 ExtJs版本:ext-4.2   功能介绍 1.多标签,js动态加载模式,全a ...

  5. CentOS上 Mono 3.2.8运行ASP.NET MVC4经验

    周一到周三,折腾了两天半的时间,经历几次周折,在小蝶惊鸿的鼎力帮助下,终于在Mono 3.2.8上运行成功MVC4.在此总结经验如下: 系统平台的版本: CentOS 6.5 Mono 3.2.8 J ...

  6. Asp.net mvc4 快速入门之构建表单

    1.asp.net mvc4  Index.cshtml页面上构建表单form的方式 @{ ViewBag.Title = "Index"; Layout = "~/Vi ...

  7. 从零开始实现asp.net MVC4框架网站的用户登录以及权限验证模块 详细教程

    从零开始实现asp.net MVC4框架网站的用户登录以及权限验证模块 详细教程   用户登录与权限验证是网站不可缺少的一部分功能,asp.net MVC4框架内置了用于实现该功能的类库,只需要简单搭 ...

  8. ASP.NET MVC4+EasyUI+EntityFrameWork5权限管理系统——菜单模块的实现(二)

    ASP.NET MVC4+EasyUI+EntityFrameWork5权限管理系统——数据库的设计(一) 菜单和模块是在同一个表中,采用的是树形结构,模块菜单表结构如下代码: USE [Permis ...

  9. 最新版CentOS6.5上安装部署ASP.NET MVC4和WebApi

    最新版CentOS6.5上安装部署ASP.NET MVC4和WebApi 使用Jexus5.8.1独立版 http://www.linuxdot.net/ ps:该“独立版”支持64位的CentOS ...

随机推荐

  1. BZOJ3658 : Jabberwocky

    考虑将某线段下方的点取走: 将所有点从低到高排序 每扫描到一条水平线,对于上面每个点,找到它下面同色的前驱后继,统计中间点的个数 然后再把线上所有点插入数据结构中 最后再统计相邻的同色的点之间的点个数 ...

  2. MySQL删除更新数据时报1175错误的问题

    今天删除mysql数据库中的一条记录的时候,一直不能删除,提示错误信息如下: Error Code: 1175. You are using safe update mode and you trie ...

  3. web farm 讨论引出

    关于web farm 有成功的实施的文档没 用它还不如 用nginx,简单易用. Nginx for windows的运行效果咋样 windows  iis无敌 玩nginx就不要用win系统,必须l ...

  4. CentOS6.4 利用sendEmail发邮件

    1.下载安装sendEmail wget http://caspian.dotconf.net/menu/Software/SendEmail/sendEmail-v1.56.tar.gz tar z ...

  5. Google Code Jam 2009 Qualification Round Problem C. Welcome to Code Jam

    本题的 Large dataset 本人尚未解决. https://code.google.com/codejam/contest/90101/dashboard#s=p2 Problem So yo ...

  6. Struts2 实战(一)

    环境: Ubuntu 14.04 LTS 64位 开发工具的准备 我选择 Eclipse, 而没有选择MyEclipse, 一是因为免费,不想去弄破解,二是不想太傻瓜化的东西(注:本人并没有用过MyE ...

  7. mac mysql环境配置

    安装mysql:http://www.mysql.com/downloads/ 找到 MySQL Community Edition (GPL) Community (GPL) Downloads » ...

  8. sheet目标数据插入函数主键模块

    #coding:gbk #导入处理excel的模块 import xlrd #定义哪些字段需要判断,只支持时间字段 toSureColArray = ['CREATE_TIME','MODIFY_TI ...

  9. mongodb 手动分片的命令汇总

    手动分片的操作 自动分片会带来性能的下降. 所以要合理使用手动分片. 并且配合Tag一起使用. # 对于4个shard的程序, 预先处理的指令1. 加入分片服务器sh.addShard( " ...

  10. 用宏 x y z,找出最大值最小值

    #define max(x,y,z) ((x)>(y)?(x):(y))>(z)?((x)>(y)?(x):(y)):(z) #define min(x,y,z) ((x)<( ...