posts - 5, comments - 4, trackbacks - 0, articles - 0

2011年12月16日

<div id="power_tree">
<ul>
<li>
<input type="checkbox"><label>一级</label>
<ul>
<li>
<input type="checkbox"><label>二级1</label>
<ul>
<li>
<input type="checkbox"><label>三级1</label></li>
<li>
<input type="checkbox"><label>三级2</label></li>
<li>
<input type="checkbox"><label>三级3</label></li></ul>
</li>
<li>
<input type="checkbox"><label>二级2</label>
<ul>
<li>
<input type="checkbox"><label>三级1</label></li></ul>
</li>
<li>
<input type="checkbox"><label>二级3</label></li>
<li>
<input type="checkbox"><label>二级4</label>
<ul>
<li>
<input type="checkbox"><label>三级1</label>
<ul>
<li>
<input type="checkbox"><label>四级1</label></li></ul>
</li>
</ul>
</li>
</div>
<script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
function Test(obj) {
var $this = $(obj);
var checked = obj.checked;
var parentUl = $this.parent().parent('ul');
var parentLevel = parentUl.prev().prev('input:checkbox');
var nextLevel = $this.next().next('ul').find("input:checkbox");
//无论如何子级状态总量随着父级状态变化
nextLevel.attr("checked", checked);
if (checked) {
if (parentLevel.size() > 0) {
//只要选上父级就选上
parentLevel.attr("checked", true);
Test(parentLevel);//递归
}
} else {
//子取消默认设置父级取消
var flag = false;
//但是需要看其它兄弟是否有选上的
parentUl.children('li').each(function () {
var _$this = $(this);
var _checked = _$this.children(':first').attr("checked");
//直到碰到选上的兄弟为止跳出循环
return !(flag = _checked != undefined);
});
if (parentLevel.size() > 0) {
parentLevel.attr("checked", flag);
Test(parentLevel);
}
}
}
$('#power_tree :checkbox').change(function () {
Test(this);
});
});
</script>
 

请点击上面的运行代码,然后刷新页面(CDN加载Jquery)

子选父必选    父选子全选      所有子取消父即取消 

 

这里面附上 demo

posted @ 2011-12-16 17:06 白菜.tang 阅读(183) 评论(0) 编辑

2011年12月9日

public class Person<T>
    {
        public string name;
        public bool sex;
        public int age;
        public DateTime birthday;
        public DateTime? now;
        public T desc;
    }

//main方法下面的

            var NVC = new NameValueCollection();
            NVC.Add("name", "白菜");
            NVC.Add("sex", "1");
            NVC.Add("age", "23");
            NVC.Add("birthday", "1989-06-27");
            NVC.Add("now", "2011-12-08");
            NVC.Add("Desc", ".net程序员");
            var person = NVC.ModelGeneration<Person<string>>();

 以下为扩展方法

public static class ModelGenerationExtension
    {
        /// <summary>
        /// 从名值对参数中自动填充模型
        /// </summary>
        public static T ModelGeneration<T>(this NameValueCollection nvc)
        {
            var type = typeof(T);
            var obj = (T)Activator.CreateInstance(type);
            var bindflag = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.GetField;
            var fileds = type.GetFields(bindflag);
            foreach (var filed in fileds)
            {
                var val = nvc[filed.Name];
                var fType = filed.FieldType;
                if (fType.IsGenericType && fType.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    //泛型参数 可空类型
                    fType = fType.GetGenericArguments()[0];
                }
                try
                {
                    if (typeof(bool) == fType && val.ToLower() != "true" && val.ToLower() != "false")
                        if (val == "1")
                            val = "true";
                        else
                            val = "false";
                    type.GetField(filed.Name, bindflag).SetValue(obj, Convert.ChangeType(val, fType));
                }
                catch
                {
                    type.GetField(filed.Name, bindflag).SetValue(obj, Activator.CreateInstance(fType));
                }

            }
            return obj;
        }
    }

 

当然可以像这样应用:

var model= Request.Form.ModelGeneration<你的类型>();

posted @ 2011-12-09 17:51 白菜.tang 阅读(44) 评论(0) 编辑

/// <summary>
    /// Json扩展方法类(编译时检查,类型安全)
    /// </summary>
    public static class JsonContextExtension
    {
        /// <summary>
        /// 从一个对象信息生成Json串
        /// </summary>
        /// <param name="obj">转换对象</param>
        /// <typeparam name="T">对象类型</typeparam>
        /// <returns></returns>
        public static string ToJson<T>(this T obj)
        {
            if (typeof(T).FullName.Contains("<>f__AnonymousType"))
            {
                //匿名类型
                var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                return serializer.Serialize(obj);
            }
            else
            {
                var serializer = new DataContractJsonSerializer(typeof(T));
                string json = string.Empty;
                using (MemoryStream stream = new MemoryStream())
                {
                    serializer.WriteObject(stream, obj);
                    json = Encoding.UTF8.GetString(stream.ToArray());
                    stream.Close();
                }
                return json;
            }
        }
        /// <summary>
        /// 从一个Json串生成对象信息
        /// </summary>
        /// <param name="jsonString">JSON字符串</param>
        /// <typeparam name="T">对象类型</typeparam>
        /// <returns></returns>
        public static T JsonToObject<T>(this string jsonString)
        {

            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
            {
                var jsonobj = (T)serializer.ReadObject(stream);
                stream.Close();
                return jsonobj;
            }
        }
    }

 

posted @ 2011-12-09 17:46 白菜.tang 阅读(222) 评论(0) 编辑

2011年12月2日

前面几篇文章介绍了下微软标识库WIF的基本概念,WIF目前支持两种验证方案,一个是 asp.net的被动联合身份验证,二是WCF的身份验证,因为前者需要用到浏览器,所以采用了一些技巧去实现,根据这些技巧的行为微软定义为"被动的".

下面我用一个示例项目来讲解:

首先我作为客户访问 下面项目中的 Default页面,这个应用程序叫做 "信赖方应用程序(RP)",是声明感知的,这些概念可以去MSDN里面详细了解.

我用Opera浏览器来拦截请求,图中的工具可以按(shift+ctrl+i),首先需要在页面右击"编辑站点首选项",

1."脚本"选项卡里面去掉"允许使用javascript",

2.然后去掉在"网络"选项卡里面的"允许自动重定向",这是为了捕获http请求头必须的.

我们请求RP的defalut页面时,由于未经验证,RP在响应头里面设置了重定向,重定向到STS的default页面(这个页面是专门用来给RP传递令牌的),你可能会疑问,这个重定向的url里面的参数好奇怪,什么wa,wtrealm..  其实这些是由Rp方的 Microsoft.IdentityModel.Web.WSFederationAuthenticationModule拦截未验证的请求后生成的,

这些参数在 WSFederationConstants 类里面.

当转到STS的Default页面时,STS说:咦?你还没有通过我的验证哦,我不能给你令牌的,你得先让我验证下你的身份.这样STS又转向到他的表单验证登录页面... 折腾啊!!

Login.aspx页面已经返回了上面的HTML ,为了演示,没有任何漂亮的样式 ,也没做任何密码决断,只要用户名不为空就算通过了.我来提交下.

提交的时候顺便把这个cookie提交过去了,这是刚刚请求那个登录页面时设置了,表单验证必备的,你懂的.

提交后,我们就算通过表单验证了,通过后干了什么呢?这个页面有点不好捕获,这也是之前为什么我要禁用脚本的原因,否则一闪就过了.这个页面是刚刚STS default.aspx页面返回的,

因为他已经被表单验证通过了,这个页面其实就是返回一个自提交JS和一个XML

以下是上面页面的HTML ,技术很简单 ,很多人用过了

以下是这次POST的拦截信息

好吧我把上面的提交下吧,这是提交是 STS default.aspx 页面 向 RP的 default.aspx 页面提交

 

哈哈,当这个令牌传递给RP时,RP端的 Default.aspx页面终于出现了

顺便把那个令牌XML格式化出来贴上

 

好了 时间不早了 读者消化下,多谢支持 ,点击此处下载

 

MSDN对此过程的图示:

http://msdn.microsoft.com/zh-cn/library/ee517293.aspx 

令牌采用的ws-trust行业标准协议,可支持java客户端

Project Tango ,Metro 的介绍

http://dev.21tx.com/2008/12/20/11343.html

 

欢迎进入【系统架构师】群

点击这里加入此群

posted @ 2011-12-02 22:45 白菜.tang 阅读(918) 评论(2) 编辑

2011年10月24日

  -- 最近在学习Windows® Identity Foundation,这是MSDN里面对WIF的介绍: ,里面已经说得很好了,小弟就不再介绍了.WIF框架下载

在没有WIF之前,我们在构建我们的应用程序时,往往都会设计自己的用户库和验证逻辑,比如给公司开发一个中文CMS系统和一个英文的电子商务系统(由于各种原因比如两个项目是不同软件公司设计的,总之两个系统未能集成在一起),而这两个系统的后台管理员理论上是有可能共享的,因为后台操作只会限定在公司内部成员.甚至将来还会继续开发其它的应用系统...

面对这样不尴不尬的情景,一个经典的作法是给这些系统额外的设计单点登录.

说到单点登录,不得不说的是一个一致的身份验证策略设计往往只有在若干安全领域专家辅助时才能完成.

如果公司没有超强的安全领域知识积累,设计的sso将是脆弱的,随着时间的推移,一些不合理的设计最终将成为扩展的瓶颈! 这些感受我想很多人都有过.

以上糟糕的情形还是被微软看出来了,终于,他们集结很多业界安全大师设计了一套全新的基于声明的新访问平台,WIF就是此平台组件之一(其它两个是ADFS V2和Windows CardSpace).

  一个貌似很熟悉的名词"基于声明"展现了一种新的方案,下面来形象的解释下WIF的验证流程.

以购买机票的流程来解释:

  有一天你要去买机票(访问信赖方RP系统),

  售票阿姨必须要你出示用户名,生日,住址(声明),同时提供的信息必须是这位阿姨可以相信的,你不能自己随便写一个,很自然的你想到了身份证(安全令牌 ps:身份证是可扫描的,内部数据是加密的).

  因为身份证是公安局(颁发机构)颁发给你的,同时公安局也是航空公司可以信赖的,信赖身份证就像信赖公安局一样,所以没什么要怀疑的,你成功的买到票了.

  从上面的过程我们可以看出,航空公司没有维护自己的用户库,也没有自己去验证用户信息的真实性,因为身份证可以证明买票者同时提供了航空公司需要的信息(声明).

  航空公司把这一切验证都外包给了一个统一的机构.同时这一机构可以提供足够的用户信息.

人类这些聪明的社会行为同样的被拿到软件设计上.下面用真实的web系统说明:

  信赖合作伙伴身份验证流程图

RP 公开了描述其地址、绑定和协定的策略。 但是该策略也包括 RP 所需的声明列表,如用户名、电子邮件地址和角色成员身份。 该策略还告知智能客户端应从中检索这些声明的 STS 的地址。 检索此策略后 (1),

客户端此时已知道到哪里去进行身份验证:STS。 用户出示凭据 (2),

智能客户端向 STS 提出 Web 服务请求 (3),

从而请求 RP 在其策略中所要求的声明。 STS 的工作是对用户进行身份验证,并返回为 RP 提供所有所需声明的安全令牌。 然后智能客户端会对依赖方提出请求 (4),

从而在安全 SOAP 标头中发送安全令牌。 RP 此时收到各个请求的声明,只拒绝那些不包括来自其信任的颁发机构的安全令牌的请求。

 

下面我来列出一些术语:

STS: SecurityTokenService(安全令牌服务),相当于公安局,提供身份证信息审查/办理/查询验证服务.

RP: 信赖方. 当某个公司需要使用身份证来办理公司业务时,它必须信赖公安局(STS),这个公司此时参与的角色被称谓 信赖方.

RP-STS:(信赖方STS) / IP-STS:(标识方STS)

IPSTS 和 RPSTS

联合身份验证概述

好了,初次写博,总结下了MSDN的概述,以后将写更多关于WIF实际应用的文章

posted @ 2011-10-24 12:05 白菜.tang 阅读(207) 评论(2) 编辑