随缘记录
模拟Session滑动时间 存到Memcache时设置 滑动时间
别用控制器过滤!!!(不灵活呀)
LRU(least recently used)
Memcache选机器(集群搭建原理:客户端配置多台集群服务器的ip和端口列表)
hash(key) % 机器数量 余数对应的机器
服务器(Socket服务器端)
没有记住密码-->关闭浏览器-->Memcache设置的20分钟还没过-->还能自动登录~(是否要解决呢?)
分区slab-->分块chunk(s)(1MB) 会浪费内存
惰性删除(不像.NET有缓存依赖)(删除时是清空内容,不会释放,不重新new,重复利用这样就不会产生内存碎片)
取的时候 才查是否过期
最大过期时间 30天(绝对过期时间)
可以重新 设值 模仿滑动时间
插入新数据时,内存不够 LRU:闲置>过期>最少访问 插入(替换)优先级(满了先插闲置的,没有闲置的就查过期的,最后是最少访问的)
get的时候 会有一个记录数
四.MEMCACHE的删除机制
删除机制其实有两种:
1.LRU删除机制:least recently used(最近最少使用),当某个单元被请求时,维护一个计数器,通过计数器来判断最近谁最少被使用。(多用它)
2.FIFO删除机制:first in,first out (最先插入,最先离开)
永久数据被踢现象:即使某个key 是设置的永久有效期,也一样会被踢出来!
当将对象放入内存时,失效数据首先被替换,然后再替换掉最近未使用的数据。
还可以 文件分布式存储
localhost、127.0.0.1和本机IP的区别如下:
localhost 是一个域名,在过去它指向 127.0.0.1 这个IP地址。在操作系统支持 ipv6 后,它同时还指向ipv6 的地址 [::1] 。
服务列表有些不可用 客户端会重新选择
删除前先判断 mc.KeyExists(string key)
Session(存储在服务器内存)是以Cookie形式返回给客户端
客户端请求时 Cookie中就存有SessionID
解决Web集群下Session问题
1、Session数据--存取数据库(慢)
2、存到Memcache服务器(需要要解决缓存共享问题)
key Guid模拟SessionID
value 可以放数据(如果是类,那么就可以放很多不同的东西,文件、图片等)
class Data{ 照片; 尺寸}
比如说 存储 Set("用户A", Data实例(需要标记可序列化)); (自己先用Newtonsoft.Json序列化,这个性能最好)(字符串)
取 Get("用户A") as Data;
拿照片 Data.照片
需要装箱,拆箱 性能低
这时候Redis就有优势了(存储时会自动序列化,但性能没Newtonsoft.Json好)
Hash数据结构
key map(field value) 这种结构可以按需选取
比如说 存储 Set("用户A", "照片", "我的自拍1.jpg");
Set("用户A", "尺寸", "21");
拿照片 Get("用户A", "照片")
无需装箱拆箱,性能高,要啥取啥
猜测结构: 数组(根据hash(键)得到索引)+链表(键值对) 哈希冲突用其他方法解决
很明显,这种猜测是很幼稚的
实际上是 Key Value(Map(field value)),也就是说value是一个Map
形象一点 Key [filed value]
主键表A(ID) 中间表(AID, BID)(联合主键,并且各自是外键) 主键表B(ID)
主键表A(ID) 中间表(ID, AID, BID, 其他字段)(主键+外键+外键) 主键表B(ID)
ModelFirst会把自动中间表给你建起来
如果中间表需要放其他字段 比如isPass 就需要显现的创建出来
权限表:
控制器下的方法 请求方法(POST、GET) 权限类型(菜单权限和普通权限) 图片路径
T4模板(Text Template Transformation Toolkit)
<#@ import namespace="System.Text" #>
<#@ output extension=".cs" #>
读取edmx文件(含有所有实体类) -->EdmItemCollection
开始生成
注意有导航属性的类 可能会循环 序列化
[JsonIgnore]
因为用户管理中的增删改都在一个页面了,为了不显臃肿
//原来是<div><table><tr></tr><td></td></tr></table></div> $div.dialog({});
所以把设置用户角色和设置用户权限放在iframe(可以内嵌网页)
<div><iframe></iframe></div> 注意 一开始都是display: none
此时,提交表单(假设点击的是dialog的ok按钮,即在div上)就是跨窗口了,需要用到
父窗口调用子窗口的方法:
先拿到嵌入在iframe的子窗体window对象var childWindow = $('#iframe')[0].contentWindow,
然后调用childWindow.submitForm();
子窗体调用父窗体的方法(从而影响父窗体,比如添加后需要隐藏表单和清空内容):
window.parent.afterAdd(data);
展示用户角色:
1、拿到UserInfo
2、拿到用户拥有的角色ID集合
3、拿到系统的角色集合
4、展示的时候 if else 把用户已拥有的角色的复选框 选中(遍历角色集合,用户角色ID集合.Contains(角色.ID))
ViewBag.Name 不需要转换 本身就是dynamic
<span></span>
Request.Form.AllKeys;(把用户勾选的角色ID放到name属性中)("name_" + roleInfo.ID)
name.StartsWith("name_")
设置用户角色:
1先删除所有用户拥有的角色(UserInf.RoleInfo.Clear())
2、按照用户勾选复选框的情况 拿到的RoleID集合 对应RoleInfo集合
3、UserInfo.RoleInfo.Add() (实际上操作的是中间表)
4、return DbSession.SaveChanges();
$Table.datagrid({
onLoadSucess: function(){} //载入成功以后触发
});
展示用户权限
1、拿到UserInfo
2、拿到用户拥有的权限集合
3、拿到权限集合
4、展示的时候 if权限 if允许(选中允许) else禁止(选中禁止) else允许禁止都为空 每个权限都有两个radio 最后再加个清除按钮
设置用户权限
1、拿到UerInfoID和ActionInfoID(ids)、isPass(value) 通过给radio注入属性
2、if有 则只修改isPass else 新建一个对象 添加到 用户权限 这个中间表(因为有isPass字段,所以建了实体类)
清除权限
1、拿到UerInfoID和ActionInfoID(ids)
2、直接操作中间表 删除此记录 where(r => r.UserInfoID == UID && r.ActionInfoID == AID).FirstOrDefault();
3、清除radio checked属性 $control.parent().find('.selections').removeAttr("checked");
过滤出菜单权限
1、用户-角色-权限
2、用户-权限
3、合并
4、去禁用
5、去重
6、把用户的菜单权限集合返回并绑定到 links
过滤非菜单权限
1、拿到url Rquest.Url.AbsolutePath
2、拿到请求方法 Request.HttpMethod
3、通过 IApplicationContext 创建业务类(这里用配置文件 交给容器new 会出错?)
4、根据url查权限表 if无 跳转404页面 else继续
5、此时已有权限信息
6、用户-权限(这里先判断,如果isPass为false,那么就没必要继续第七步了)(没有权限就跳转到NoAction.html)
7、用户-角色-权限
控制器/方法的地址和请求方式等信息 都要录入权限表~~~(虽然麻烦,但是这样每一个权限都能控制到)
超级管理员 开后门~(方便测试)