[转载]构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(48)-工作流设计-起草新申请 - ymnets - 博客园

mikel阅读(1451)

来源: [转载]构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(48)-工作流设计-起草新申请 – ymnets – 博客园

系列目录

创建新表单之后,我们就可以起草申请了,申请按照严格的表单步骤和分支执行。

起草的同时,我们分解流转的规则中的审批人并保存,具体流程如下

 

接下来创建DrafContoller控制器,此控制器只有2个页面,一个Create(起草页面)Index(表单列表)

表单列表显示个人想法,我是根据分类直接获取其下表单,即Flow_Type下的Flow_Form


public ActionResult Index()
{
List<Flow_TypeModel> list = m_BLL.GetList(ref setNoPagerAscBySort, "");
foreach (var v in list)
{
v.formList = new List<Flow_FormModel>();
List<Flow_FormModel> formList = formBLL.GetListByTypeId(v.Id);
v.formList = formList;
}
ViewBag.DrafList = list;
return View();


}

Index ActionResult


@using App.Admin;
@using App.Common;
@using App.Models.Sys;
@using App.Lang;
@{
ViewBag.Title = "起草申请";
Layout = "~/Views/Shared/_Index_Layout.cshtml";
}

<div style="padding:10px;">
@foreach (var v in (List<App.Models.Flow.Flow_TypeModel>)ViewBag.DrafList)
{
<fieldset class="accordion" style="margin: 0px; padding: 0px; padding-bottom:10px; margin-bottom: 10px;">
<legend class="tabs-header panel-title" style="border: 0px; padding: 5px; margin: 20px; margin-bottom:5px;">@v.Name</legend>
<div style="padding-left:20px;color:#808080">备注:@v.Remark</div>
<div style="padding: 0px 20px 40px 20px;">

@foreach (var r in v.formList)
{
<div style="float: left; width: 120px; margin:10px 0px 10px 0px;">
<a href="javascript:void(0)" class="easyui-linkbutton" data-options="plain:true,iconCls:'icon-details'" onclick="javascript:window.parent.addTab('@r.Name','/Flow/Draf/Create?id=@r.Id','icon-add')">@r.Name</a>
</div>

}
</div>
</fieldset>
}
</div>

Index.cshtml

上面的表单列表简单完成之后,进入最复杂的一步,获取字段组成表单

获取字段组成表单可以做得很漂亮,即在设计表单的时候设计布局,直接读取布局,否则按照表单的控件顺序读取布局。

具体对比如下:

VS

明显前者更利于打印和阅读。我们先布局第二种形式

根据表Flow_FormContent设置Create页面的固定头尾


@model App.Models.Flow.Flow_FormContentModel
@using App.Common;
@using App.Models.Flow;
@using App.Admin;
@using App.Models.Sys;
@{
ViewBag.Title = "创建";
Layout = "~/Views/Shared/_Index_Layout.cshtml";
List<permModel> perm = (List<permModel>)ViewBag.Perm;
if (perm == null)
{
perm = new List<permModel>();
}
}
<script src="~/Scripts/My97DatePicker/WdatePicker.js"></script>
<script type="text/javascript">
$(function () {
$("#btnSave").click(function () {
if ($("#Title").val() == "")
{
$.messageBox5s("提示", "表单标题必须填写!");
return false;
}
if (CheckForm()) {
$.ajax({
url: "@Url.Action("Create")",
type: "Post",
data: $("form").serialize(),
dataType: "json",
success: function (data) {
if (data.type == 1) {
$.messageBox5s("添加成功!", data.message);
$("#btnSave").hide();
}
else {
window.parent.frameReturnByMes(data.message);
}
}
});
}
return false;
});
$("#btnReturn").click(function () {
if ($("#btnSave").is(":hidden")) {
window.parent.CloseCurrentWin();
} else {
$.messager.confirm('提示', '没有保存的数据将会丢失,你确定要返回吗?', function (r) {
if (r) {
window.parent.CloseCurrentWin();
}
});
}
});
});
</script>
@Html.Raw(ViewBag.HtmlJS)
<div class="mvctool ">
@Html.ToolButton("btnSave", "icon-save", "保存", perm, "Create", true)
@Html.ToolButton("btnReturn", "icon-return", "返回",false)
</div>
@using (Html.BeginForm())
{
<table class="fromEditTable setTextWidth300">
<tbody>
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.FormId)
@Html.HiddenFor(model => model.UserId)
<input id="CreateTime" type="hidden" name="CreateTime" value="2000-1-1" />
<input id="TimeOut" type="hidden" name="TimeOut" value="2111-1-1" />
<tr>
<td style="width:100px; text-align:right;">
@Html.LabelFor(model => model.Title):
</td>
<td style="width:310px">
@Html.EditorFor(model => model.Title)
</td>
<td>@Html.ValidationMessageFor(model => model.Title)</td>
</tr>
@Html.Raw(ViewBag.Html)

<tr><td style='width:100px; text-align:right;'>紧急程度 :</td><td><select name="FormLevel" id="FormLevel"><option value="普通">普通</option><option value="重要">重要</option><option value="紧急">紧急</option></select></td></tr>
</tbody>
</table>
}

代码

@Html.Raw(ViewBag.Html)就是我们的表单核心部分。所以Create必须返回ViewBag.Html内容为设计表单的JS和字段

这里代码有点别扭,因为有26个字段,所以要循环26个字段去判断是否有关联来读取。很麻烦。可以用反射来做可以省很多代码

先创建一个类,这个类是辅助工作流的通用类


using App.Models.Flow;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace App.Admin
{
public class FlowHelper
{
//获取指定类型的HTML表单
public string GetInput(string type, string id, string attrNo)
{
string str = "";
if (type == "文本")
{
str = "<input id='" + id + "'  name='" + attrNo + "'  type='text' />";
}
else if (type == "多行文本")
{
str = "<textarea id='" + id + "' name='" + attrNo + "'  cols='60' style='height: 80px;' rows='5'></textarea>";
}
else if (type == "日期")
{
str = "<input type='text'  name='" + attrNo + "' class='Wdate' onfocus=\"WdatePicker({dateFmt:'yyyy-MM-dd'})\"  id='" + id + "'  />";
}
else if (type == "时间")
{
str = "<input type='text'  name='" + attrNo + "' class='Wdate' onfocus=\"WdatePicker({dateFmt:'yyyy-MM-dd HH:mm'})\"  id='" + id + "'  />";
}
else if (type == "数字")
{
str = "<input type='number'  name='" + attrNo + "'  id='" + id + "'  />";
}
return str;
}

}
}

FlowHelper.cs


[SupportFilter]
public ActionResult Create(string id)
{
ViewBag.Perm = GetPermission();
ViewBag.Html = ExceHtmlJs(id);
Flow_FormContentModel model = new Flow_FormContentModel();
model.FormId = id;
return View(model);
}
//根据设定公文,生成表单及控制条件
private string ExceHtmlJs(string id)
{
//定义一个sb为生成HTML表单
StringBuilder sbHtml = new StringBuilder();
StringBuilder sbJS = new StringBuilder();
sbJS.Append("<script type='text/javascript'>function CheckForm(){");
Flow_FormModel model = formBLL.GetById(id);

#region 判断流程是否有字段,有就生成HTML表单
//获得对象的类型,model
Type formType = model.GetType();
//查找名称为"A-Z"的属性
string[] arrStr = { "AttrA", "AttrB", "AttrC", "AttrD", "AttrE", "AttrF", "AttrG", "AttrH", "AttrI", "AttrJ", "AttrK"
, "AttrL", "AttrM", "AttrN", "AttrO", "AttrP", "AttrQ", "AttrR", "AttrS", "AttrT", "AttrU"
, "AttrV", "AttrW", "AttrX", "AttrY", "AttrZ"};
foreach (string str in arrStr)
{
object o = formType.GetProperty(str).GetValue(model, null);
if (o != null)
{
sbHtml.Append(JuageExc(o.ToString(), str, ref sbJS));
}
}
#endregion
sbJS.Append("return true}</script>");
ViewBag.HtmlJS = sbJS.ToString();
return sbHtml.ToString();
}

private string JuageExc(string attr, string no,ref StringBuilder sbJS)
{

if (!string.IsNullOrEmpty(attr))
{
return GetHtml(attr, no, ref sbJS);

}
return "";
}
//获取指定名称的HTML表单
private string GetHtml(string id, string no, ref StringBuilder sbJS)
{
StringBuilder sb = new StringBuilder();
Flow_FormAttrModel attrModel = formAttrBLL.GetById(id);
sb.AppendFormat("<tr><td style='width:100px; text-align:right;'>{0} :</td>", attrModel.Title);
//获取指定类型的HTML表单
sb.AppendFormat("<td>{0}</td></tr>", new FlowHelper().GetInput(attrModel.AttrType, attrModel.Name, no));
sbJS.Append(attrModel.CheckJS);
return sb.ToString();
}

引入命名空间using System;

代码结构:上面没有什么特殊算法。主要是26个字段用反射来读取。自己细细消化一下就行

应该可以用了,点击请假申请看看!

完成。可以起草新的申请了。接下来就是保存申请…

保存是最复杂的一步要取得表单,分解步骤,分解分支,最后指定审核人

看Create方法


public JsonResult Create(Flow_FormContentModel model)
{
model.Id = ResultHelper.NewId;
model.CreateTime = ResultHelper.NowTime;
model.UserId = GetUserId();
if (model != null && ModelState.IsValid)
{

if (formContentBLL.Create(ref errors, model))
{

//当前的Form模版
Flow_FormModel formModel = formBLL.GetById(model.FormId);

//创建成功后把步骤取出
List<Flow_StepModel> stepModelList = stepBLL.GetList(ref setNoPagerAscBySort,model.FormId);
//查询步骤
bool IsEnd = true;
foreach (Flow_StepModel stepModel in stepModelList)
{
List<Flow_StepRuleModel> stepRuleModelList = stepRuleBLL.GetList(stepModel.Id);
//获取规则判断流转方向
foreach (Flow_StepRuleModel stepRuleModel in stepRuleModelList)
{
string val =new FlowHelper().GetFormAttrVal(stepRuleModel.AttrId, formModel, model);
//有满足不流程结束的条件
if (!JudgeVal(stepRuleModel.AttrId, val, stepRuleModel.Operator, stepRuleModel.Result))
{
if (stepRuleModel.NextStep != "0")
{
IsEnd = false;
}
}
}
//插入步骤审核表
Flow_FormContentStepCheckModel stepCheckModel = new Flow_FormContentStepCheckModel();
stepCheckModel.Id = ResultHelper.NewId;
stepCheckModel.ContentId = model.Id;
stepCheckModel.StepId = stepModel.Id;
stepCheckModel.State = 2;//0不通过1通过2审核中
stepCheckModel.StateFlag = false;//true此步骤审核完成
stepCheckModel.CreateTime = ResultHelper.NowTime;
stepCheckModel.IsEnd = IsEnd;//是否流程的最后一步
if (stepCheckBLL.Create(ref errors, stepCheckModel))//新建步骤成功
{
//获得流转规则下的审核人员
List<string> userIdList = GetStepCheckMemberList(stepModel.Id,model.Id);
foreach (string userId in userIdList)
{
//批量建立步骤审核人表
Flow_FormContentStepCheckStateModel stepCheckModelState = new Flow_FormContentStepCheckStateModel();
stepCheckModelState.Id = ResultHelper.NewId;
stepCheckModelState.StepCheckId = stepCheckModel.Id;
stepCheckModelState.UserId = userId;
stepCheckModelState.CheckFlag = 2;
stepCheckModelState.Reamrk = "";
stepCheckModelState.TheSeal = "";
stepCheckModelState.CreateTime = ResultHelper.NowTime;
stepCheckStateBLL.Create(ref errors, stepCheckModelState);
}
}

if (IsEnd)//如果是最后一步就无需要下面继续了
{
break;
}
IsEnd = true;
}



LogHandler.WriteServiceLog(GetUserId(), "Id" + model.Id + ",AttrA" + model.AttrA, "成功", "创建", "Flow_FormContent");
return Json(JsonHandler.CreateMessage(1, Suggestion.InsertSucceed));
}
else
{
string ErrorCol = errors.Error;
LogHandler.WriteServiceLog(GetUserId(), "Id" + model.Id + ",AttrA" + model.AttrA + "," + ErrorCol, "失败", "创建", "Flow_FormContent");
return Json(JsonHandler.CreateMessage(0, Suggestion.InsertFail + ErrorCol));
}
}
else
{
return Json(JsonHandler.CreateMessage(0, Suggestion.InsertFail));
}
}


//无分页获取
public GridPager setNoPagerAscBySort = new GridPager()
{
rows = 1000,
page = 1,
sort = "Sort",
order = "asc"
};
//无分页获取
public GridPager setNoPagerDescBySort = new GridPager()
{
rows = 1000,
page = 1,
sort = "Sort",
order = "desc"
};


using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using App.Common;
using App.IBLL;
using App.Models.Sys;
using Microsoft.Practices.Unity;
using App.Flow.IBLL;
using App.Models.Flow;
using System.Text;
using System;

namespace App.Admin.Areas.Flow.Controllers
{


public class DrafController : BaseController
{
[Dependency]
public ISysUserBLL userBLL { get; set; }
[Dependency]
public IFlow_TypeBLL m_BLL { get; set; }
[Dependency]
public IFlow_FormBLL formBLL { get; set; }
[Dependency]
public IFlow_FormAttrBLL formAttrBLL { get; set; }
[Dependency]
public IFlow_FormContentBLL formContentBLL { get; set; }
[Dependency]
public IFlow_StepBLL stepBLL { get; set; }
[Dependency]
public IFlow_StepRuleBLL stepRuleBLL { get; set; }
[Dependency]
public IFlow_FormContentStepCheckBLL stepCheckBLL { get; set; }
[Dependency]
public IFlow_FormContentStepCheckStateBLL stepCheckStateBLL { get; set; }


ValidationErrors errors = new ValidationErrors();

public ActionResult Index()
{
List<Flow_TypeModel> list = m_BLL.GetList(ref setNoPagerAscBySort, "");
foreach (var v in list)
{
v.formList = new List<Flow_FormModel>();
List<Flow_FormModel> formList = formBLL.GetListByTypeId(v.Id);
v.formList = formList;
}
ViewBag.DrafList = list;
return View();


}


[HttpPost]
[SupportFilter]
public JsonResult Create(Flow_FormContentModel model)
{
model.Id = ResultHelper.NewId;
model.CreateTime = ResultHelper.NowTime;
model.UserId = GetUserId();
if (model != null && ModelState.IsValid)
{

if (formContentBLL.Create(ref errors, model))
{

//当前的Form模版
Flow_FormModel formModel = formBLL.GetById(model.FormId);

//创建成功后把步骤取出
List<Flow_StepModel> stepModelList = stepBLL.GetList(ref setNoPagerAscBySort,model.FormId);
//查询步骤
bool IsEnd = true;
foreach (Flow_StepModel stepModel in stepModelList)
{
List<Flow_StepRuleModel> stepRuleModelList = stepRuleBLL.GetList(stepModel.Id);
//获取规则判断流转方向
foreach (Flow_StepRuleModel stepRuleModel in stepRuleModelList)
{
string val =new FlowHelper().GetFormAttrVal(stepRuleModel.AttrId, formModel, model);
//有满足流程结束的条件
if (!JudgeVal(stepRuleModel.AttrId, val, stepRuleModel.Operator, stepRuleModel.Result))
{
if (stepRuleModel.NextStep != "0")
{
IsEnd = false;
}
}
}
//插入步骤审核表
Flow_FormContentStepCheckModel stepCheckModel = new Flow_FormContentStepCheckModel();
stepCheckModel.Id = ResultHelper.NewId;
stepCheckModel.ContentId = model.Id;
stepCheckModel.StepId = stepModel.Id;
stepCheckModel.State = 2;//0不通过1通过2审核中
stepCheckModel.StateFlag = false;//true此步骤审核完成
stepCheckModel.CreateTime = ResultHelper.NowTime;
stepCheckModel.IsEnd = IsEnd;//是否流程的最后一步
if (stepCheckBLL.Create(ref errors, stepCheckModel))//新建步骤成功
{
//获得流转规则下的审核人员
List<string> userIdList = GetStepCheckMemberList(stepModel.Id,model.Id);
foreach (string userId in userIdList)
{
//批量建立步骤审核人表
Flow_FormContentStepCheckStateModel stepCheckModelState = new Flow_FormContentStepCheckStateModel();
stepCheckModelState.Id = ResultHelper.NewId;
stepCheckModelState.StepCheckId = stepCheckModel.Id;
stepCheckModelState.UserId = userId;
stepCheckModelState.CheckFlag = 2;
stepCheckModelState.Reamrk = "";
stepCheckModelState.TheSeal = "";
stepCheckModelState.CreateTime = ResultHelper.NowTime;
stepCheckStateBLL.Create(ref errors, stepCheckModelState);
}
}

if (IsEnd)//如果是最后一步就无需要下面继续了
{
break;
}
IsEnd = true;
}



LogHandler.WriteServiceLog(GetUserId(), "Id" + model.Id + ",AttrA" + model.AttrA, "成功", "创建", "Flow_FormContent");
return Json(JsonHandler.CreateMessage(1, Suggestion.InsertSucceed));
}
else
{
string ErrorCol = errors.Error;
LogHandler.WriteServiceLog(GetUserId(), "Id" + model.Id + ",AttrA" + model.AttrA + "," + ErrorCol, "失败", "创建", "Flow_FormContent");
return Json(JsonHandler.CreateMessage(0, Suggestion.InsertFail + ErrorCol));
}
}
else
{
return Json(JsonHandler.CreateMessage(0, Suggestion.InsertFail));
}
}

public List<string> GetStepCheckMemberList(string stepId,string formContentId)
{
List<string> userModelList = new List<string>();
Flow_StepModel model = stepBLL.GetById(stepId);
if (model.FlowRule == "上级")
{
SysUserModel userModel = userBLL.GetById(GetUserId());
string[] array = userModel.Lead.Split(',');//获得领导,可能有多个领导
foreach (string str in array)
{
userModelList.Add(str);
}
}
else if (model.FlowRule == "职位")
{
string[] array = model.Execution.Split(',');//获得领导,可能有多个领导
foreach (string str in array)
{
List<SysUserModel> userList = userBLL.GetListByPosId(str);
foreach (SysUserModel userModel in userList)
{
userModelList.Add(userModel.Id);
}
}
}
else if (model.FlowRule == "部门")
{
GridPager pager = new GridPager()
{
rows = 10000,
page = 1,
sort = "Id",
order = "desc"
};
string[] array = model.Execution.Split(',');//获得领导,可能有多个领导
foreach (string str in array)
{
List<SysUserModel> userList = userBLL.GetUserByDepId(ref pager, str, "");
foreach (SysUserModel userModel in userList)
{
userModelList.Add(userModel.Id);
}
}
}
else if (model.FlowRule == "人员")
{
string[] array = model.Execution.Split(',');//获得领导,可能有多个领导
foreach (string str in array)
{
userModelList.Add(str);
}
}
else if (model.FlowRule == "自选")
{
string users  = formContentBLL.GetById(formContentId).CustomMember;
string[] array = users.Split(',');//获得领导,可能有多个领导
foreach (string str in array)
{
userModelList.Add(str);
}
}
return userModelList;
}
//对比
private bool JudgeVal(string attrId, string rVal, string cVal, string lVal)
{
string attrType = formAttrBLL.GetById(attrId).AttrType;
return new FlowHelper().Judge(attrType, rVal, cVal, lVal);
}


[SupportFilter]
public ActionResult Create(string id)
{
ViewBag.Perm = GetPermission();
ViewBag.Html = ExceHtmlJs(id);
Flow_FormContentModel model = new Flow_FormContentModel();
model.FormId = id;
return View(model);
}
//根据设定公文,生成表单及控制条件
private string ExceHtmlJs(string id)
{
//定义一个sb为生成HTML表单
StringBuilder sbHtml = new StringBuilder();
StringBuilder sbJS = new StringBuilder();
sbJS.Append("<script type='text/javascript'>function CheckForm(){");
Flow_FormModel model = formBLL.GetById(id);

#region 判断流程是否有字段,有就生成HTML表单
//获得对象的类型,model
Type formType = model.GetType();
//查找名称为"A-Z"的属性
string[] arrStr = { "AttrA", "AttrB", "AttrC", "AttrD", "AttrE", "AttrF", "AttrG", "AttrH", "AttrI", "AttrJ", "AttrK"
, "AttrL", "AttrM", "AttrN", "AttrO", "AttrP", "AttrQ", "AttrR", "AttrS", "AttrT", "AttrU"
, "AttrV", "AttrW", "AttrX", "AttrY", "AttrZ"};
foreach (string str in arrStr)
{
object o = formType.GetProperty(str).GetValue(model, null);
if (o != null)
{
sbHtml.Append(JuageExc(o.ToString(), str, ref sbJS));
}
}
#endregion
sbJS.Append("return true}</script>");
ViewBag.HtmlJS = sbJS.ToString();
return sbHtml.ToString();
}

private string JuageExc(string attr, string no,ref StringBuilder sbJS)
{

if (!string.IsNullOrEmpty(attr))
{
return GetHtml(attr, no, ref sbJS);

}
return "";
}




//获取指定名称的HTML表单
private string GetHtml(string id, string no, ref StringBuilder sbJS)
{
StringBuilder sb = new StringBuilder();
Flow_FormAttrModel attrModel = formAttrBLL.GetById(id);
sb.AppendFormat("<tr><td style='width:100px; text-align:right;'>{0} :</td>", attrModel.Title);
//获取指定类型的HTML表单
sb.AppendFormat("<td>{0}</td></tr>", new FlowHelper().GetInput(attrModel.AttrType, attrModel.Name, no));
sbJS.Append(attrModel.CheckJS);
return sb.ToString();
}
}
}

FlowHelper.cs


public List<string> GetStepCheckMemberList(string stepId,string formContentId)
{
List<string> userModelList = new List<string>();
Flow_StepModel model = stepBLL.GetById(stepId);
if (model.FlowRule == "上级")
{
SysUserModel userModel = userBLL.GetById(GetUserId());
string[] array = userModel.Lead.Split(',');//获得领导,可能有多个领导
foreach (string str in array)
{
userModelList.Add(str);
}
}
else if (model.FlowRule == "职位")
{
string[] array = model.Execution.Split(',');//获得领导,可能有多个领导
foreach (string str in array)
{
List<SysUserModel> userList = userBLL.GetListByPosId(str);
foreach (SysUserModel userModel in userList)
{
userModelList.Add(userModel.Id);
}
}
}
else if (model.FlowRule == "部门")
{
GridPager pager = new GridPager()
{
rows = 10000,
page = 1,
sort = "Id",
order = "desc"
};
string[] array = model.Execution.Split(',');//获得领导,可能有多个领导
foreach (string str in array)
{
List<SysUserModel> userList = userBLL.GetUserByDepId(ref pager, str, "");
foreach (SysUserModel userModel in userList)
{
userModelList.Add(userModel.Id);
}
}
}
else if (model.FlowRule == "人员")
{
string[] array = model.Execution.Split(',');//获得领导,可能有多个领导
foreach (string str in array)
{
userModelList.Add(str);
}
}
else if (model.FlowRule == "自选")
{
string users  = formContentBLL.GetById(formContentId).CustomMember;
string[] array = users.Split(',');//获得领导,可能有多个领导
foreach (string str in array)
{
userModelList.Add(str);
}
}
return userModelList;
}

获取人员代码

代码分析:

1.填充表单内容Flow_FormContent

2.获得表单步骤Flow_Step

3.根据步骤获得Flow_StepRule

4.取得判断流程方向的标示(是否结束)

5.插入审批人

需要慢慢消化,分解过程比较复杂

作者:YmNets
出处:http://ymnets.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

[转载]PHP底层的运行机制与原理 - 北京流浪儿 - 博客园

mikel阅读(961)

来源: [转载]PHP底层的运行机制与原理 – 北京流浪儿 – 博客园

PHP入门很简单,但是要精通也不是一件简单的事。我们除了会使用之外,还得知道它底层的工作原理。

PHP是一种适用于web开发的动态语言。具体点说,就是一个用C语言实现包含大量组件的软件框架。更狭义点看,可以把它认为是一个强大的UI框架。

了解PHP底层实现的目的是什么?动态语言要像用好首先得了解它,内存管理、框架模型值得我们借鉴,通过扩展开发实现更多更强大的功能,优化我们程序的性能。

1. PHP的设计理念及特点

多进程模型:由于PHP是多进程模型,不同请求间互不干涉,这样保证了一个请求挂掉不会对全盘服务造成影响,当然,随着时代发展,PHP也早已支持多线程模型。

弱类型语言:和C/C++、Java、C#等语言不同,PHP是一门弱类型语言。一个变量的类型并不是一开始就确定不变,运行中才会确定并可能发生隐式或显式的类型转换,这种机制的灵活性在web开发中非常方便、高效,具体会在后面PHP变量中详述。

引擎(Zend)+组件(ext)的模式降低内部耦合。

中间层(sapi)隔绝web server和PHP。

语法简单灵活,没有太多规范。缺点导致风格混杂,但再差的程序员也不会写出太离谱危害全局的程序。

2. PHP的四层体系

PHP的核心架构如下图:

从图上可以看出,PHP从下到上是一个4层体系:

Zend引擎:Zend整体用纯C实现,是PHP的内核部分,它将PHP代码翻译(词法、语法解析等一系列编译过程)为可执行opcode的处理并 实现相应的处理方法、实现了基本的数据结构(如hashtable、oo)、内存分配及管理、提供了相应的api方法供外部调用,是一切的核心,所 有的外围功能均围绕Zend实现。

Extensions:围绕着Zend引擎,extensions通过组件式的方式提供各种基础服务,我们常见的各种内置函数(如array系 列)、标准库等都是通过extension来实现,用户也可以根据需要实现自己的extension以达到功能扩展、性能优化等目的(如贴吧正在使用的 PHP中间层、富文本解析就是extension的典型应用)。

Sapi:Sapi全称是Server Application Programming Interface,也就是服务端应用编程接口,Sapi通过一系列钩子函数,使得PHP可以和外围交互数据,这是PHP非常优雅和成功的一个设计,通过 sapi成功的将PHP本身和上层应用解耦隔离,PHP可以不再考虑如何针对不同应用进行兼容,而应用本身也可以针对自己的特点实现不同的处理方式。

上层应用:这就是我们平时编写的PHP程序,通过不同的sapi方式得到各种各样的应用模式,如通过webserver实现web应用、在命令行下以脚本方式运行等等。

如 果PHP是一辆车,那么车的框架就是PHP本身,Zend是车的引擎(发动机),Ext下面的各种组件就是车的轮子,Sapi可以看做是公路,车可以跑在 不同类型的公路上,而一次PHP程序的执行就是汽车跑在公路上。因此,我们需要:性能优异的引擎+合适的车轮+正确的跑道。

3. Sapi

如前所述,Sapi通过通过一系列的接口,使得外部应用可以和PHP交换数据并可以根据不同应用特点实现特定的处理方法,我们常见的一些sapi有:

apache2handler:这是以apache作为webserver,采用mod_PHP模式运行时候的处理方式,也是现在应用最广泛的一种。

cgi:这是webserver和PHP直接的另一种交互方式,也就是大名鼎鼎的fastcgi协议,在最近今年fastcgi+PHP得到越来越多的应用,也是异步webserver所唯一支持的方式。

cli:命令行调用的应用模式

4. PHP的执行流程&opcode

我们先来看看PHP代码的执行所经过的流程。

从图上可以看到,PHP实现了一个典型的动态语言执行过程:拿到一段代码后,经过词法解析、语法解析等阶段后,源程序会被翻译成一个个指令 (opcodes),然后ZEND虚拟机顺次执行这些指令完成操作。PHP本身是用C实现的,因此最终调用的也都是C的函数,实际上,我们可以把PHP看 做是一个C开发的软件。

PHP的执行的核心是翻译出来的一条一条指令,也即opcode。Opcode是PHP程序执行的最基本单位。一个opcode由两个参数(op1,op2)、返回值和处理函数组成。PHP程序最终被翻译为一组opcode处理函数的顺序执行。

常见的几个处理函数:

(1) ZEND_ASSIGN_SPEC_CV_CV_HANDLER : 变量分配 ($a=$b)

(2) ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER:函数调用

(3) ZEND_CONCAT_SPEC_CV_CV_HANDLER:字符串拼接 $a.$b

(4) ZEND_ADD_SPEC_CV_CONST_HANDLER: 加法运算 $a+2

(5) ZEND_IS_EQUAL_SPEC_CV_CONST:判断相等 $a==1

(6) ZEND_IS_IDENTICAL_SPEC_CV_CONST:判断相等 $a===1

5. HashTable — 核心数据结构

HashTable是zend的核心数据结构,在PHP里面几乎并用来实现所有常见功能,我们知道的PHP数组即是其典型应用,此外,在zend内部,如函数符号表、全局变量等也都是基于hash table来实现。

PHP的hash table具有如下特点:

支持典型的key->value查询

可以当做数组使用

添加、删除节点是O(1)复杂度

key支持混合类型:同时存在关联数组合索引数组

Value支持混合类型:array (“string”,2332)

支持线性遍历:如foreach

Zend hash table实现了典型的hash表散列结构,同时通过附加一个双向链表,提供了正向、反向遍历数组的功能。其结构如下图:

可以看到,在hash table中既有key->value形式的散列结构,也有双向链表模式,使得它能够非常方便的支持快速查找和线性遍历。

散列结构:Zend的散列结构是典型的hash表模型,通过链表的方式来解决冲突。需要注意的是zend的hash table是一个自增长的数据结构,当hash表数目满了之后,其本身会动态以2倍的方式扩容并重新元素位置。初始大小均为8。另外,在进行 key->value快速查找时候,zend本身还做了一些优化,通过空间换时间的方式加快速度。比如在每个元素中都会用一个变量 nKeyLength标识key的长度以作快速判定。

双向链表:Zend hash table通过一个链表结构,实现了元素的线性遍历。理论上,做遍历使用单向链表就够了,之所以使用双向链表,主要目的是为了快速删除,避免遍历。 Zend hash table是一种复合型的结构,作为数组使用时,即支持常见的关联数组也能够作为顺序索引数字来使用,甚至允许2者的混合。

PHP关联数组:关联数组是典型的hash_table应用。一次查询过程经过如下几步(从代码可以看出,这是一个常见的hash查询过程并增加一些快速判定加速查找。

getKeyHashValue h;
index = n & nTableMask;
Bucket *p = arBucket[index];
while (p) {
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
RETURN p->data;
}
p=p->next;
}
RETURN FALTURE;

PHP 索引数组:索引数组就是我们常见的数组,通过下标访问。例如 $arr[0],Zend HashTable内部进行了归一化处理,对于index类型key同样分配了hash值和nKeyLength(为0)。内部成员变量 nNextFreeElement就是当前分配到的最大id,每次push后自动加一。正是这种归一化处理,PHP才能够实现关联和非关联的混合。由于 push操作的特殊性,索引key在PHP数组中先后顺序并不是通过下标大小来决定,而是由push的先后决定。例如 $arr[1] = 2; $arr[2] = 3;对于double类型的key,Zend HashTable会将他当做索引key处理。

6. PHP变量

PHP 是一门弱类型语言,本身不严格区分变量的类型。PHP在变量申明的时候不需要指定类型。PHP在程序运行期间可能进行变量类型的隐示转换。和其他强类型语 言一样,程序中也可以进行显示的类型转换。PHP变量可以分为简单类型(int、string、bool)、集合类型(array resource object)和常量(const)。以上所有的变量在底层都是同一种结构 zval。

Zval是zend中另一个非常重要的数据结构,用来标识并实现PHP变量,其数据结构如下:

Zval主要由三部分组成:

type:指定了变量所述的类型(整数、字符串、数组等)

refcount&is_ref:用来实现引用计数(后面具体介绍)

value:核心部分,存储了变量的实际数据

Zvalue是用来保存一个变量的实际数据。因为要存储多种类型,所以zvalue是一个union,也由此实现了弱类型。

PHP变量类型和其实际存储对应关系如下:

IS_LONG   -> lvalue

IS_DOUBLE -> dvalue

IS_ARRAY  -> ht

IS_STRING -> str

IS_RESOURCE -> lvalue

引用计数在内存回收、字符串操作等地方使用非常广泛。PHP中的变量就是引用计数的典型应用。Zval的引用计数通过成员变量is_ref和ref_count实现,通过引用计数,多个变量可以共享同一份数据。避免频繁拷贝带来的大量消耗。

在进行赋值操作时,zend将变量指向相同的zval同时ref_count++,在unset操作时,对应的ref_count-1。只有ref_count减为0时才会真正执行销毁操作。如果是引用赋值,则zend会修改is_ref为1。

PHP 变量通过引用计数实现变量共享数据,那如果改变其中一个变量值呢?当试图写入一个变量时,Zend若发现该变量指向的zval被多个变量共享,则为其复制 一份ref_count为1的zval,并递减原zval的refcount,这个过程称为“zval分离”。可见,只有在有写操作发生时 zend才进行拷贝操作,因此也叫copy-on-write(写时拷贝)

对于引用型变量,其要求和非引用型相反,引用赋值的变量间必须是捆绑的,修改一个变量就修改了所有捆绑变量。

整数、浮点数是PHP中的基础类型之一,也是一个简单型变量。对于整数和浮点数,在zvalue中直接存储对应的值。其类型分别是long和double。

从 zvalue结构中可以看出,对于整数类型,和c等强类型语言不同,PHP是不区分int、unsigned int、long、long long等类型的,对它来说,整数只有一种类型也就是long。由此,可以看出,在PHP里面,整数的取值范围是由编译器位数来决定而不是固定不变的。

对于浮点数,类似整数,它也不区分float和double而是统一只有double一种类型。

在PHP中,如果整数范围越界了怎么办?这种情况下会自动转换为double类型,这个一定要小心,很多trick都是由此产生。

和 整数一样,字符变量也是PHP中的基础类型和简单型变量。通过zvalue结构可以看出,在PHP中,字符串是由由指向实际数据的指针和长度结 构体组成,这点和c++中的string比较类似。由于通过一个实际变量表示长度,和c不同,它的字符串可以是2进制数据(包含\0),同时在PHP中, 求字符串长度strlen是O(1)操作。

在新增、修改、追加字符串操作时,PHP都会重新分配内存生成新的字符串。最后,出于安全考虑,PHP在生成一个字符串时末尾仍然会添加\0

常见的字符串拼接方式及速度比较:

假设有如下4个变量:

$strA=‘123’; $strB = ‘456’; $intA=123; intB=456;

现在对如下的几种字符串拼接方式做一个比较和说明:

(1)$res = $strA.$strB 和 $res = “$strA$strB”

这种情况下,zend会重新malloc一块内存并进行相应处理,其速度一般。

(2)$strA = $strA.$strB

这种是速度最快的,zend会在当前strA基础上直接relloc,避免重复拷贝。

(3)$res = $intA.$intB

这种速度较慢,因为需要做隐式的格式转换,实际编写程序中也应该注意尽量避免。

(4)$strA = sprintf (“%s%s”,$strA.$strB);

这会是最慢的一种方式,因为sprintf在PHP中并不是一个语言结构,本身对于格式识别和处理就需要耗费比较多时间,另外本身机制也是malloc。不过sprintf的方式最具可读性,实际中可以根据具体情况灵活选择。

PHP的数组通过Zend HashTable来天然实现。

foreach 操作如何实现?对一个数组的foreach就是通过遍历hashtable中的双向链表完成。对于索引数组,通过foreach遍 历效率比for高很多,省去了key->value的查找。count操作直接调用 HashTable->NumOfElements,O(1)操作。对于’123’这样的字符串,zend会转换为其整数形 式。$arr[‘123’]和$arr[123]是等价的。

资源类型变量是PHP中最复杂的一种变量,也是一种复合型结构。

PHP的zval可以表示广泛的数据类型,但是对于自定义的数据类型却很难充分描述。由于没有有效的方式描绘这些复合结构,因此也没有办法对它们使用传统的操作符。要解决这个问题,只需要通过一个本质上任意的标识符(label)引用指针,这种方式被称为资源。

在zval中,对于resource,lval作为指针来使用,直接指向资源所在的地址。Resource可以是任意的复合结构,我们熟悉的mySQLi、fsock、memcached等都是资源。

如何使用资源:

注册:对于一个自定义的数据类型,要想将它作为资源。首先需要进行注册,zend会为它分配全局唯一标示。

获取一个资源变量:对于资源,zend维护了一个id->实际数据的hash_tale。对于一个resource,在zval中只记录了它的id。fetch的时候通过id在hash_table中找到具体的值返回。

资源销毁:资源的数据类型是多种多样的。Zend本身没有办法销毁它。因此需要用户在注册资源的时候提供销毁函数。当unset资源时,zend调用相应的函数完成析构。同时从全局资源表中删除它。

资 源可以长期驻留,不只是在所有引用它的变量超出作用域之后,甚至是在一个请求结束了并且新的请求产生之后。这些资源称为持久资源,因为它们贯通SAPI的 整个生命周期持续存在,除非特意销毁。很多情况下,持久化资源可以在一定程度上提高性能。比如我们常见的mySQL_pconnect ,持久化资源通过pemalloc分配内存,这样在请求结束的时候不会释放。 对zend来说,对两者本身并不区分。

PHP中的局部变 量和全局变量是如何实现的?对于一个请求,任意时刻PHP都可以看到两个符号表(symbol_table和active_symbol_table), 其中前者用来维护全局变量。后者是一个指针,指向当前活动的变量符号表,当程序进入到某个函数中时,zend 就会为它分配一个符号表x同时将active_symbol_table指向a。通过这样的方式实现全局、局部变量的区分。

获取变量值:PHP的符号表是通过hash_table实现的,对于每个变量都分配唯一标识,获取的时候根据标识从表中找到相应zval返回。

函数中使用全局变量:在函数中,我们可以通过显式申明global来使用全局变量。在active_symbol_table中创建symbol_table中同名变量的引用,如果symbol_table中没有同名变量则会先创建。

 

转载自:http://www.phpernote.com/php-function/839.html

创业的都怎么了

mikel阅读(905)

没创业的想创业,创了业的都骂创业不是人能承受的。

这都到底怎么了?!

互联网+下国家和社会都在鼓励大众创业,难道是又要创出几个马云来提高gdp?!股市创业版风起云涌的同时多少泡沫多少虚高?!

人心惶惶的创业大潮下,多少是被创业的,又有多少是成功的?!不上市就不算成功,没到融资就项目不行。可怜的创业者疲于奔命的夹缝中生存得多么痛苦。

慢下来想想自己真的非得创业不可?!

人穷志短

mikel阅读(1152)

没钱,人在做事的时候就畏首畏尾。

当发现一切都要钱去做的时候,总感觉自己这么多年白活了!

人穷志短!

报价的艺术

mikel阅读(791)

不一定报的低或高都能谈成项目,报价和定价是门艺术。

越高越好自然卖家高兴,但是买家不接受也是竹篮打水一场空。所以说如何让客户觉得值,就要有详细的项目评估和成本核算,然后是结合客户的情况调整。

报低了,别人觉得你的产品是地摊货,还能压价。

报高了,产品要有过硬的竞争力才能最终胜出,否则也不行。

资金流动节奏决定收益

mikel阅读(1062)

每个项目的资金回款周期都是有节奏的。

这个节奏就是收益的节奏,就像音乐一样,要有规律才动听

此页面重定向不正确 Firefox 检测到该服务器正在将此地址的请求循环重定向

mikel阅读(1052)

此页面重定向不正确 Firefox 检测到该服务器正在将此地址的请求循环重定向.

“此页面重定向不正确

Firefox 检测到该服务器正在将此地址的请求循环重定向。

* 此问题可能是因为禁用或拒绝 Cookie 导致。”

有时候用火狐(firefox)上午访问的好好的,下午再访问同一页面时,就报上面的错误。用IE访问可能是正常的。出现此错误,是Cookie导致的。相关技术可以到网上搜索。
这里介绍解决办法:清除相应站点的Cookie就可以了。

这里以清除起点(qidian.com)的Cookie为例:
1、选择工具->选项
2、点击进入隐私标签页,再点击显示Cookie按钮
3、在跳出的Cookies对话框中,在搜索输入框中输入”qidian.com”(如果是清除163的就输入163.com),下面会自动显示电脑上存储的起点站点的Cookie信息
4、将其全选(点开头第一条,然后拉到最后,shift选最后一条)
5、点击移除Cookie按钮
当然不嫌麻烦的话也可以清除所有的COOKIE信息。

现在回到出现错误的页面,重试一下,OK,页面正常了。我估计这个错误,是相关的版面进行了更新,更新后的内容用到的COOKIE信息与用户机器上存储的信息出现了冲突导致的。

xcode项目改名

mikel阅读(842)

总会遇到几个项目,在做到一半的时候被要求改项目名,网上找了下相关的资料,大多数是xcode5以前的版本,所以解决好了在这里mark一下,给需要的人。

目标为:将项目名XCD4改成xcd5。

先上结果图:==》

1.在左侧的导航区域点击两次项目名,两次间隔时间稍微长些,项目名会变成可编辑状态。

将名称修改为xcd5后按enter键弹出一个对话框,这个时候放心的点击Rename就好了,在随后弹出的对话框中点击Enable、OK,第一步完成。

2.点击product==>Scheme==>Manage Schemes, 在随后弹出的窗口修改项目的Schemes属性。

同样双击XCD4,两次间隔稍微长些,待激活后修改名称为xcd5,修改完后点击空白处再点击ok键确认。

修改成功后会如下图所示:

3.在导航区域中右键名位XCD4的文件组,选中Show in Finder,在弹出的Finder中修改XCD4为xcd5。

返回xcode界面,XCD4下面的文件都变成红色字样的文件,所以选中XCD4文件组,在检查器中修改他的name属性为xcd5,再点击Location下面的一个很小的文件夹图片,选中刚才在Finder下修改为xcd5的文件夹。红色文字消失。

4.用同样的方法修改XCD4Tests为xcd5Tests。选中xcd5Tests文件组下面的XCD4Tests.m文件,在@interface行选中XCD4Tests右键Refactor==>Rename,如图所示。

如果弹出提示框说找不到XCD4Tests.m文件,就关掉项目重新打开即可。

然后点击Preview再save一下。

顺便修改下XCD4Tests.m的name属性,将它改为xcd5Tests.m。

5.运行项目,提示错误,找不到Prefix.pch文件。

点击项目,再点击Building Settings,修改Prefix Header路径,将XCD4/xcd5-Prefix.pch修改成xcd5/xcd5-Prefix.pch。

6.再次编译,又提示错误,说找不到Info.plist文件,点击Building Settings==>Packaging,修改Info.plist File路径,将XCD4/xcd5-Info.plist修改成xcd5/xcd5-Info.plist。

再次编译,测试通过,至此大功告成。

转载请注明出处:http://www.cnblogs.com/tbfirstone/p/3601541.html。

[转载]Asp.Net MVC 权限控制(三):Controller和Action级别控制 - Jetlian - 博客园

mikel阅读(882)

来源: [转载]Asp.Net MVC 权限控制(三):Controller和Action级别控制 – Jetlian – 博客园

再次在重构!这次对Controller和Action进行验证。

思路:系统有很多功能集,功能集对应很多Controller和Action角色分配很多功能集


首先构建一个基础数据:

1.功能集初始化:

<div class="container">
<div class="line number1 index0 alt2"><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number2 index1 alt1"><code class="csharp spaces">  </code><code class="csharp color1">/// 系统模块</code></div>
<div class="line number3 index2 alt2"><code class="csharp spaces">  </code><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number4 index3 alt1"><code class="csharp spaces">  </code><code class="csharp keyword">public</code> <code class="csharp keyword">class</code> <code class="csharp plain">SystemModule</code></div>
<div class="line number5 index4 alt2"><code class="csharp spaces">  </code><code class="csharp plain">{</code></div>
<div class="line number6 index5 alt1"><code class="csharp spaces">      </code><code class="csharp keyword">public</code> <code class="csharp plain">SystemModule()</code></div>
<div class="line number7 index6 alt2"><code class="csharp spaces">      </code><code class="csharp plain">{</code></div>
<div class="line number8 index7 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">this</code><code class="csharp plain">.ID = Guid.NewGuid();</code></div>
<div class="line number9 index8 alt2"><code class="csharp spaces">      </code><code class="csharp plain">}</code></div>
<div class="line number10 index9 alt1"></div>
<div class="line number11 index10 alt2"><code class="csharp spaces">      </code><code class="csharp keyword">public</code> <code class="csharp plain">Guid ID { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number12 index11 alt1"></div>
<div class="line number13 index12 alt2"><code class="csharp spaces">      </code><code class="csharp keyword">public</code> <code class="csharp keyword">string</code> <code class="csharp plain">Name { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number14 index13 alt1"></div>
<div class="line number15 index14 alt2"><code class="csharp spaces">      </code><code class="csharp keyword">public</code> <code class="csharp keyword">string</code> <code class="csharp plain">Description { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number16 index15 alt1"></div>
<div class="line number17 index16 alt2"><code class="csharp spaces">      </code><code class="csharp keyword">public</code> <code class="csharp plain">SystemModule Parent { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number18 index17 alt1"></div>
<div class="line number19 index18 alt2"><code class="csharp spaces">      </code><code class="csharp keyword">public</code> <code class="csharp plain">List&lt;SystemModuleController&gt; SystemModuleControllers { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number20 index19 alt1"></div>
<div class="line number21 index20 alt2"><code class="csharp spaces">      </code><code class="csharp keyword">public</code> <code class="csharp keyword">static</code> <code class="csharp plain">List&lt;SystemModule&gt; Init()</code></div>
<div class="line number22 index21 alt1"><code class="csharp spaces">      </code><code class="csharp plain">{</code></div>
<div class="line number23 index22 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">var</code> <code class="csharp plain">m1 = </code><code class="csharp keyword">new</code> <code class="csharp plain">SystemModule { Name = </code><code class="csharp string">"资源监测"</code> <code class="csharp plain">};</code></div>
<div class="line number24 index23 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">var</code> <code class="csharp plain">m2 = </code><code class="csharp keyword">new</code> <code class="csharp plain">SystemModule { Name = </code><code class="csharp string">"规划管理"</code> <code class="csharp plain">};</code></div>
<div class="line number25 index24 alt2"></div>
<div class="line number26 index25 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">var</code> <code class="csharp plain">c1 = </code><code class="csharp keyword">new</code> <code class="csharp plain">SystemModuleController { ControllerName = </code><code class="csharp string">"PlanManagement"</code><code class="csharp plain">, ActionName = </code><code class="csharp string">"Search"</code> <code class="csharp plain">};</code></div>
<div class="line number27 index26 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">var</code> <code class="csharp plain">c2 = </code><code class="csharp keyword">new</code> <code class="csharp plain">SystemModuleController { ControllerName = </code><code class="csharp string">"PlanManagement"</code><code class="csharp plain">, ActionName = </code><code class="csharp string">"Add"</code> <code class="csharp plain">};</code></div>
<div class="line number28 index27 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">var</code> <code class="csharp plain">c3 = </code><code class="csharp keyword">new</code> <code class="csharp plain">SystemModuleController { ControllerName = </code><code class="csharp string">"PlanManagement"</code><code class="csharp plain">, ActionName = </code><code class="csharp string">"Edit"</code> <code class="csharp plain">};</code></div>
<div class="line number29 index28 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">var</code> <code class="csharp plain">c4 = </code><code class="csharp keyword">new</code> <code class="csharp plain">SystemModuleController { ControllerName = </code><code class="csharp string">"PlanManagement"</code><code class="csharp plain">, ActionName = </code><code class="csharp string">"Delete"</code> <code class="csharp plain">};</code></div>
<div class="line number30 index29 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">var</code> <code class="csharp plain">c5 = </code><code class="csharp keyword">new</code> <code class="csharp plain">SystemModuleController { ControllerName = </code><code class="csharp string">"PlanManagement"</code><code class="csharp plain">, ActionName = </code><code class="csharp string">"Approval"</code> <code class="csharp plain">};</code></div>
<div class="line number31 index30 alt2"></div>
<div class="line number32 index31 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">var</code> <code class="csharp plain">m21 = </code><code class="csharp keyword">new</code> <code class="csharp plain">SystemModule { Name = </code><code class="csharp string">"规划信息查询"</code><code class="csharp plain">, Parent = m2, SystemModuleControllers = </code><code class="csharp keyword">new</code> <code class="csharp plain">List&lt;SystemModuleController&gt; { c1 } };</code></div>
<div class="line number33 index32 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">var</code> <code class="csharp plain">m22 = </code><code class="csharp keyword">new</code> <code class="csharp plain">SystemModule { Name = </code><code class="csharp string">"规划信息管理"</code><code class="csharp plain">, Parent = m2, SystemModuleControllers = </code><code class="csharp keyword">new</code> <code class="csharp plain">List&lt;SystemModuleController&gt; { c2, c3, c4 } };</code></div>
<div class="line number34 index33 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">var</code> <code class="csharp plain">m23 = </code><code class="csharp keyword">new</code> <code class="csharp plain">SystemModule { Name = </code><code class="csharp string">"规划辅助审批"</code><code class="csharp plain">, Parent = m2, SystemModuleControllers = </code><code class="csharp keyword">new</code> <code class="csharp plain">List&lt;SystemModuleController&gt; { c5 } };</code></div>
<div class="line number35 index34 alt2"></div>
<div class="line number36 index35 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">return</code> <code class="csharp keyword">new</code> <code class="csharp plain">List&lt;SystemModule&gt; { m1, m2, m12, m21, m22, m23 };</code></div>
<div class="line number37 index36 alt2"><code class="csharp spaces">      </code><code class="csharp plain">}</code></div>
<div class="line number38 index37 alt1"><code class="csharp spaces">  </code><code class="csharp plain">}</code></div>
<div class="line number38 index37 alt1">
2.角色初始化:
</div>
<div class="line number38 index37 alt1">
<div class="container">
<div class="line number1 index0 alt2"><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number2 index1 alt1"><code class="csharp color1">/// 角色</code></div>
<div class="line number3 index2 alt2"><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number4 index3 alt1"><code class="csharp keyword">public</code> <code class="csharp keyword">class</code> <code class="csharp plain">SystemRole</code></div>
<div class="line number5 index4 alt2"><code class="csharp plain">{</code></div>
<div class="line number6 index5 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp plain">SystemRole()</code></div>
<div class="line number7 index6 alt2"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number8 index7 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">this</code><code class="csharp plain">.ID = Guid.NewGuid();</code></div>
<div class="line number9 index8 alt2"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number10 index9 alt1"></div>
<div class="line number11 index10 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp plain">Guid ID { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number12 index11 alt1"></div>
<div class="line number13 index12 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp keyword">string</code> <code class="csharp plain">Name { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number14 index13 alt1"></div>
<div class="line number15 index14 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp keyword">string</code> <code class="csharp plain">Description { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number16 index15 alt1"></div>
<div class="line number17 index16 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp plain">List&lt;SystemModule&gt; SystemModules { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number18 index17 alt1"></div>
<div class="line number19 index18 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp keyword">static</code> <code class="csharp plain">SystemRole Init(</code><code class="csharp keyword">string</code><code class="csharp plain">[] roles)</code></div>
<div class="line number20 index19 alt1"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number21 index20 alt2"><code class="csharp spaces">        </code><code class="csharp keyword">var</code> <code class="csharp plain">modules = SystemModule.Init();</code></div>
<div class="line number22 index21 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">var</code> <code class="csharp plain">systemModules = roles.Select(r =&gt; modules.FirstOrDefault(m =&gt; m.Name == r)).ToList();</code></div>
<div class="line number23 index22 alt2"><code class="csharp spaces">        </code><code class="csharp keyword">var</code> <code class="csharp plain">role = </code><code class="csharp keyword">new</code> <code class="csharp plain">SystemRole { Name = </code><code class="csharp string">"默认角色"</code><code class="csharp plain">, SystemModules = systemModules };</code></div>
<div class="line number24 index23 alt1"></div>
<div class="line number25 index24 alt2"><code class="csharp spaces">        </code><code class="csharp keyword">return</code> <code class="csharp plain">role;</code></div>
<div class="line number26 index25 alt1"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number27 index26 alt2"><code class="csharp plain">}</code></div>
<div class="line number27 index26 alt2">
3. 系统所有Controller和Action的读取
</div>
<div class="line number27 index26 alt2">
<div class="container">
<div class="line number1 index0 alt2"><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number2 index1 alt1"><code class="csharp spaces">   </code><code class="csharp color1">/// 读取系统的所有Controller和Action</code></div>
<div class="line number3 index2 alt2"><code class="csharp spaces">   </code><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number4 index3 alt1"><code class="csharp spaces">   </code><code class="csharp keyword">public</code><code class="csharp keyword">class</code><code class="csharp plain">SystemModuleController</code></div>
<div class="line number5 index4 alt2"><code class="csharp spaces">   </code><code class="csharp plain">{</code></div>
<div class="line number6 index5 alt1"><code class="csharp spaces">       </code><code class="csharp keyword">public</code><code class="csharp plain">SystemModuleController()</code></div>
<div class="line number7 index6 alt2"><code class="csharp spaces">       </code><code class="csharp plain">{</code></div>
<div class="line number8 index7 alt1"><code class="csharp spaces">           </code><code class="csharp keyword">this</code><code class="csharp plain">.ID = Guid.NewGuid();</code></div>
<div class="line number9 index8 alt2"><code class="csharp spaces">       </code><code class="csharp plain">}</code></div>
<div class="line number11 index10 alt2"><code class="csharp spaces">       </code><code class="csharp keyword">public</code><code class="csharp plain">Guid ID { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number13 index12 alt2"><code class="csharp spaces">       </code><code class="csharp keyword">public</code><code class="csharp keyword">string</code><code class="csharp plain">ModuleName { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number15 index14 alt2"><code class="csharp spaces">       </code><code class="csharp keyword">public</code><code class="csharp keyword">string</code><code class="csharp plain">ControllerName { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number17 index16 alt2"><code class="csharp spaces">       </code><code class="csharp keyword">public</code><code class="csharp keyword">string</code><code class="csharp plain">ActionName { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number19 index18 alt2"><code class="csharp spaces">       </code><code class="csharp keyword">public</code><code class="csharp keyword">string</code><code class="csharp plain">Description { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number21 index20 alt2"><code class="csharp spaces">       </code><code class="csharp keyword">public</code><code class="csharp plain">List&lt;SystemModuleController&gt; SystemModuleActions { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">set</code><code class="csharp plain">; }</code></div>
<div class="line number23 index22 alt2"><code class="csharp spaces">       </code><code class="csharp keyword">public</code><code class="csharp keyword">static</code><code class="csharp plain">List&lt;SystemModuleController&gt; GetSystemModuleController()</code></div>
<div class="line number24 index23 alt1"><code class="csharp spaces">       </code><code class="csharp plain">{</code></div>
<div class="line number25 index24 alt2"><code class="csharp spaces">           </code><code class="csharp keyword">var</code><code class="csharp plain">systemModuleControllers = </code><code class="csharp keyword">new</code><code class="csharp plain">List&lt;SystemModuleController&gt;();</code></div>
<div class="line number26 index25 alt1"><code class="csharp spaces">           </code><code class="csharp comments">// 读取项目中的Controller</code></div>
<div class="line number27 index26 alt2"><code class="csharp spaces">           </code><code class="csharp keyword">var</code><code class="csharp plain">types = Assembly.Load(</code><code class="csharp string">"PRMMS.Authorization"</code><code class="csharp plain">).GetTypes().Where(b =&gt; b.BaseType != </code><code class="csharp keyword">null</code><code class="csharp plain">&amp;&amp; b.BaseType.Name == </code><code class="csharp string">"BaseController"</code><code class="csharp plain">);</code></div>
<div class="line number28 index27 alt1"><code class="csharp spaces">           </code><code class="csharp keyword">foreach</code><code class="csharp plain">(</code><code class="csharp keyword">var</code><code class="csharp plain">type </code><code class="csharp keyword">in</code><code class="csharp plain">types)</code></div>
<div class="line number29 index28 alt2"><code class="csharp spaces">           </code><code class="csharp plain">{</code></div>
<div class="line number30 index29 alt1"><code class="csharp spaces">               </code><code class="csharp comments">// 标记需要权限验证的Controller</code></div>
<div class="line number31 index30 alt2"><code class="csharp spaces">               </code><code class="csharp keyword">var</code><code class="csharp plain">modules = type.GetCustomAttributes(</code><code class="csharp keyword">typeof</code><code class="csharp plain">(ModuleAuthorizationAttribute), </code><code class="csharp keyword">true</code><code class="csharp plain">);</code></div>
<div class="line number32 index31 alt1"><code class="csharp spaces">               </code><code class="csharp keyword">if</code><code class="csharp plain">(modules.Length == 1)</code></div>
<div class="line number33 index32 alt2"><code class="csharp spaces">               </code><code class="csharp plain">{</code></div>
<div class="line number34 index33 alt1"><code class="csharp spaces">                   </code><code class="csharp comments">// Controller名称</code></div>
<div class="line number35 index34 alt2"><code class="csharp spaces">                   </code><code class="csharp keyword">var</code><code class="csharp plain">controllerName = type.Name.Replace(</code><code class="csharp string">"Controller"</code><code class="csharp plain">, </code><code class="csharp string">""</code><code class="csharp plain">);</code></div>
<div class="line number36 index35 alt1"><code class="csharp spaces">                   </code><code class="csharp comments">// Controller描述</code></div>
<div class="line number37 index36 alt2"><code class="csharp spaces">                   </code><code class="csharp keyword">var</code><code class="csharp plain">description = </code><code class="csharp keyword">string</code><code class="csharp plain">.Empty;</code></div>
<div class="line number38 index37 alt1"><code class="csharp spaces">                   </code><code class="csharp keyword">var</code><code class="csharp plain">attrs = type.GetCustomAttributes(</code><code class="csharp keyword">typeof</code><code class="csharp plain">(System.ComponentModel.DescriptionAttribute), </code><code class="csharp keyword">true</code><code class="csharp plain">);</code></div>
<div class="line number39 index38 alt2"><code class="csharp spaces">                   </code><code class="csharp keyword">if</code><code class="csharp plain">(attrs.Length &gt; 0)</code></div>
<div class="line number40 index39 alt1"><code class="csharp spaces">                   </code><code class="csharp plain">{</code></div>
<div class="line number41 index40 alt2"><code class="csharp spaces">                       </code><code class="csharp plain">description = (attrs[0] </code><code class="csharp keyword">as</code><code class="csharp plain">System.ComponentModel.DescriptionAttribute).Description;</code></div>
<div class="line number42 index41 alt1"><code class="csharp spaces">                   </code><code class="csharp plain">}</code></div>
<div class="line number44 index43 alt1"><code class="csharp spaces">                   </code><code class="csharp comments">// 获取Controller下的Action</code></div>
<div class="line number45 index44 alt2"><code class="csharp spaces">                   </code><code class="csharp keyword">var</code><code class="csharp plain">systemModuleControllerAction = </code><code class="csharp keyword">new</code><code class="csharp plain">List&lt;SystemModuleController&gt;();</code></div>
<div class="line number46 index45 alt1"><code class="csharp spaces">                   </code><code class="csharp keyword">var</code><code class="csharp plain">actions = type.GetMethods().Where(a =&gt; a.ReturnType != </code><code class="csharp keyword">null</code><code class="csharp plain">&amp;&amp; a.ReturnType.Name == </code><code class="csharp string">"ActionResult"</code><code class="csharp plain">);</code></div>
<div class="line number47 index46 alt2"><code class="csharp spaces">                   </code><code class="csharp keyword">foreach</code><code class="csharp plain">(</code><code class="csharp keyword">var</code><code class="csharp plain">action </code><code class="csharp keyword">in</code><code class="csharp plain">actions)</code></div>
<div class="line number48 index47 alt1"><code class="csharp spaces">                   </code><code class="csharp plain">{</code></div>
<div class="line number49 index48 alt2"><code class="csharp spaces">                       </code><code class="csharp comments">// Action名称</code></div>
<div class="line number50 index49 alt1"><code class="csharp spaces">                       </code><code class="csharp keyword">var</code><code class="csharp plain">actionName = action.Name;</code></div>
<div class="line number51 index50 alt2"><code class="csharp spaces">                       </code><code class="csharp comments">// Action描述</code></div>
<div class="line number52 index51 alt1"><code class="csharp spaces">                       </code><code class="csharp keyword">var</code><code class="csharp plain">desc = </code><code class="csharp keyword">string</code><code class="csharp plain">.Empty;</code></div>
<div class="line number53 index52 alt2"><code class="csharp spaces">                       </code><code class="csharp keyword">var</code><code class="csharp plain">act = action.GetCustomAttributes(</code><code class="csharp keyword">typeof</code><code class="csharp plain">(System.ComponentModel.DescriptionAttribute), </code><code class="csharp keyword">true</code><code class="csharp plain">);</code></div>
<div class="line number54 index53 alt1"><code class="csharp spaces">                       </code><code class="csharp keyword">if</code><code class="csharp plain">(act.Length &gt; 0)</code></div>
<div class="line number55 index54 alt2"><code class="csharp spaces">                       </code><code class="csharp plain">{</code></div>
<div class="line number56 index55 alt1"><code class="csharp spaces">                           </code><code class="csharp plain">desc = (act[0] </code><code class="csharp keyword">as</code><code class="csharp plain">System.ComponentModel.DescriptionAttribute).Description;</code></div>
<div class="line number57 index56 alt2"><code class="csharp spaces">                       </code><code class="csharp plain">}</code></div>
<div class="line number58 index57 alt1"><code class="csharp spaces">                       </code><code class="csharp plain">systemModuleControllerAction.Add(</code><code class="csharp keyword">new</code><code class="csharp plain">SystemModuleController</code></div>
<div class="line number59 index58 alt2"><code class="csharp spaces">                                                            </code><code class="csharp plain">{</code></div>
<div class="line number60 index59 alt1"><code class="csharp spaces">                                                                </code><code class="csharp plain">ControllerName = controllerName,</code></div>
<div class="line number61 index60 alt2"><code class="csharp spaces">                                                                </code><code class="csharp plain">ActionName = actionName,</code></div>
<div class="line number62 index61 alt1"><code class="csharp spaces">                                                                </code><code class="csharp plain">Description = desc</code></div>
<div class="line number63 index62 alt2"><code class="csharp spaces">                                                            </code><code class="csharp plain">});</code></div>
<div class="line number64 index63 alt1"><code class="csharp spaces">                   </code><code class="csharp plain">}</code></div>
<div class="line number66 index65 alt1"><code class="csharp spaces">                   </code><code class="csharp keyword">var</code><code class="csharp plain">systemModule = </code><code class="csharp keyword">new</code><code class="csharp plain">SystemModuleController</code></div>
<div class="line number67 index66 alt2"><code class="csharp spaces">                   </code><code class="csharp plain">{</code></div>
<div class="line number68 index67 alt1"><code class="csharp spaces">                       </code><code class="csharp plain">ControllerName = controllerName,</code></div>
<div class="line number69 index68 alt2"><code class="csharp spaces">                       </code><code class="csharp plain">Description = description,</code></div>
<div class="line number70 index69 alt1"><code class="csharp spaces">                       </code><code class="csharp plain">SystemModuleActions = systemModuleControllerAction</code></div>
<div class="line number71 index70 alt2"><code class="csharp spaces">                   </code><code class="csharp plain">};</code></div>
<div class="line number72 index71 alt1"><code class="csharp spaces">                   </code><code class="csharp plain">systemModuleControllers.Add(systemModule);</code></div>
<div class="line number73 index72 alt2"><code class="csharp spaces">               </code><code class="csharp plain">}</code></div>
<div class="line number74 index73 alt1"><code class="csharp spaces">           </code><code class="csharp plain">}</code></div>
<div class="line number75 index74 alt2"><code class="csharp spaces">           </code><code class="csharp keyword">return</code><code class="csharp plain">systemModuleControllers;</code></div>
<div class="line number76 index75 alt1"><code class="csharp spaces">       </code><code class="csharp plain">}</code></div>
<div class="line number77 index76 alt2"><code class="csharp spaces">   </code><code class="csharp plain">}</code></div>
<div class="line number77 index76 alt2">
系统登录后,初始化权限并保存缓存中。
</div>
<div class="line number77 index76 alt2">
<div class="container">
<div class="line number1 index0 alt2"><code class="csharp plain">[HttpPost]</code></div>
<div class="line number2 index1 alt1"><code class="csharp plain">[ValidateAntiForgeryToken]</code></div>
<div class="line number3 index2 alt2"><code class="csharp keyword">public</code> <code class="csharp plain">ActionResult Login(LoginModel model, </code><code class="csharp keyword">string</code> <code class="csharp plain">returnUrl)</code></div>
<div class="line number4 index3 alt1"><code class="csharp plain">{</code></div>
<div class="line number5 index4 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">var</code> <code class="csharp plain">userName = model.UserName;</code></div>
<div class="line number6 index5 alt1"></div>
<div class="line number7 index6 alt2"><code class="csharp spaces">    </code><code class="csharp plain">FormsAuthenticationTicket authTicket = </code><code class="csharp keyword">new</code> <code class="csharp plain">FormsAuthenticationTicket(</code></div>
<div class="line number8 index7 alt1"><code class="csharp spaces">    </code><code class="csharp plain">1,</code></div>
<div class="line number9 index8 alt2"><code class="csharp spaces">    </code><code class="csharp plain">userName,</code></div>
<div class="line number10 index9 alt1"><code class="csharp spaces">    </code><code class="csharp plain">DateTime.Now,</code></div>
<div class="line number11 index10 alt2"><code class="csharp spaces">    </code><code class="csharp plain">DateTime.Now.AddMinutes(20),</code></div>
<div class="line number12 index11 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">false</code><code class="csharp plain">,</code></div>
<div class="line number13 index12 alt2"><code class="csharp spaces">    </code><code class="csharp plain">model.Roles.Aggregate((i, j) =&gt; i + </code><code class="csharp string">","</code> <code class="csharp plain">+ j)</code></div>
<div class="line number14 index13 alt1"><code class="csharp spaces">    </code><code class="csharp plain">);</code></div>
<div class="line number15 index14 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">string</code> <code class="csharp plain">encryptedTicket = FormsAuthentication.Encrypt(authTicket);</code></div>
<div class="line number16 index15 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">var</code> <code class="csharp plain">authCookie = </code><code class="csharp keyword">new</code> <code class="csharp plain">HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);</code></div>
<div class="line number17 index16 alt2"><code class="csharp spaces">    </code><code class="csharp plain">System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);</code></div>
<div class="line number18 index17 alt1"></div>
<div class="line number19 index18 alt2"><code class="csharp spaces">    </code><code class="csharp comments">// 初始化权限</code></div>
<div class="line number20 index19 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">var</code> <code class="csharp plain">systemRole = SystemRole.Init(model.Roles);</code></div>
<div class="line number21 index20 alt2"><code class="csharp spaces">    </code><code class="csharp comments">// 缓存权限</code></div>
<div class="line number22 index21 alt1"><code class="csharp spaces">    </code><code class="csharp plain">AccountHelper.AddCache(systemRole.SystemModules);</code></div>
<div class="line number23 index22 alt2"></div>
<div class="line number24 index23 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">return</code> <code class="csharp plain">RedirectToAction(</code><code class="csharp string">"Index"</code><code class="csharp plain">, </code><code class="csharp string">"Home"</code><code class="csharp plain">);</code></div>
<div class="line number25 index24 alt2"><code class="csharp plain">}</code></div>
<div class="line number25 index24 alt2">
AccountHelper:
</div>
<div class="line number25 index24 alt2">
<div class="container">
<div class="line number1 index0 alt2"><code class="csharp keyword">public</code> <code class="csharp keyword">class</code> <code class="csharp plain">AccountHelper</code></div>
<div class="line number2 index1 alt1"><code class="csharp plain">{</code></div>
<div class="line number3 index2 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">private</code> <code class="csharp keyword">const</code> <code class="csharp keyword">string</code> <code class="csharp plain">CacheName = </code><code class="csharp string">"SystemModules"</code><code class="csharp plain">;</code></div>
<div class="line number4 index3 alt1"></div>
<div class="line number5 index4 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number6 index5 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// 获取用户信息</code></div>
<div class="line number7 index6 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number8 index7 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;returns&gt;&lt;/returns&gt;</code></div>
<div class="line number9 index8 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp keyword">static</code> <code class="csharp plain">FormsAuthenticationTicket GetCookieUser()</code></div>
<div class="line number10 index9 alt1"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number11 index10 alt2"><code class="csharp spaces">        </code><code class="csharp plain">HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];</code></div>
<div class="line number12 index11 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">if</code> <code class="csharp plain">(authCookie == </code><code class="csharp keyword">null</code> <code class="csharp plain">|| authCookie.Value == </code><code class="csharp string">""</code><code class="csharp plain">)</code></div>
<div class="line number13 index12 alt2"><code class="csharp spaces">        </code><code class="csharp plain">{</code></div>
<div class="line number14 index13 alt1"><code class="csharp spaces">            </code><code class="csharp keyword">return</code> <code class="csharp keyword">null</code><code class="csharp plain">;</code></div>
<div class="line number15 index14 alt2"><code class="csharp spaces">        </code><code class="csharp plain">}</code></div>
<div class="line number16 index15 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">try</code></div>
<div class="line number17 index16 alt2"><code class="csharp spaces">        </code><code class="csharp plain">{</code></div>
<div class="line number18 index17 alt1"><code class="csharp spaces">            </code><code class="csharp keyword">return</code> <code class="csharp plain">FormsAuthentication.Decrypt(authCookie.Value);</code></div>
<div class="line number19 index18 alt2"><code class="csharp spaces">        </code><code class="csharp plain">}</code></div>
<div class="line number20 index19 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">catch</code> <code class="csharp plain">(Exception ex)</code></div>
<div class="line number21 index20 alt2"><code class="csharp spaces">        </code><code class="csharp plain">{</code></div>
<div class="line number22 index21 alt1"><code class="csharp spaces">            </code><code class="csharp keyword">return</code> <code class="csharp keyword">null</code><code class="csharp plain">;</code></div>
<div class="line number23 index22 alt2"><code class="csharp spaces">        </code><code class="csharp plain">}</code></div>
<div class="line number24 index23 alt1"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number25 index24 alt2"></div>
<div class="line number26 index25 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number27 index26 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// 添加缓存</code></div>
<div class="line number28 index27 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number29 index28 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;param name="systemModules"&gt;&lt;/param&gt;</code></div>
<div class="line number30 index29 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp keyword">static</code> <code class="csharp keyword">void</code> <code class="csharp plain">AddCache(List&lt;SystemModule&gt; systemModules)</code></div>
<div class="line number31 index30 alt2"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number32 index31 alt1"><code class="csharp spaces">        </code><code class="csharp plain">HttpContext.Current.Cache[CacheName] = systemModules;</code></div>
<div class="line number33 index32 alt2"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number34 index33 alt1"></div>
<div class="line number35 index34 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number36 index35 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// 读取缓存</code></div>
<div class="line number37 index36 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number38 index37 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;returns&gt;&lt;/returns&gt;</code></div>
<div class="line number39 index38 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp keyword">static</code> <code class="csharp plain">List&lt;SystemModule&gt; GetCache()</code></div>
<div class="line number40 index39 alt1"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number41 index40 alt2"><code class="csharp spaces">        </code><code class="csharp keyword">if</code> <code class="csharp plain">(HttpContext.Current.Cache[CacheName] == </code><code class="csharp keyword">null</code><code class="csharp plain">)</code></div>
<div class="line number42 index41 alt1"><code class="csharp spaces">        </code><code class="csharp plain">{</code></div>
<div class="line number43 index42 alt2"><code class="csharp spaces">            </code><code class="csharp comments">// 重新构建权限</code></div>
<div class="line number44 index43 alt1"><code class="csharp spaces">            </code><code class="csharp keyword">var</code> <code class="csharp plain">user = GetCookieUser();</code></div>
<div class="line number45 index44 alt2"><code class="csharp spaces">            </code><code class="csharp keyword">var</code> <code class="csharp plain">roles = user.UserData.Split(</code><code class="csharp keyword">new</code><code class="csharp plain">[] { </code><code class="csharp string">','</code> <code class="csharp plain">});</code></div>
<div class="line number46 index45 alt1"><code class="csharp spaces">            </code><code class="csharp plain">HttpContext.Current.Cache[CacheName] = SystemRole.Init(roles).SystemModules;</code></div>
<div class="line number47 index46 alt2"><code class="csharp spaces">        </code><code class="csharp plain">}</code></div>
<div class="line number48 index47 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">return</code> <code class="csharp plain">(List&lt;SystemModule&gt;)HttpContext.Current.Cache[CacheName];</code></div>
<div class="line number49 index48 alt2"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number50 index49 alt1"></div>
<div class="line number51 index50 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number52 index51 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// 验证Controller和Action</code></div>
<div class="line number53 index52 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number54 index53 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;param name="controllerName"&gt;&lt;/param&gt;</code></div>
<div class="line number55 index54 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;param name="actionName"&gt;&lt;/param&gt;</code></div>
<div class="line number56 index55 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;returns&gt;&lt;/returns&gt;</code></div>
<div class="line number57 index56 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp keyword">static</code> <code class="csharp keyword">bool</code> <code class="csharp plain">ValidatePermission(</code><code class="csharp keyword">string</code> <code class="csharp plain">controllerName, </code><code class="csharp keyword">string</code> <code class="csharp plain">actionName)</code></div>
<div class="line number58 index57 alt1"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number59 index58 alt2"><code class="csharp spaces">        </code><code class="csharp keyword">var</code> <code class="csharp plain">systemModules = GetCache();</code></div>
<div class="line number60 index59 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">foreach</code> <code class="csharp plain">(</code><code class="csharp keyword">var</code> <code class="csharp plain">systemModule </code><code class="csharp keyword">in</code> <code class="csharp plain">systemModules)</code></div>
<div class="line number61 index60 alt2"><code class="csharp spaces">        </code><code class="csharp plain">{</code></div>
<div class="line number62 index61 alt1"><code class="csharp spaces">            </code><code class="csharp keyword">if</code> <code class="csharp plain">(systemModule != </code><code class="csharp keyword">null</code> <code class="csharp plain">&amp;&amp; systemModule.SystemModuleControllers != </code><code class="csharp keyword">null</code><code class="csharp plain">)</code></div>
<div class="line number63 index62 alt2"><code class="csharp spaces">            </code><code class="csharp plain">{</code></div>
<div class="line number64 index63 alt1"><code class="csharp spaces">                </code><code class="csharp keyword">foreach</code> <code class="csharp plain">(</code><code class="csharp keyword">var</code> <code class="csharp plain">controller </code><code class="csharp keyword">in</code> <code class="csharp plain">systemModule.SystemModuleControllers)</code></div>
<div class="line number65 index64 alt2"><code class="csharp spaces">                </code><code class="csharp plain">{</code></div>
<div class="line number66 index65 alt1"><code class="csharp spaces">                    </code><code class="csharp keyword">if</code> <code class="csharp plain">(controller.ControllerName == controllerName &amp;&amp; controller.ActionName == actionName) </code><code class="csharp keyword">return</code> <code class="csharp keyword">true</code><code class="csharp plain">;</code></div>
<div class="line number67 index66 alt2"><code class="csharp spaces">                </code><code class="csharp plain">}</code></div>
<div class="line number68 index67 alt1"><code class="csharp spaces">            </code><code class="csharp plain">}</code></div>
<div class="line number69 index68 alt2"><code class="csharp spaces">        </code><code class="csharp plain">}</code></div>
<div class="line number70 index69 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">return</code> <code class="csharp keyword">false</code><code class="csharp plain">;</code></div>
<div class="line number71 index70 alt2"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number72 index71 alt1"><code class="csharp plain">}</code></div>
<div class="line number72 index71 alt1">
同样在业务的Controller添加拦截标记
</div>
<div class="line number72 index71 alt1">
<div class="container">
<div class="line number1 index0 alt2"><code class="csharp plain">[LoginAllow]</code></div>
<div class="line number2 index1 alt1"><code class="csharp plain">[PermissionFilter]</code></div>
<div class="line number3 index2 alt2"><code class="csharp keyword">public</code> <code class="csharp keyword">class</code> <code class="csharp plain">BaseController : Controller</code></div>
<div class="line number4 index3 alt1"><code class="csharp plain">{</code></div>
<div class="line number5 index4 alt2"><code class="csharp plain">}</code></div>
<div class="line number6 index5 alt1"></div>
<div class="line number7 index6 alt2"><code class="csharp plain">[Description(</code><code class="csharp string">"规划管理控制器"</code><code class="csharp plain">)]</code></div>
<div class="line number8 index7 alt1"><code class="csharp plain">[ModuleAuthorization]</code></div>
<div class="line number9 index8 alt2"><code class="csharp keyword">public</code> <code class="csharp keyword">class</code> <code class="csharp plain">PlanManagementController : BaseController</code></div>
<div class="line number10 index9 alt1"><code class="csharp plain">{</code></div>
<div class="line number11 index10 alt2"><code class="csharp spaces">    </code><code class="csharp plain">[Description(</code><code class="csharp string">"首页"</code><code class="csharp plain">)]</code></div>
<div class="line number12 index11 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp plain">ActionResult Index()</code></div>
<div class="line number13 index12 alt2"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number14 index13 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">return</code> <code class="csharp plain">View();</code></div>
<div class="line number15 index14 alt2"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number16 index15 alt1"></div>
<div class="line number17 index16 alt2"><code class="csharp spaces">    </code><code class="csharp plain">[Description(</code><code class="csharp string">"查询"</code><code class="csharp plain">)]</code></div>
<div class="line number18 index17 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp plain">ActionResult Search()</code></div>
<div class="line number19 index18 alt2"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number20 index19 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">return</code> <code class="csharp plain">View();</code></div>
<div class="line number21 index20 alt2"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number22 index21 alt1"></div>
<div class="line number23 index22 alt2"><code class="csharp spaces">    </code><code class="csharp plain">[Description(</code><code class="csharp string">"添加"</code><code class="csharp plain">)]</code></div>
<div class="line number24 index23 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp plain">ActionResult Add()</code></div>
<div class="line number25 index24 alt2"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number26 index25 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">return</code> <code class="csharp plain">View();</code></div>
<div class="line number27 index26 alt2"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number28 index27 alt1"></div>
<div class="line number29 index28 alt2"><code class="csharp spaces">    </code><code class="csharp plain">[Description(</code><code class="csharp string">"编辑"</code><code class="csharp plain">)]</code></div>
<div class="line number30 index29 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp plain">ActionResult Edit()</code></div>
<div class="line number31 index30 alt2"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number32 index31 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">return</code> <code class="csharp plain">View();</code></div>
<div class="line number33 index32 alt2"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number34 index33 alt1"></div>
<div class="line number35 index34 alt2"><code class="csharp spaces">    </code><code class="csharp plain">[Description(</code><code class="csharp string">"删除"</code><code class="csharp plain">)]</code></div>
<div class="line number36 index35 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp plain">ActionResult Delete()</code></div>
<div class="line number37 index36 alt2"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number38 index37 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">return</code> <code class="csharp plain">View();</code></div>
<div class="line number39 index38 alt2"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number40 index39 alt1"></div>
<div class="line number41 index40 alt2"><code class="csharp spaces">    </code><code class="csharp plain">[Description(</code><code class="csharp string">"审批"</code><code class="csharp plain">)]</code></div>
<div class="line number42 index41 alt1"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp plain">ActionResult Approval()</code></div>
<div class="line number43 index42 alt2"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number44 index43 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">return</code> <code class="csharp plain">View();</code></div>
<div class="line number45 index44 alt2"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number46 index45 alt1"><code class="csharp plain">}</code></div>
<div class="line number46 index45 alt1">
拦截器:PermissionFilterAttribute
</div>
<div class="line number46 index45 alt1">
<div class="container">
<div class="line number1 index0 alt2"><code class="csharp plain">[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = </code><code class="csharp keyword">false</code><code class="csharp plain">)]</code></div>
<div class="line number2 index1 alt1"><code class="csharp spaces">  </code><code class="csharp keyword">public</code> <code class="csharp keyword">class</code> <code class="csharp plain">PermissionFilterAttribute : ActionFilterAttribute</code></div>
<div class="line number3 index2 alt2"><code class="csharp spaces">  </code><code class="csharp plain">{</code></div>
<div class="line number4 index3 alt1"><code class="csharp spaces">      </code><code class="csharp comments">// OnActionExecuted 在执行操作方法后由 ASP.NET MVC 框架调用。</code></div>
<div class="line number5 index4 alt2"><code class="csharp spaces">      </code><code class="csharp comments">// OnActionExecuting 在执行操作方法之前由 ASP.NET MVC 框架调用。</code></div>
<div class="line number6 index5 alt1"><code class="csharp spaces">      </code><code class="csharp comments">// OnResultExecuted 在执行操作结果后由 ASP.NET MVC 框架调用。</code></div>
<div class="line number7 index6 alt2"><code class="csharp spaces">      </code><code class="csharp comments">// OnResultExecuting 在执行操作结果之前由 ASP.NET MVC 框架调用。</code></div>
<div class="line number8 index7 alt1"></div>
<div class="line number9 index8 alt2"></div>
<div class="line number10 index9 alt1"><code class="csharp spaces">      </code><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number11 index10 alt2"><code class="csharp spaces">      </code><code class="csharp color1">/// 在执行操作方法之前由 ASP.NET MVC 框架调用。</code></div>
<div class="line number12 index11 alt1"><code class="csharp spaces">      </code><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number13 index12 alt2"><code class="csharp spaces">      </code><code class="csharp color1">/// &lt;param name="filterContext"&gt;&lt;/param&gt;</code></div>
<div class="line number14 index13 alt1"><code class="csharp spaces">      </code><code class="csharp keyword">public</code> <code class="csharp keyword">override</code> <code class="csharp keyword">void</code> <code class="csharp plain">OnActionExecuting(ActionExecutingContext filterContext)</code></div>
<div class="line number15 index14 alt2"><code class="csharp spaces">      </code><code class="csharp plain">{</code></div>
<div class="line number16 index15 alt1"><code class="csharp spaces">          </code><code class="csharp comments">//fcinfo = new filterContextInfo(filterContext);</code></div>
<div class="line number17 index16 alt2"></div>
<div class="line number18 index17 alt1"><code class="csharp spaces">          </code><code class="csharp comments">//根据验证判断进行处理</code></div>
<div class="line number19 index18 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">if</code> <code class="csharp plain">(!</code><code class="csharp keyword">this</code><code class="csharp plain">.AuthorizeCore(filterContext))</code></div>
<div class="line number20 index19 alt1"><code class="csharp spaces">          </code><code class="csharp plain">{</code></div>
<div class="line number21 index20 alt2"><code class="csharp spaces">              </code><code class="csharp plain">filterContext.RequestContext.HttpContext.Response.Redirect(</code><code class="csharp string">"~/Account/Login"</code><code class="csharp plain">);</code></div>
<div class="line number22 index21 alt1"><code class="csharp spaces">          </code><code class="csharp plain">}</code></div>
<div class="line number23 index22 alt2"><code class="csharp spaces">      </code><code class="csharp plain">}</code></div>
<div class="line number24 index23 alt1"></div>
<div class="line number25 index24 alt2"><code class="csharp spaces">      </code><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number26 index25 alt1"><code class="csharp spaces">      </code><code class="csharp color1">/// //权限判断业务逻辑</code></div>
<div class="line number27 index26 alt2"><code class="csharp spaces">      </code><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number28 index27 alt1"><code class="csharp spaces">      </code><code class="csharp color1">/// &lt;param name="filterContext"&gt;&lt;/param&gt;</code></div>
<div class="line number29 index28 alt2"><code class="csharp spaces">      </code><code class="csharp color1">/// &lt;returns&gt;&lt;/returns&gt;</code></div>
<div class="line number30 index29 alt1"><code class="csharp spaces">      </code><code class="csharp keyword">protected</code> <code class="csharp keyword">virtual</code> <code class="csharp keyword">bool</code> <code class="csharp plain">AuthorizeCore(ActionExecutingContext filterContext)</code></div>
<div class="line number31 index30 alt2"><code class="csharp spaces">      </code><code class="csharp plain">{</code></div>
<div class="line number32 index31 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">object</code><code class="csharp plain">[] filter;</code></div>
<div class="line number33 index32 alt2"></div>
<div class="line number34 index33 alt1"><code class="csharp spaces">          </code><code class="csharp comments">// 验证当前Action是否是匿名访问Action</code></div>
<div class="line number35 index34 alt2"><code class="csharp spaces">          </code><code class="csharp plain">filter = filterContext.Controller.GetType().GetCustomAttributes(</code><code class="csharp keyword">typeof</code><code class="csharp plain">(AnonymousAttribute), </code><code class="csharp keyword">true</code><code class="csharp plain">);</code></div>
<div class="line number36 index35 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">if</code> <code class="csharp plain">(filter.Length == 1)</code></div>
<div class="line number37 index36 alt2"><code class="csharp spaces">          </code><code class="csharp plain">{</code></div>
<div class="line number38 index37 alt1"><code class="csharp spaces">              </code><code class="csharp keyword">return</code> <code class="csharp keyword">true</code><code class="csharp plain">;</code></div>
<div class="line number39 index38 alt2"><code class="csharp spaces">          </code><code class="csharp plain">}</code></div>
<div class="line number40 index39 alt1"></div>
<div class="line number41 index40 alt2"><code class="csharp spaces">          </code><code class="csharp comments">// 验证当前Action是否是权限控制页面Action</code></div>
<div class="line number42 index41 alt1"><code class="csharp spaces">          </code><code class="csharp plain">filter = filterContext.Controller.GetType().GetCustomAttributes(</code><code class="csharp keyword">typeof</code><code class="csharp plain">(ModuleAuthorizationAttribute), </code><code class="csharp keyword">true</code><code class="csharp plain">);</code></div>
<div class="line number43 index42 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">if</code> <code class="csharp plain">(filter.Length == 1)</code></div>
<div class="line number44 index43 alt1"><code class="csharp spaces">          </code><code class="csharp plain">{</code></div>
<div class="line number45 index44 alt2"><code class="csharp spaces">              </code><code class="csharp comments">//获取 controllerName 名称</code></div>
<div class="line number46 index45 alt1"><code class="csharp spaces">              </code><code class="csharp keyword">var</code> <code class="csharp plain">controllerName = filterContext.RouteData.Values[</code><code class="csharp string">"controller"</code><code class="csharp plain">].ToString();</code></div>
<div class="line number47 index46 alt2"><code class="csharp spaces">              </code><code class="csharp comments">//获取ACTION 名称</code></div>
<div class="line number48 index47 alt1"><code class="csharp spaces">              </code><code class="csharp keyword">var</code> <code class="csharp plain">actionName = filterContext.RouteData.Values[</code><code class="csharp string">"action"</code><code class="csharp plain">].ToString();</code></div>
<div class="line number49 index48 alt2"><code class="csharp spaces">              </code><code class="csharp keyword">return</code> <code class="csharp plain">AccountHelper.ValidatePermission(controllerName, actionName);</code></div>
<div class="line number50 index49 alt1"><code class="csharp spaces">          </code><code class="csharp plain">}</code></div>
<div class="line number51 index50 alt2"></div>
<div class="line number52 index51 alt1"><code class="csharp spaces">          </code><code class="csharp comments">// 验证当前Action是否是登录用户Action</code></div>
<div class="line number53 index52 alt2"><code class="csharp spaces">          </code><code class="csharp plain">filter = filterContext.Controller.GetType().GetCustomAttributes(</code><code class="csharp keyword">typeof</code><code class="csharp plain">(LoginAllowAttribute), </code><code class="csharp keyword">true</code><code class="csharp plain">);</code></div>
<div class="line number54 index53 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">if</code> <code class="csharp plain">(filter.Length == 1)</code></div>
<div class="line number55 index54 alt2"><code class="csharp spaces">          </code><code class="csharp plain">{</code></div>
<div class="line number56 index55 alt1"><code class="csharp spaces">              </code><code class="csharp keyword">return</code> <code class="csharp plain">HttpContext.Current.User.Identity.IsAuthenticated;</code></div>
<div class="line number57 index56 alt2"><code class="csharp spaces">          </code><code class="csharp plain">}</code></div>
<div class="line number58 index57 alt1"></div>
<div class="line number59 index58 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">throw</code> <code class="csharp keyword">new</code> <code class="csharp plain">Exception(</code><code class="csharp string">"用户验证失败!"</code><code class="csharp plain">);</code></div>
<div class="line number60 index59 alt1"><code class="csharp spaces">      </code><code class="csharp plain">}</code></div>
<div class="line number61 index60 alt2"><code class="csharp spaces">  </code><code class="csharp plain">}</code></div>
<div class="line number61 index60 alt2">

 

代码下载:PRMMS.Authorization.zip

[转载]Asp.Net MVC 权限控制(二):Controller级别控制 - Jetlian - 博客园

mikel阅读(849)

来源: [转载]Asp.Net MVC 权限控制(二):Controller级别控制 – Jetlian – 博客园

由于直接在Controller上标记角色名有很大的局限性,所以本示例使用 ActionFilterAttribute 进行权限拦截。

首先创建三类标记:

1. 匿名访问标记(AnonymousAttribute)
2. 登录用户访问标记(LoginAllowViewAttribute)
3. 权限验证访问标记(PermissionPageAttribute)

 

最重要的一个权限拦截:AuthorizeFilter,包括三步验证:

1. 是否为匿名访问,如果是匿名访问直接通过;
2. 是否为权限验证,通过查询登录时保存的Cookie进行验证;
3. 是否已登录,如果登录直接通过;

<div class="container">
<div class="line number1 index0 alt2"><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number2 index1 alt1"><code class="csharp color1">/// 权限拦截</code></div>
<div class="line number3 index2 alt2"><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number4 index3 alt1"><code class="csharp plain">[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = </code><code class="csharp keyword">false</code><code class="csharp plain">)]</code></div>
<div class="line number5 index4 alt2"><code class="csharp keyword">public</code> <code class="csharp keyword">class</code> <code class="csharp plain">AuthorizeFilter : ActionFilterAttribute</code></div>
<div class="line number6 index5 alt1"><code class="csharp plain">{</code></div>
<div class="line number7 index6 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number8 index7 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// 在执行操作方法之前由 ASP.NET MVC 框架调用。</code></div>
<div class="line number9 index8 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number10 index9 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;param name="filterContext"&gt;&lt;/param&gt;</code></div>
<div class="line number11 index10 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">public</code> <code class="csharp keyword">override</code> <code class="csharp keyword">void</code> <code class="csharp plain">OnActionExecuting(ActionExecutingContext filterContext)</code></div>
<div class="line number12 index11 alt1"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number13 index12 alt2"><code class="csharp spaces">        </code><code class="csharp comments">//根据验证判断进行处理</code></div>
<div class="line number14 index13 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">if</code> <code class="csharp plain">(!</code><code class="csharp keyword">this</code><code class="csharp plain">.AuthorizeCore(filterContext))</code></div>
<div class="line number15 index14 alt2"><code class="csharp spaces">        </code><code class="csharp plain">{</code></div>
<div class="line number16 index15 alt1"><code class="csharp spaces">            </code><code class="csharp plain">filterContext.RequestContext.HttpContext.Response.Redirect(</code><code class="csharp string">"~/Account/Login"</code><code class="csharp plain">);</code></div>
<div class="line number17 index16 alt2"><code class="csharp spaces">        </code><code class="csharp plain">}</code></div>
<div class="line number18 index17 alt1"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number19 index18 alt2"></div>
<div class="line number20 index19 alt1"></div>
<div class="line number21 index20 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;summary&gt;</code></div>
<div class="line number22 index21 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// //权限判断业务逻辑</code></div>
<div class="line number23 index22 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;/summary&gt;</code></div>
<div class="line number24 index23 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;param name="filterContext"&gt;&lt;/param&gt;</code></div>
<div class="line number25 index24 alt2"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;param name="isViewPage"&gt;是否是页面&lt;/param&gt;</code></div>
<div class="line number26 index25 alt1"><code class="csharp spaces">    </code><code class="csharp color1">/// &lt;returns&gt;&lt;/returns&gt;</code></div>
<div class="line number27 index26 alt2"><code class="csharp spaces">    </code><code class="csharp keyword">protected</code> <code class="csharp keyword">virtual</code> <code class="csharp keyword">bool</code> <code class="csharp plain">AuthorizeCore(ActionExecutingContext filterContext)</code></div>
<div class="line number28 index27 alt1"><code class="csharp spaces">    </code><code class="csharp plain">{</code></div>
<div class="line number29 index28 alt2"><code class="csharp spaces">        </code><code class="csharp keyword">object</code><code class="csharp plain">[] filter;</code></div>
<div class="line number30 index29 alt1"></div>
<div class="line number31 index30 alt2"><code class="csharp spaces">        </code><code class="csharp comments">// 验证当前Action是否是匿名访问Action</code></div>
<div class="line number32 index31 alt1"><code class="csharp spaces">        </code><code class="csharp plain">filter = filterContext.Controller.GetType().GetCustomAttributes(</code><code class="csharp keyword">typeof</code><code class="csharp plain">(AnonymousAttribute), </code><code class="csharp keyword">true</code><code class="csharp plain">);</code></div>
<div class="line number33 index32 alt2"><code class="csharp spaces">        </code><code class="csharp keyword">if</code> <code class="csharp plain">(filter.Length == 1)</code></div>
<div class="line number34 index33 alt1"><code class="csharp spaces">        </code><code class="csharp plain">{</code></div>
<div class="line number35 index34 alt2"><code class="csharp spaces">            </code><code class="csharp keyword">return</code> <code class="csharp keyword">true</code><code class="csharp plain">;</code></div>
<div class="line number36 index35 alt1"><code class="csharp spaces">        </code><code class="csharp plain">}</code></div>
<div class="line number37 index36 alt2"></div>
<div class="line number38 index37 alt1"><code class="csharp spaces">        </code><code class="csharp comments">// 验证当前Action是否是权限控制页面Action</code></div>
<div class="line number39 index38 alt2"><code class="csharp spaces">        </code><code class="csharp plain">filter = filterContext.Controller.GetType().GetCustomAttributes(</code><code class="csharp keyword">typeof</code><code class="csharp plain">(PermissionPageAttribute), </code><code class="csharp keyword">true</code><code class="csharp plain">);</code></div>
<div class="line number40 index39 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">if</code> <code class="csharp plain">(filter.Length == 1)</code></div>
<div class="line number41 index40 alt2"><code class="csharp spaces">        </code><code class="csharp plain">{</code></div>
<div class="line number42 index41 alt1"><code class="csharp spaces">            </code><code class="csharp comments">//获取 controllerName 名称</code></div>
<div class="line number43 index42 alt2"><code class="csharp spaces">            </code><code class="csharp keyword">var</code> <code class="csharp plain">controllerName = filterContext.RouteData.Values[</code><code class="csharp string">"controller"</code><code class="csharp plain">].ToString();</code></div>
<div class="line number44 index43 alt1"><code class="csharp spaces">            </code><code class="csharp comments">//获取ACTION 名称</code></div>
<div class="line number45 index44 alt2"><code class="csharp spaces">            </code><code class="csharp keyword">var</code> <code class="csharp plain">actionName = filterContext.RouteData.Values[</code><code class="csharp string">"action"</code><code class="csharp plain">].ToString();</code></div>
<div class="line number46 index45 alt1"></div>
<div class="line number47 index46 alt2"><code class="csharp spaces">            </code><code class="csharp keyword">var</code> <code class="csharp plain">validateAuthorize = </code><code class="csharp keyword">new</code> <code class="csharp plain">ValidateAuthorize();</code></div>
<div class="line number48 index47 alt1"><code class="csharp spaces">            </code><code class="csharp keyword">return</code> <code class="csharp plain">validateAuthorize.validate(controllerName);</code></div>
<div class="line number49 index48 alt2"><code class="csharp spaces">        </code><code class="csharp plain">}</code></div>
<div class="line number50 index49 alt1"></div>
<div class="line number51 index50 alt2"><code class="csharp spaces">        </code><code class="csharp comments">// 验证当前Action是否是登录用户Action</code></div>
<div class="line number52 index51 alt1"><code class="csharp spaces">        </code><code class="csharp plain">filter = filterContext.Controller.GetType().GetCustomAttributes(</code><code class="csharp keyword">typeof</code><code class="csharp plain">(LoginAllowViewAttribute), </code><code class="csharp keyword">true</code><code class="csharp plain">);</code></div>
<div class="line number53 index52 alt2"><code class="csharp spaces">        </code><code class="csharp keyword">if</code> <code class="csharp plain">(filter.Length == 1)</code></div>
<div class="line number54 index53 alt1"><code class="csharp spaces">        </code><code class="csharp plain">{</code></div>
<div class="line number55 index54 alt2"><code class="csharp spaces">            </code><code class="csharp keyword">return</code> <code class="csharp plain">HttpContext.Current.User.Identity.IsAuthenticated;</code></div>
<div class="line number56 index55 alt1"><code class="csharp spaces">        </code><code class="csharp plain">}</code></div>
<div class="line number57 index56 alt2"></div>
<div class="line number58 index57 alt1"><code class="csharp spaces">        </code><code class="csharp keyword">throw</code> <code class="csharp keyword">new</code> <code class="csharp plain">Exception(</code><code class="csharp string">"用户验证出错!"</code><code class="csharp plain">);</code></div>
<div class="line number59 index58 alt2"><code class="csharp spaces">    </code><code class="csharp plain">}</code></div>
<div class="line number60 index59 alt1"><code class="csharp plain">}</code></div>
<div class="line number60 index59 alt1">
用户登录后保存用户信息。
</div>
<div class="line number60 index59 alt1">
<div class="container">
<div class="line number1 index0 alt2"><code class="csharp plain">[HttpPost]</code></div>
<div class="line number2 index1 alt1"><code class="csharp spaces">      </code><code class="csharp plain">[ValidateAntiForgeryToken]</code></div>
<div class="line number3 index2 alt2"><code class="csharp spaces">      </code><code class="csharp keyword">public</code> <code class="csharp plain">ActionResult Login(LoginModel model, </code><code class="csharp keyword">string</code> <code class="csharp plain">returnUrl)</code></div>
<div class="line number4 index3 alt1"><code class="csharp spaces">      </code><code class="csharp plain">{</code></div>
<div class="line number5 index4 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">string</code> <code class="csharp plain">UserData = </code><code class="csharp string">""</code><code class="csharp plain">;</code></div>
<div class="line number6 index5 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">var</code> <code class="csharp plain">userName = model.UserName;</code></div>
<div class="line number7 index6 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">if</code> <code class="csharp plain">(userName == </code><code class="csharp string">"admin"</code><code class="csharp plain">)</code></div>
<div class="line number8 index7 alt1"><code class="csharp spaces">          </code><code class="csharp plain">{</code></div>
<div class="line number9 index8 alt2"><code class="csharp spaces">              </code><code class="csharp plain">UserData = </code><code class="csharp string">"Log"</code><code class="csharp plain">;</code></div>
<div class="line number10 index9 alt1"><code class="csharp spaces">          </code><code class="csharp plain">}</code></div>
<div class="line number11 index10 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">else</code> <code class="csharp keyword">if</code> <code class="csharp plain">(userName == </code><code class="csharp string">"in"</code><code class="csharp plain">)</code></div>
<div class="line number12 index11 alt1"><code class="csharp spaces">          </code><code class="csharp plain">{</code></div>
<div class="line number13 index12 alt2"><code class="csharp spaces">              </code><code class="csharp plain">UserData = </code><code class="csharp string">"Infrastructure"</code><code class="csharp plain">;</code></div>
<div class="line number14 index13 alt1"><code class="csharp spaces">          </code><code class="csharp plain">}</code></div>
<div class="line number15 index14 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">else</code> <code class="csharp keyword">if</code> <code class="csharp plain">(userName == </code><code class="csharp string">"fl"</code><code class="csharp plain">)</code></div>
<div class="line number16 index15 alt1"><code class="csharp spaces">          </code><code class="csharp plain">{</code></div>
<div class="line number17 index16 alt2"><code class="csharp spaces">              </code><code class="csharp plain">UserData = </code><code class="csharp string">"FileLibrary"</code><code class="csharp plain">;</code></div>
<div class="line number18 index17 alt1"><code class="csharp spaces">          </code><code class="csharp plain">}</code></div>
<div class="line number19 index18 alt2"></div>
<div class="line number20 index19 alt1"><code class="csharp spaces">          </code><code class="csharp plain">FormsAuthenticationTicket authTicket = </code><code class="csharp keyword">new</code> <code class="csharp plain">FormsAuthenticationTicket(</code></div>
<div class="line number21 index20 alt2"><code class="csharp spaces">          </code><code class="csharp plain">1,</code></div>
<div class="line number22 index21 alt1"><code class="csharp spaces">          </code><code class="csharp plain">userName,</code></div>
<div class="line number23 index22 alt2"><code class="csharp spaces">          </code><code class="csharp plain">DateTime.Now,</code></div>
<div class="line number24 index23 alt1"><code class="csharp spaces">          </code><code class="csharp plain">DateTime.Now.AddMinutes(20),</code></div>
<div class="line number25 index24 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">false</code><code class="csharp plain">,</code></div>
<div class="line number26 index25 alt1"><code class="csharp spaces">          </code><code class="csharp plain">UserData</code><code class="csharp comments">//写入用户角色</code></div>
<div class="line number27 index26 alt2"><code class="csharp spaces">          </code><code class="csharp plain">);</code></div>
<div class="line number28 index27 alt1"></div>
<div class="line number29 index28 alt2"><code class="csharp spaces">          </code><code class="csharp keyword">string</code> <code class="csharp plain">encryptedTicket = FormsAuthentication.Encrypt(authTicket);</code></div>
<div class="line number30 index29 alt1"></div>
<div class="line number31 index30 alt2"><code class="csharp spaces">          </code><code class="csharp plain">System.Web.HttpCookie authCookie = </code><code class="csharp keyword">new</code> <code class="csharp plain">System.Web.HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);</code></div>
<div class="line number32 index31 alt1"><code class="csharp spaces">          </code><code class="csharp plain">System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);</code></div>
<div class="line number33 index32 alt2"></div>
<div class="line number34 index33 alt1"><code class="csharp spaces">          </code><code class="csharp keyword">return</code> <code class="csharp plain">RedirectToAction(</code><code class="csharp string">"Index"</code><code class="csharp plain">, </code><code class="csharp string">"Home"</code><code class="csharp plain">);</code></div>
<div class="line number35 index34 alt2"><code class="csharp spaces">      </code><code class="csharp plain">}</code></div>
<div class="line number35 index34 alt2">

代码下载:AuthorizationProject.zip