﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-阿不</title><link>http://www.cnblogs.com/hjf1223/</link><description>不抛弃，不放弃</description><language>zh-cn</language><lastBuildDate>Thu, 24 Jul 2008 08:13:16 GMT</lastBuildDate><pubDate>Thu, 24 Jul 2008 08:13:16 GMT</pubDate><ttl>60</ttl><item><title>ASP.NET MVC ：MVC页面验证与授权</title><link>http://www.cnblogs.com/hjf1223/archive/2008/07/09/mvc_authorization.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Wed, 09 Jul 2008 14:22:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/07/09/mvc_authorization.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1238509.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/07/09/mvc_authorization.html#Feedback</comments><slash:comments>14</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1238509.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1238509.html</trackback:ping><description><![CDATA[<p>在ASP.NET MVC中，如何来实现表单的验证与授权访问呢？至少在CTP3中，还没有一个官方的解决方案。ASP.NET WebForm的表单验证和授权机制是否适合在ASP.NET MVC中使用呢？带着这些问题来进入我们今天的主题。</p> <p>在ASP.NET WebForm的架构下，我们可以通过一定的配置即可实现用户身份验证和授权。特别是在ASP.NET 2.0的Membership功能的支撑下，可以做到更加简洁可复用的用户验证系统。通过web.config可以做到对页面或目录对不同用户身份可见性的定制，但是它是基于物理文件和目录。而在ASP.NET MVC架构下，用户访问的每一个页面在磁盘中并没有一个固定的物理文件，它是通过Controller控制数据与视图的组合来生成HTML代码，进而向客户端输出。那么我们该如何来复用已有的表单验证授权机制呢？</p> <p>在MVC中，请求的功能入口是Controller相应的Action函数，我们可以在函数执行前去控制请求权限。在ASP.NET MVC Preview 2后，提供了一个机制让我们可以对Action的AOP拦截，这个接口定义如下：</p> <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"> <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">interface</span> IActionFilter</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>     <span style="color: #0000ff">void</span> OnActionExecuted(ActionExecutedContext filterContext);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     <span style="color: #0000ff">void</span> OnActionExecuting(ActionExecutingContext filterContext);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>     <span style="color: #0000ff">void</span> OnResultExecuted(ResultExecutedContext filterContext);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>     <span style="color: #0000ff">void</span> OnResultExecuting(ResultExecutingContext filterContext);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span> }</pre></div></div>
<p>我们有两种方式来实现拦截，一种我们可以通过定义Attribute来实现拦截的功能，在System.Web.Mvc程序集中有一个ActionFilterAttribute抽象类，通过重写这个抽象类的这些虚方法，我们就可以实现对特定的执行过程进行拦截。</p>
<p>另一种方法，我们注意到Controller这个类也实现了IActionFilter这个接口，并且也提供了这四个函数的虚拟方法定义。框架内部，在调用Action方法的时候同时来调用这些拦截方法。具体的可以参考：ControllerActionInvoker 这个类的实现，所有的Action的调用都在这个类当中被实现。所以我们只要重写Controller里这四个虚方法，也可完成本Controller面的所有Action的拦截。</p>
<p>在这里，我也找到了国外友人已经实现好的基于角色的MVC权限控制的方案。自定义了两个自定义Attribute，分别为：RequiresAuthenticationAttribute和RequiresRoleAttribute。通过这两个Attribute来可以作用于Class和Method，用标记哪些Controller或Action需要登录后，或者需要拥有哪些角色才能执行。如果用户没有拥有访问当然Controller或Action权限的时候，就会自动被重定向到登录页面去。下面是两个类的定义：</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #008000">/// &lt;summary&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #008000">/// Checks the User's authentication using FormsAuthentication</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #008000">/// and redirects to the Login Url for the application on fail</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #008000">/// &lt;/summary&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">[RequiresAuthentication]</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> RequiresAuthenticationAttribute : ActionFilterAttribute</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">{</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnActionExecuting(ActionExecutingContext filterContext)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">    {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        <span style="color: #008000">//redirect if not authenticated</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        <span style="color: #0000ff">if</span> (!filterContext.HttpContext.User.Identity.IsAuthenticated)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            <span style="color: #008000">//use the current url for the redirect</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            <span style="color: #0000ff">string</span> redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            <span style="color: #008000">//send them off to the login page</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            <span style="color: #0000ff">string</span> redirectUrl = <span style="color: #0000ff">string</span>.Format(<span style="color: #006080">"?ReturnUrl={0}"</span>, redirectOnSuccess);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            <span style="color: #0000ff">string</span> loginUrl = FormsAuthentication.LoginUrl + redirectUrl;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            filterContext.HttpContext.Response.Redirect(loginUrl, <span style="color: #0000ff">true</span>);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">    }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">}</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #008000">/// &lt;summary&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #008000">/// Checks the User's role using FormsAuthentication</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #008000">/// and throws and UnauthorizedAccessException if not authorized</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #008000">/// &lt;/summary&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> RequiresRoleAttribute : ActionFilterAttribute</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">{</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> RoleToCheckFor { get; set; }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnActionExecuting(ActionExecutingContext filterContext)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">    {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        <span style="color: #008000">//redirect if the user is not authenticated</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        <span style="color: #0000ff">if</span> (!String.IsNullOrEmpty(RoleToCheckFor))</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            <span style="color: #0000ff">if</span> (!filterContext.HttpContext.User.Identity.IsAuthenticated)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">                <span style="color: #008000">//use the current url for the redirect</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">                <span style="color: #0000ff">string</span> redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">                <span style="color: #008000">//send them off to the login page</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">                <span style="color: #0000ff">string</span> redirectUrl = <span style="color: #0000ff">string</span>.Format(<span style="color: #006080">"?ReturnUrl={0}"</span>, redirectOnSuccess);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">                <span style="color: #0000ff">string</span> loginUrl = FormsAuthentication.LoginUrl + redirectUrl;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">                filterContext.HttpContext.Response.Redirect(loginUrl, <span style="color: #0000ff">true</span>);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">&nbsp;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            <span style="color: #0000ff">else</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">                <span style="color: #0000ff">bool</span> isAuthorized = filterContext.HttpContext.User.IsInRole(<span style="color: #0000ff">this</span>.RoleToCheckFor);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">                <span style="color: #0000ff">if</span> (!isAuthorized)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">                    <span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> UnauthorizedAccessException(<span style="color: #006080">"You are not authorized to view this page"</span>);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        <span style="color: #0000ff">else</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            <span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> InvalidOperationException(<span style="color: #006080">"No Role Specified"</span>);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">    }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">}</pre></div></div>
<p>如上所介绍的两种方法，我们一样可以定义一个Controller基类，通过拦截来进行权限的控制。但是与定义Attribute相比，手法并不是很好，也不利于通用化。但是就理论上的性能来说，会比Attribute更好。</p>
<p>到目前为止，ASP.NET MVC还没有更新的消息，我想在正式版本的ASP.NET MVC框架，权限控制问题会有一个官方说法。希望到时候会有一种更为灵活和可配置的方案。也许通过控制Url来控制访问权限也是一种可行的方案，会不会集成到RouteTable里面呢？让我们试目以待吧。</p>
<p>上一篇：<a href="http://www.cnblogs.com/hjf1223/archive/2008/07/09/mvc_webform.html">ASP.NET MVC :从ASP.NET WebForm到ASP.NET MVC技术上的共用和差异</a></p>
<p>广告：<a href="http://www.zazuone.com/">我的基于MVC的网站</a></p><img src ="http://www.cnblogs.com/hjf1223/aggbug/1238509.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41275/" target="_blank">[新闻]Mozilla将于本周五发布Firefox 3.1第一个预览版</a>]]></description></item><item><title>ASP.NET MVC :从ASP.NET WebForm到ASP.NET MVC技术上的共用和差异</title><link>http://www.cnblogs.com/hjf1223/archive/2008/07/09/mvc_webform.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Wed, 09 Jul 2008 05:40:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/07/09/mvc_webform.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1238507.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/07/09/mvc_webform.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1238507.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1238507.html</trackback:ping><description><![CDATA[<p>关于WebForm与MVC的讨论，年初的时候已经有一段很长时间的讨论了。我无意再去争论哪种架构模式更适合我们做开发，不管是哪个领域，技术的存在都有其不同的历史意义和市场价值。我更关注的是，在合适的机会去掌握更多的技术，从技术实现的角度来寻找当前阶段最为顺手的一种做事方法。所以请注意，在这里不讨论WebForm与MVC的优劣，适用场景。在这里只有ASP.NET WebForm与ASP.NET MVC，同样属于ASP.NET框架下的两种不同的Web开发技术，是如何充分发挥ASP.NET平台的强大功能，以及对于掌握ASP.NET WebForm的开发人员，转向ASP.NET MVC架构的学习成本。这就是我本篇文章的立意所在，同时我也是希望为我之后的几篇MVC系列文章提供一些注脚和铺垫。</p> <p>之前，从事ASP.NET开发，在没有特殊说明的情况下，指的就是ASP.NET WebForm的开发。之前ASP.NET技术的发展，直接就体现在WebForm技术上的进步。在ASP.NET MVC 出现之后，之前大家所掌握的ASP.NET技术对于ASP.NET MVC仍然有效，并且是最基础的部分。包括：页面处理流程，Web请求上下文对象，Web配置系统，公用性的组件模块，部分的服务器控件等等。我想从这几大块来详细阐述ASP.NET MVC对于ASP.NET技术的继承：</p> <ol> <li>页面处理流程：ASP.NET MVC 的页面处理流程仍然是在ASP.NET原有的处理流程上的扩展，在在上游的请求通道不变的前提下，通过特定的IHttpModule和IHttpHandler来处理ASP.NET MVC的请求。与WebForm页面处理不一样的地方就在于，在WebForm中，每一个页面都是一个IHttpHandler实例，页面的事件流程就是从IHttpHandler的ProcessRequest(HttpContext httpContext)方法开始。而在ASP.NET MVC中，所有的Controller都并不是IHttpHandler的继承实例，它的Action是在MvcHandler中被执行的，当然我们也可以自定义是MvcHandler。  <li>Web请求上下文对象：在ASP.NET MVC中，处理请求的线程模型没有改变。请求的上下文对象，与原有的ASP.NET WebForm仍然是共用的。  <li>Web配置系统：ASP.NET MVC仍然使用原有的配置系统，在Web.config中只是部分的配置节点不适用于ASP.NET MVC，比如页面访问授权配置。  <li>公用性的组件模块：在ASP.NET MVC中，包括Membership，healthMonitoring，httpModule,trace在内的内置和自定义的组件模块仍然是继续可用。  <li>部分服务器控件可用：首先，最为明显的是我们使用的是.aspx页面作为MVC的View。虽然后缀仍然为.aspx，但是它的意义已经不再是一个可执行的页面文件了，不再是一个纯粹意义上的IHttpHandler。但是它仍然是继承于原有的Page基类。在ASP.NET MVC中，将它作为View来展示，仍然以ProcessRequest为入口来执行页面，也就意味着除了回发事件的相关事件和函数不会被执行外，页面的执行事件流程仍然是有效的。以此，如果不考虑服务器控件的性能和其它因素影响，我们仍然是可以使用大部分的服务器控件，当然用不用取决于你。</li></ol> <p>以上是我总结到的一些ASP.NET MVC对ASP.NET原有技术的继承，但是做为ASP.NET技术的发展，有很多东西是本身就是乏善可陈的，不说，也应该知道就是那样。但是说出来，更有助于大家来区分ASP.NET，(ASP.NET)WebForm，ASP.NET MVC(为什么WebForm前面的ASP.NET加括弧呢？大家来说说原因)这三者的概念区别和关系。</p> <p>下面我还想来说说，ASP.NET MVC较之前的ASP.NET(WebForm)开发技术在实践上有哪些比较明显的区别：</p> <ol> <li>.aspx文件，已经不再是一个可被独立请求的页面了。你不能对它从物理上进行权限控制。  <li>我们的少用服务器控件了。我们仍然可以使用，你完全可以不考虑runat='server'的性能影响。但是并不保证所有的服务器控件都可用。可能还有其它的原因让你选择不使用服务器控件。  <li>我们没有PostBack和页面回发事件机制了。提交表单我们基本使用Web的原生方式了，传输的数据量也更为合理。  <li>我们少用ViewState了。少用，意味着我们还是可以用的。只是由于MVC架构的限制，我们在ViewState存的值并不会被序列化到客户端去，它有效性是在一次请求的上下文中。在某些特定的场合内，ViewState还是能发挥它的余热，并且并不影响性能。  <li>要处理一个用户的自定义请求，比如RSS请求。我们不再需要定义一个IHttpHandler或特定的.aspx页面。处理用户的每个请求都只是在一个Controller的Action函数当中，在Action函数中，你可以输出View，可以输出JSON字符串，还可以输出任何自定义格式的文件和输出流。  <li>业务逻辑与UI逻辑从架构上得到了很好的分离，但是你要不想这么做，仍然也是有效的。只是在这种情况下，你还是选择WebForm吧。</li></ol> <p>ASP.NET MVC和WebForm在很多实现上的统一，是我们已经掌握ASP.NET原有开发模式的开发人员顺利的上手MVC保证。之后陆续会有几篇我在用MVC实践自己一个<a href="http://www.zazuone.com">网站</a>后，对MVC的一些总结和心得。</p><img src ="http://www.cnblogs.com/hjf1223/aggbug/1238507.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41275/" target="_blank">[新闻]Mozilla将于本周五发布Firefox 3.1第一个预览版</a>]]></description></item><item><title>Visual Studio 2008 Error: The web services enumeration components are not available. You need to reinstall Visual Studio to add web references to your application.</title><link>http://www.cnblogs.com/hjf1223/archive/2008/06/26/1230291.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Thu, 26 Jun 2008 03:57:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/06/26/1230291.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1230291.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/06/26/1230291.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1230291.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1230291.html</trackback:ping><description><![CDATA[<p>今天在Visual Studio 2008中引用WebService，出现这样的错误提示：</p> <p>The web services enumeration components are not available. You need to reinstall Visual Studio to add web references to your application.</p> <p>在中文社区中没有找到相关的解决办法，通过国外的一个博客找到了解决方案：</p> <p><em>运行：devenv /resetskippkgs</em></p> <p>这个办法至少对<a href="http://paradigma.pt/ja/slog/index.php/2007/03/error-the-web-services-enumeration-components-are-not-available.html">他</a>，对我都是有效的。</p><img src ="http://www.cnblogs.com/hjf1223/aggbug/1230291.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41274/" target="_blank">[新闻]瑞星将向个人用户免费1年</a>]]></description></item><item><title>读取纯真IP数据库的公用组件QQWry.NET</title><link>http://www.cnblogs.com/hjf1223/archive/2008/06/19/QQWry_net.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Thu, 19 Jun 2008 12:25:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/06/19/QQWry_net.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1226174.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/06/19/QQWry_net.html#Feedback</comments><slash:comments>26</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1226174.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1226174.html</trackback:ping><description><![CDATA[<p>这是一个读取纯真IP数据库的公用组件接口，我是通过luma的《<a href="http://lumaqq.linuxsir.org/article/qqwry_format_detail.html">纯真IP数据库格式详解</a>》了解了纯真IP数据库数据格式，并且基于网络上的一个IPLocation.dll源码的基础改编而来。我为什么要改编这个组件呢？因为我看到这个组件在使用过程中，每次都要打开文件流，并且整个接口使用静态的属性。并不适合Web环境下，多线程并发查询的需求，并且在性能上也不是最优。有了luma的格式详解，和现有的IPLocation.dll的源码，使我的工作变得异常的简单。出现的一个小错误，也是经过一次调试后就解决了。性能较IPLocation.dll也有较大的提高，虽然只有短短的几百行代码，虽然网上也有很多类似的代码，但继承我一贯的做法，我仍然把这个组件开源贡献出来。下面是一些接口使用的介绍：</p><pre class="code">QQWry.NET.<span style="color: #2b91af">QQWryLocator </span>qqWry = <span style="color: blue">new </span>QQWry.NET.<span style="color: #2b91af">QQWryLocator</span>(<span style="color: #a31515">"qqwry.dat"</span>);<span style="color: green">//初始化数据库文件，并获得IP记录数，通过Count可以获得

</span>QQWry.NET.<span style="color: #2b91af">IPLocation </span>ip = qqWry.Query(<span style="color: #a31515">"120.67.217.7"</span>);  <span style="color: green">//查询一个IP地址
</span><span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"{0} {1} {2}"</span>, ip.IP, ip.Country, ip.Local); </pre><pre class="code">以下是与IPLocation.dll在性能上的对比代码：</pre>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.39%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 244px; background-color: #f4f4f4">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> Stopwatch stopwatch = <span style="color: #0000ff">new</span> Stopwatch();</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> List&lt;<span style="color: #0000ff">string</span>&gt; ips = <span style="color: #0000ff">new</span> List&lt;<span style="color: #0000ff">string</span>&gt; { <span style="color: #006080">"218.5.3.128"</span>, <span style="color: #006080">"120.67.217.7"</span>, <span style="color: #006080">"125.78.67.175"</span>, <span style="color: #006080">"220.250.64.23"</span>, <span style="color: #006080">"218.5.3.128"</span>, <span style="color: #006080">"120.67.217.7"</span>, <span style="color: #006080">"125.78.67.175"</span>, <span style="color: #006080">"220.250.64.23"</span> };</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> stopwatch.Start();</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i = 0; i &lt; 100; i++)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span> {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>    <span style="color: #0000ff">foreach</span> (<span style="color: #0000ff">string</span> item <span style="color: #0000ff">in</span> ips)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>    {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>         ip = qqWry.Query(item);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>       <span style="color: #008000">// Console.WriteLine("{0} {1} {2}", ip.IP, ip.Country, ip.Local);</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>    }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span> }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>&nbsp; </pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span> stopwatch.Stop();</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span> Console.WriteLine(<span style="color: #006080">"QQWryLocator 花了{0} ms"</span>, stopwatch.ElapsedMilliseconds);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  15:</span>&nbsp; </pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  16:</span> stopwatch.Reset();</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  17:</span> stopwatch.Start();</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  18:</span> <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i = 0; i &lt; 100; i++)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  19:</span> {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  20:</span>    <span style="color: #0000ff">foreach</span> (<span style="color: #0000ff">string</span> item <span style="color: #0000ff">in</span> ips)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  21:</span>    {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  22:</span>        <span style="color: #0000ff">string</span> s = IPLocation.IPLocation.IPLocate(<span style="color: #006080">"qqwry.dat"</span>, item);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  23:</span>       <span style="color: #008000">// Console.WriteLine(s);</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  24:</span>    }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  25:</span> }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  26:</span> stopwatch.Stop();</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  27:</span> Console.WriteLine(<span style="color: #006080">"IPLocation 花了{0} ms"</span>, stopwatch.ElapsedMilliseconds);</pre></div></div>
<p>性能比较结果：</p>
<p><a href="http://www.cnblogs.com/images/cnblogs_com/hjf1223/WindowsLiveWriter/IPQQWry.NET_11EFE/image_6.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="319" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/hjf1223/WindowsLiveWriter/IPQQWry.NET_11EFE/image_thumb_2.png" width="769" border="0"></a>&nbsp;</p>
<p><a href="http://downloads.cnblogs.com/hjf1223/QQWry.NET.rar">源码和示例下载</a>。</p>
<p>阿不</p><img src ="http://www.cnblogs.com/hjf1223/aggbug/1226174.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41273/" target="_blank">[新闻]中国互联网历史上最伟大的产品TOP10（二）</a>]]></description></item><item><title>利用script标签实现的跨域名AJAX请求（ExtJS）</title><link>http://www.cnblogs.com/hjf1223/archive/2008/05/31/1211221.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Sat, 31 May 2008 13:38:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/05/31/1211221.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1211221.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/05/31/1211221.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1211221.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1211221.html</trackback:ping><description><![CDATA[摘要: 在AJAX应用环境中，由于安全的原因，浏览器不允许XMLHttpRequest组件请求跨域资源。在很多情况下，这个限制给我来带来的诸多不便。很多同行，研究了各种各样的解决方案： 1.通过修改document.domain和隐藏的IFrame来实现跨域请求。这种方案可能是最简单的一种跨域请求的方案，但是它同样是一种限制最大的方案。首先，它只能实现在同一个顶级域名下的跨域请求；另外，当在一个页面中还包&nbsp;&nbsp;<a href='http://www.cnblogs.com/hjf1223/archive/2008/05/31/1211221.html'>阅读全文</a><img src ="http://www.cnblogs.com/hjf1223/aggbug/1211221.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41271/" target="_blank">[新闻]盖茨官方否认天价租楼看奥运 纯属地产商炒作</a>]]></description></item><item><title>在IE中测试调用Web Service</title><link>http://www.cnblogs.com/hjf1223/archive/2008/05/12/1194116.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Mon, 12 May 2008 14:24:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/05/12/1194116.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1194116.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/05/12/1194116.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1194116.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1194116.html</trackback:ping><description><![CDATA[<p>使用.NET 开发Web Service，有一个很方便的功能就是可以通过IE直接测试Web Service。当你的Web Service的参数都是元数据类型，那么只要你使用IE浏览Web Service就可以页面的输入框中输入必需的参数，点击调用，即可完成Web Service的测试调用。方便！</p> <p>但是，在有些情况下，虽然我们开发的Web Service都使用元数据类型的参数，为什么死活都无法直接调用测试呢？点击方法链接也只是出现SOAP消息的格式定义？原来这个问题一直都没有解决，google一下就可以找到解决办法了，只要我们在web.config中的system.web配置节点下增加这一段配置即可：</p> <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"> <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">&lt;</span><span style="color: #800000">webServices</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span>    <span style="color: #0000ff">&lt;</span><span style="color: #800000">protocols</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>      <span style="color: #0000ff">&lt;</span><span style="color: #800000">add</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="HttpPost"</span> <span style="color: #0000ff">/&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>      <span style="color: #0000ff">&lt;</span><span style="color: #800000">add</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="HttpGet"</span> <span style="color: #0000ff">/&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>      <span style="color: #0000ff">&lt;</span><span style="color: #800000">add</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="HttpPostLocalhost"</span> <span style="color: #0000ff">/&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">protocols</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span> <span style="color: #0000ff">&lt;/</span><span style="color: #800000">webServices</span><span style="color: #0000ff">&gt;</span></pre></div></div>
<p>相关资料：<a title="http://msdn.microsoft.com/en-us/library/aa560062.aspx" href="http://msdn.microsoft.com/en-us/library/aa560062.aspx">http://msdn.microsoft.com/en-us/library/aa560062.aspx</a></p><img src ="http://www.cnblogs.com/hjf1223/aggbug/1194116.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41270/" target="_blank">[新闻]2008年7月24日IT博客精选</a>]]></description></item><item><title>微软整体IT安全方案与SharePoint 2007成功案例展示——ITProCity福州站邀请函</title><link>http://www.cnblogs.com/hjf1223/archive/2008/05/07/ITPro_event1.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Wed, 07 May 2008 04:37:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/05/07/ITPro_event1.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1186638.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/05/07/ITPro_event1.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1186638.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1186638.html</trackback:ping><description><![CDATA[<p>受拖发布这份邀请，有兴趣参加的朋友，请留言下你的邮箱申请，时间紧迫名额有限请赶快申请。</p> <p><i>本周六5</i><i>月10</i><i>日在福州外贸中心酒店10</i><i>楼会议室 </i>举行的福建ITPro交流活动，  <p>这是省内由微软举办的第一次IT行业专家交流会，届时我们会邀请微软最有价值专家及微软资深讲师与各位分享沟通技术热点及解决方案，希望能有机会与各位IT精英现场交流。  <p>具体安排如下：&nbsp; </p><i>如果无法正常显示，请访问：<a href="http://www.itprocity.com/event/edm/edm20080510_fuz.htm" target="_blank">http://www.itprocity.com/event/edm/edm20080510_fuz.htm</a></i>  <table cellspacing="0" cellpadding="0" width="770" bgcolor="#ffffff" border="0"> <tbody> <tr> <td colspan="2"><a href="mailto:owen@owencn.net" target="_blank"><img height="216" src="http://www.itprocity.com/event/edm/images/20080403-edm-header.png" width="770" border="0"></a></td></tr> <tr> <td style="padding-right: 72px; padding-left: 72px; padding-bottom: 4px; padding-top: 4px" width="50%" colspan="2"> <div id="title">微软整体IT安全方案与SharePoint 2007成功案例展示</div> <table width="100%"> <tbody> <tr valign="top"> <td id="left" style="padding-right: 12px"><em>活动时间：05月10日 / 14:00-17:00 / 13:30开始签到</em>  <p>信息系统给企业带来了诸多便利，越来越多的信息通过网络进行高效的传递，同时也带来了全新的挑战，即如何保护我们的系统，使它们能够在不断演变、日益增多的安全风险中安然无恙，微软有没有专门争对安全的整体方案呢？IT整体安全策略 SharePoint Server 2007是一个好平台，这大家都知道，但大部分都碰到一个问题，如何应用？能帮助企业实现什么？能给企业带来什么价值？由中国移动福建公司泉州分公司成功案例的分享，将会给我们带来一个最好的学习机会。 </p> <p><strong>日程安排</strong> <u>13:30-14:00</u>　来宾签到<br><u>14:00-14:30</u>　福建ITPRO团队介绍<br><u>14:30-15:20</u>　微软IT整体安全策略<br><u>15:20-15:40</u>　休息、交流<br><u>15:40-16:30</u>　SharePoint 2007中国移动成功案例<br><u>16:30-17:00</u>　填写反馈表/交流/Q&amp;A</p><em>联 系 人：王冬兴<br>报名电话：13313783437<br>报名邮箱：<a href="mailto:owen@owencn.net" target="_blank">owen@owencn.net</a></em>  <p><strong>ITProCity简介</strong> 　　ITProCity是一个面向IT专业人士及其团队的会员制联盟组织，面向所有IT专业人士开放，符合条件的IT专业人士和IT专业人士团队都可以成为ITProCity的会员。<br>　　ITProCity 致力构建一个社区协助平台，帮助IT专业人士及其团队沟通交流、获取知识、提升技能、实现价值；并帮助IT专业人士及其团队与主流IT厂商之间建立良好的互动关系。 </p></td> <td id="right" style="border-right: #abc7ff 1px dashed; padding-right: 12px; border-top: #abc7ff 1px dashed; padding-left: 12px; padding-bottom: 12px; border-left: #abc7ff 1px dashed; color: #325495; padding-top: 12px; border-bottom: #abc7ff 1px dashed" width="104" bgcolor="#e5ebff"><b>讲师介绍</b> <strong>宋立桓</strong>MVP <strong>雷君</strong>MVP <br><br><br><b>活动地点</b> <a href="http://www.tw128.com/UpLoadPic/hotel/2007759434055558.JPG"><img height="78" src="http://www.itprocity.com/event/edm/images/20080403-edm-maps.gif" width="104" border="0"></a> <strong>福州外贸中心酒店10楼小会议室</strong> 福州 鼓楼区 五四路73号</td></tr></tbody></table><br></td></tr> <tr> <td style="padding-right: 72px; padding-left: 72px; padding-bottom: 4px; padding-top: 4px" colspan="2"> <div align="right">ITProCity团队<br>福建ITPRO团队<br>2008年05月<br> <hr color="#cccccc" noshade size="1"> </div></td></tr></tbody></table><img src ="http://www.cnblogs.com/hjf1223/aggbug/1186638.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41269/" target="_blank">[新闻]TOM在线与Joost正式组建合资公司</a>]]></description></item><item><title>深入ASP.NET数据绑定（下）——多样的绑定方式</title><link>http://www.cnblogs.com/hjf1223/archive/2008/05/05/digging_into_binding_expression_3.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Mon, 05 May 2008 14:32:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/05/05/digging_into_binding_expression_3.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1183933.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/05/05/digging_into_binding_expression_3.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1183933.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1183933.html</trackback:ping><description><![CDATA[摘要: 在这个系列的上篇中介绍了数据绑定语法的原理以及.NET中如何实现单向绑定，中篇我们简单的介绍了ASP.NET 2.0 中新增的Bind语法配合DataSourceControl来实现数据的自动双向绑定。这两部分的内容相对动态抽象并且不常接触，没有很好的源代码支持很难解释清楚，要想真正弄清它们的内部原理，还需要大家亲自动手去反编译分析动态编译的程序集。 在了解了数据绑定语法的原理后，我还想来谈谈我中&nbsp;&nbsp;<a href='http://www.cnblogs.com/hjf1223/archive/2008/05/05/digging_into_binding_expression_3.html'>阅读全文</a><img src ="http://www.cnblogs.com/hjf1223/aggbug/1183933.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41268/" target="_blank">[新闻]财富:谷歌副总裁称其新闻搜索值1亿美元</a>]]></description></item><item><title>深入ASP.NET数据绑定（中）——数据双向绑定机理</title><link>http://www.cnblogs.com/hjf1223/archive/2008/05/04/digging_into_binding_expression_2.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Sun, 04 May 2008 14:15:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/05/04/digging_into_binding_expression_2.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1182399.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/05/04/digging_into_binding_expression_2.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1182399.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1182399.html</trackback:ping><description><![CDATA[<p>在上一篇《<a href="http://www.cnblogs.com/hjf1223/archive/2008/05/03/digging_into_binding_expression_1.html">深入ASP.NET数据绑定（上）</a>》中，我们分析了在.NET中的数据绑定语法的一些内部机理。简单说来就是ASP.NET在运行时为我们完成了页面的动态编译，并解析页面的各种服务器端代码，包括数据绑定语法。而数据绑定的语法虽是一些&lt;%# %&gt;代码块，在生成的代码中，仍然使用了服务器端控件以及在DataBinding事件调用DataBinder.Eval方法来完成数据的绑定工作。所有的数据绑定模板控件都使用了这样的机制来进行数据的单向绑定，在.NET 2.0中新增了双向的数据绑定方式，主要用在GridView,DetailsView,FormView等数据容器控件中，结合DataSourceControl就可以非常轻松的完成数据的更新和提交工作，而不需要我们手工去遍历输入控件的值。那在这样的双向数据绑定中，ASP.NET又是做了哪些工作，来为我们透明输入控件与字段的取值与对应关系，让我们可以在DataSouceControl中方便得到数据项修改前的值和修改后的值？下面就让我们一起来从一段页面代码开始吧：</p> <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; max-height: 200px"> <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">&lt;</span><span style="color: #800000">asp:DetailsDataSouce</span> <span style="color: #ff0000">ID</span><span style="color: #0000ff">="DetailsDataSouce1"</span> <span style="color: #ff0000">runat</span><span style="color: #0000ff">="server"</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> <span style="color: #0000ff">&lt;/</span><span style="color: #800000">asp:DetailsDataSouce</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> <span style="color: #0000ff">&lt;</span><span style="color: #800000">asp:DetailsView</span> <span style="color: #ff0000">ID</span><span style="color: #0000ff">="detailsView"</span> <span style="color: #ff0000">runat</span><span style="color: #0000ff">="server"</span> <span style="color: #ff0000">DefaultMode</span><span style="color: #0000ff">="Edit"</span> <span style="color: #ff0000">DataSourceID</span><span style="color: #0000ff">="DetailsDataSouce1"</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     <span style="color: #0000ff">&lt;</span><span style="color: #800000">Fields</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>         <span style="color: #0000ff">&lt;</span><span style="color: #800000">asp:TemplateField</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>             <span style="color: #0000ff">&lt;</span><span style="color: #800000">HeaderTemplate</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>                 电流:<span style="color: #0000ff">&lt;/</span><span style="color: #800000">HeaderTemplate</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>             <span style="color: #0000ff">&lt;</span><span style="color: #800000">EditItemTemplate</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>                 <span style="color: #0000ff">&lt;</span><span style="color: #800000">asp:TextBox</span> <span style="color: #ff0000">ID</span><span style="color: #0000ff">="textBox1"</span> <span style="color: #ff0000">runat</span><span style="color: #0000ff">="server"</span> <span style="color: #ff0000">Text</span><span style="color: #0000ff">='&lt;%# Bind("[电流{a}]") %&gt;'</span><span style="color: #0000ff">&gt;&lt;/</span><span style="color: #800000">asp:TextBox</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>             <span style="color: #0000ff">&lt;/</span><span style="color: #800000">EditItemTemplate</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span>         <span style="color: #0000ff">&lt;/</span><span style="color: #800000">asp:TemplateField</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>     <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Fields</span><span style="color: #0000ff">&gt;</span></pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span> <span style="color: #0000ff">&lt;/</span><span style="color: #800000">asp:DetailsView</span><span style="color: #0000ff">&gt;</span></pre></div></div>
<p>在一个页面中，定义了如上的一个DetailsView控件，为这个控件指定了ID为DetailsDataSource1的DataSouceControl控件，这个控件是我们自己定义的一个DataSourceControl，它返回的数据字段包括："ID"，"电流{a}"，"电压(v)"，"备注'"，"名称]"。我并没有设置DetailsView的<span style="color: red">AutoGenerateRows</span>属性的值，默认情况下，它是为我们自动的生成这些字段的对应的数据显示和输入控件。除此之外，我们还另外添加了一个数据模板字段，在这个模板中指定了编辑模板。在编辑模板中我使用了&lt;%# Bind("")%&gt;这样的语法，将textBox1与"[电流{a}]"字段双向绑定起来。</p>
<p><img alt="Thumbsup" src="http://www.cybergifs.com/faces/thumbsup2.gif"><font color="#ff0000">为什么这里的字段都有一些特殊呢？因为我原先的意图是除了分析绑定语法以外，还要测试哪些特殊字符无法使用数据绑定语法来绑定数据的。这个在下篇文章中会具体介绍。</font></p>
<p><img alt="Thumbsup" src="http://www.cybergifs.com/faces/thumbsup2.gif"><font color="#ff0000">Bind与Eval不一样，这样的Bind并不Page或TemplateControl的一个方法，事实上我们应该把它当成一个关键字来看待，因为在ASP.NET的双向数据绑定当中，并没有这样的一个函数存在，它的存在是只是告诉ASP.NET动态编译页面类时，将这个语法编译成一定的代码格式，并生成一些函数代理来达到双向数据交流的目的。</font></p>
<p>那么这一段代码，动态编译生成的服务器代码又是如何的呢？让我们反编译动态程序集，里面会找到用于创建DetailsView的__BuildControldetailsView的私有方法，在这里会调用到一些其它内部方法，我们不要让这些方法来干扰我们的视线，直接找到创建如上模板字段的方法：</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> [DebuggerNonUserCode]</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> <span style="color: #0000ff">private</span> TemplateField __BuildControl__control5()</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     TemplateField field = <span style="color: #0000ff">new</span> TemplateField();</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>     field.HeaderTemplate = <span style="color: #0000ff">new</span> CompiledTemplateBuilder(<span style="color: #0000ff">new</span> BuildTemplateMethod(<span style="color: #0000ff">this</span>.__BuildControl__control6));</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>     field.EditItemTemplate = <span style="color: #0000ff">new</span> CompiledBindableTemplateBuilder(<span style="color: #0000ff">new</span> BuildTemplateMethod(<span style="color: #0000ff">this</span>.__BuildControl__control7), <span style="color: #0000ff">new</span> ExtractTemplateValuesMethod(<span style="color: #0000ff">this</span>.__ExtractValues__control7));</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>     <span style="color: #0000ff">return</span> field;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span> }</pre></div></div>
<p>这里首先把this.__BuildControl__control6作为一个代理函数，用于创建头部模板的内容，也就是如上的“电流：”字段标题。然后才是创建EditItemTemplate，这个模板又被一些的中介模板所代替，我们只需要来关心this.__BuildControl__control7和__ExtractValues__control7即可。__BuildControl__control7是为了编辑数据字段时，将数据字段的值显示在输入控件中（输入控件的初始化，即字段值绑定到输入控件中）；而__ExtractValues__control7则是在提交数据时，要找出这个模板内所有的双向绑定字段，将这些字段的值以绑定字段名为Key，以输入控件的值为Value添加了IOrderedDictionary字典中。DetailsView等数据绑定控件调用这些委托代理来收集所有的被双向绑定的字段的最新的值。下面分别是两段函数的代码片段：</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> [DebuggerNonUserCode]</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> <span style="color: #0000ff">private</span> TextBox __BuildControl__control8()</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     TextBox box = <span style="color: #0000ff">new</span> TextBox();</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>     box.TemplateControl = <span style="color: #0000ff">this</span>;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>     box.ApplyStyleSheetSkin(<span style="color: #0000ff">this</span>);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>     box.ID = <span style="color: #006080">"textBox1"</span>;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>     box.DataBinding += <span style="color: #0000ff">new</span> EventHandler(<span style="color: #0000ff">this</span>.__DataBinding__control8);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>     <span style="color: #0000ff">return</span> box;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span> }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> __DataBinding__control8(<span style="color: #0000ff">object</span> sender, EventArgs e)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span> {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span>     TextBox box = (TextBox) sender;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span>     IDataItemContainer bindingContainer = (IDataItemContainer) box.BindingContainer;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  15:</span>     <span style="color: #0000ff">if</span> (<span style="color: #0000ff">this</span>.Page.GetDataItem() != <span style="color: #0000ff">null</span>)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  16:</span>     {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  17:</span>         box.Text = Convert.ToString(<span style="color: #0000ff">base</span>.Eval(<span style="color: #006080">"[电流{a}]"</span>), CultureInfo.CurrentCulture);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  18:</span>     }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  19:</span> }</pre></div></div>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> [DebuggerNonUserCode]</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> <span style="color: #0000ff">public</span> IOrderedDictionary __ExtractValues__control7(Control __container)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     TextBox box = (TextBox) __container.FindControl(<span style="color: #006080">"textBox1"</span>);</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>     OrderedDictionary dictionary = <span style="color: #0000ff">new</span> OrderedDictionary();</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>     <span style="color: #0000ff">if</span> (box != <span style="color: #0000ff">null</span>)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>     {</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>         dictionary[<span style="color: #006080">"[电流{a}]"</span>] = box.Text;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>     }</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>     <span style="color: #0000ff">return</span> dictionary;</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span> }</pre></div></div>
<p>由上面的代码片段可以了解到，ASP.NET动态编译器是将Bind语法拆分为两部分：绑定输出和读取输入控件值。绑定输出部分与前篇介绍的机制是完全一样的，并且也是调用DataBinder.Eval方法来绑定数据；而读取输入控件值则是会根据页面上控件的类型，以及绑定的控件属性名称，生成一段强类型的控件属性读取代码，并将控件的值保存到dictionay中返回出去。而它全然不知，容器控件是如何将这些值合并起来传给对应的DataSouceControl控件的。</p>
<p><img alt="Thumbsup" src="http://www.cybergifs.com/faces/thumbsup2.gif"><font color="#ff0000">关于数据容器控件而何与DataSouceControl协同工作，并不是我们这里要分析的重点。但是我们可以简单的描述一下工作流程，以DetailsView的数据更新为例：大家通过反编译DetailsView的源码，会找到名称为HandleUpdate的私有方法，在这个方法里面会去处理数据项更新前的值(至于在Web环境中如何保存更新前的值，就需要靠ViewState的强大功能了)，和更新后的值(通过ExtractRowValues函数调用类似上面生成的__ExtractValues__control7代理函数来收集所有双向绑定字段的值存到NewValues里面)，并将他们分别保存在两个不同的IOrderedDictionary对象（OldValues，NewValues）中。然后将调用对应的DataSouceView的Update方法，传入原字段值和新字段值和一些必须的参数，即可由我们通过重写DataSourceView的方法来得到所有需要更新字段的原始值和新值，并可以对比比较哪些字段值是否发生了变化。NBearDataSource控件就是利用了这样的机制来直接重DataSourceControl和DataSourceView来达到数据的全自动修改和添加方案的。</font></p>
<p>这里还有一点不得不说，在GridView,DetailsView，并不一定需要使用&lt;%# Bind("")%&gt;语法来实现数据的双向绑定，他们的字段双向绑定可以通过BoundField及它的子控件代替模板控件的绑定语法，一样可以达到双向绑定的目的，简单但没有模板来得灵活。而在存取不同版本的字段值也是类似的机制。</p>
<p>由于这部分涉及到的都是动态和内部代码，如果没有亲自去阅读这些代码，估计还是很难理解。最后我们再来简单总结一下：ASP.NET在模板中双向绑定字段，是通过&lt;%# Bind() %&gt;这样的语法，但是Bind我们更应该把它理解为是一个关键字，而不是一个函数。因为在ASP.NET的控件中，并没有存在这个函数。ASP.NET运行时在编译页面代码时，会把Bind关键字的代码当成两部分来编译：一部分是单向绑定代码；另一部分而是读取对应输入控件的绑定属性，以绑定字段名为Key，添加到IOrderedDictionary中收集返回给数据容器控件（GridView,DetailsView,FormView）等，让它们处理。</p>
<p>总体来说，ASP.NET 2.0的双向绑定机制给我们在提交数据时带来了极大的方便，尽管有些人很排斥DataSourceControl的模式，但是我们不可否认合理应用会大大提高我们的开发效率。希望通过这两篇的介绍，我们能对ASP.NET数据绑定机制有更多的认识。在下一篇的文章中，我们将会介绍一些关于数据绑定方式，性能，以及对字段名的局限性等相关主题。</p>
<p><a href="http://www.cnblogs.com/Files/hjf1223/ColumnName.rar">附上示例工程</a>，本文分析面页是Default3.aspx和App_Web_ryn6wtvv.dll程序集。</p>
<p><font color="#ff0000">系列导航:</font></p>
<p><a href="http://www.cnblogs.com/hjf1223/archive/2008/05/03/digging_into_binding_expression_1.html"><font color="#ff0000">深入ASP.NET数据绑定（上）</font></a></p>
<p><a href="http://www.cnblogs.com/hjf1223/archive/2008/05/05/digging_into_binding_expression_3.html"><font color="#ff0000">深入ASP.NET数据绑定（下）——多样的绑定方式</font></a></p><img src ="http://www.cnblogs.com/hjf1223/aggbug/1182399.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41267/" target="_blank">[新闻]Ubuntu创始人呼吁开发Linux桌面软件对抗苹果</a>]]></description></item><item><title>深入ASP.NET数据绑定（上）</title><link>http://www.cnblogs.com/hjf1223/archive/2008/05/03/digging_into_binding_expression_1.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Sat, 03 May 2008 15:05:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/05/03/digging_into_binding_expression_1.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1180962.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/05/03/digging_into_binding_expression_1.html#Feedback</comments><slash:comments>33</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1180962.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1180962.html</trackback:ping><description><![CDATA[摘要: 在ASP.NET我们在使用Repeater，DetailsView，FormView，GridView等数据绑定模板时，都会使用<%# Eval("字段名") %>或<%# Bind("字段名") %>这样的语法来单向或双向绑定数据。但是我们却很少去了解，在这些语法的背后，ASP.NET究竟都做了哪些事情来方便我们使用这样的语法来绑定数据。究竟解析这样的语法是在编译时，还是运行时？如果没有深入去了解，我们肯定不得而知。这个简短的系列文章就是带我们大家一起去深入探究一下ASP.NET绑定语法的内部机理，以让我们更加全面的认识和运用它。&nbsp;&nbsp;<a href='http://www.cnblogs.com/hjf1223/archive/2008/05/03/digging_into_binding_expression_1.html'>阅读全文</a><img src ="http://www.cnblogs.com/hjf1223/aggbug/1180962.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41266/" target="_blank">[新闻]央视国际联手微软打造数字奥运媒体平台</a>]]></description></item><item><title>LumaQQ.NET Preview 3 发布——新增群信息功能</title><link>http://www.cnblogs.com/hjf1223/archive/2008/04/22/lumaqq_net_preview3.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Tue, 22 Apr 2008 14:15:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/04/22/lumaqq_net_preview3.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1166331.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/04/22/lumaqq_net_preview3.html#Feedback</comments><slash:comments>46</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1166331.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1166331.html</trackback:ping><description><![CDATA[<p><font color="#ff0000">版权声明：该开源开发包，是基于LumaQQ的基于等价移植到.NET平台下，开发者不直接参与QQ协议的分析工作，移植到.NET平台纯粹是为了方便广大.NET开发者学习和研究之用，并且没有产生任何直接的经济效益，并且纯粹是个人的技术学习研究行为，与本人所在单位没有任何关系。此开发包的用户在使用过程产生的效益和涉及的法律责任与本人没有直接关系。如果影响到您或您的公司利益，敬请谅解并且与我联系，本人会第一时间作出处理。本系列章首发且单发于博客园，由于各种原因不欢迎转载本系列文章，如果您转载了该系列文章请自行承担责任并且转载完整版本，包括版权声明。</font></p> <p>首先要向所有关心LumaQQ.NET发展的朋友们道个歉，因为距上一次版本更新已经过去了一个多月的时间了，新版本一直迟迟都没有发布。在这段时间里，由于一些个人原因，没有时间和精力投入到新版本的开发当中来，让大家失望了。最近很多人都在问，LumaQQ.NET希望做得什么程度。我目前的定位是：以Lumaqq2005的协议为蓝本，基本能做到简单的文本信息收发功能即可，不打算去分析更新的协议，也不找算做到能基本代替官方QQ的程度，因为我们是定位在机器人开发包的级别。如果有让您失望，还请谅解。关于更详细的开发计划请参考：<a href="http://space.cnblogs.com/group/topic/1717/">关于LumaQQ.NET未来开发计划</a></p> <p>在Preview 3当中，我们主要增加了群消息的功能（但不包括群管理功能），还修复和完善了之前存在的一些不足和BUG，下面就来简单了解下：</p> <h4>框架完善部分</h4> <ol> <li>使用了新的ByteBuffer，可以解决可能存在的内存使用不合理的问题（感谢<a href="http://space.cnblogs.com/22667/">Red_angelX</a>的提醒和提供这么好的一个类）  <li>完善信息发送接口,可以收发长信息（感谢<a href="http://space.cnblogs.com/lersh/">蓝色的风之精灵</a>的贡献）  <ul> <li>关于如何实现收发长信息可以参考<a href="http://space.cnblogs.com/lersh/">蓝色的风之精灵</a>的两篇文章<a href="http://www.cnblogs.com/lersh/archive/2008/04/22/1165451.html">修改LumaQQ.NET，使其支持长消息发送</a>和<a href="http://www.cnblogs.com/lersh/archive/2008/04/22/1165919.html">使LumaQQ.NET支持接收长消息</a></li></ul> <li>可以解析默认表情(解析成[face0.gif]等格式,由用户去替换)和自定义表情(文件名) （感谢<a href="http://space.cnblogs.com/lersh/">蓝色的风之精灵</a>的贡献）  <ul> <li>关于解析表情同样请参考<a href="http://space.cnblogs.com/lersh/">蓝色的风之精灵</a>的文章<a href="http://www.cnblogs.com/lersh/archive/2008/04/21/1163565.html">关于转换QQ消息中系统表情，自定义表情和截图的函数</a>。与之不同的是，我把默认表情都解析成[face{0}.gif]的格式，大家可以根据需要再去替换。</li></ul> <li>修复了一些已知的bug，包括之前的天气预报日期问题和QQ注销后程序不退出会出错的问题等。</li></ol> <h4>新增功能部分，主要新功能群信息的功能</h4> <ol> <li>得到我加入的群列表。  <ul> <li>这个功能需要使用好友管理的读取好友列表的功能，在返回的好友列表中有两种好：普通好友和群好友。大家只要根据定义的类型来判断就可以得到所加入的群列表，如：<span style="color: blue">if</span>(friend.Type == <span style="color: #2b91af">FriendType</span>.IS_CLUSTER)<a href="http://11011.net/software/vspaste"></a></li></ul> <li>接收群消息和群通知的功能  <ul> <li>这个功能分为几个事件，这些事件的InPacket事件参数类型都为ReceiveIMPacket，但是事件不同，里面的属性字段使用不同，同样的，所有的群操作命回复事件包都是ClusterCommandReplyPacket，但是根据事件不同，这个对象的属性使用不同。请大家仔细查阅ClusterCommandReplyPacket的注释说明。  <ul> <li>ReceiveClusterIM：接收到群消息事件  <li>AddedToCluster:被加入到群通知  <li>RemovedFromCluster:被从某个群中移动的通知  <li>ApprovedJoinCluster:群管理员同意我加入群的通知  <li>RejectJoinCluster：群管理员拒绝的加入群的通知  <li>HasRequestedJoinCluster:有人请求加入群的通知</li></ul></li></ul> <li>请求加入群功能，这个功能通过JoinCluster接口发送请求，如果返回结果提示需要发送身份验证，则调用RequestJoinCluster来发送验证信息。加入结果则以系统通知（上面的事件）的形式返回。  <li>根据群ID查找群，通过SearchClusterById发送查找群请求。  <li>退出群，通过调用ExitCluster请求退出群。  <li>发送群信息功能，暂不能分包发送长信息。  <li>修改群名片  <li>刷新群内组织架构  <li>得到单个成员和全部群名片信息  <li>得到群资料，群成员列表（QQ号码）  <li>得到在线成员  <li>得到群成员详细信息</li></ol> <p>以上功能测试基本正常，如果有任何问题或疑问请通过<a href="http://space.cnblogs.com/group/lumaQQ_net">LumaQQ.NET</a>小组交流讨论，同时大家也可以加入LumaQQ.NET QQ群讨论，号码是：22858783 谢谢！</p> <p>另外，在这里要特别感谢<a href="http://space.cnblogs.com/lersh/">蓝色的风之精灵</a>的热心和贡献，解决了一些疑难问题，希望大家再接再厉一起来完善LumaQQ.NET。 </p> <p><a href="http://www.cnblogs.com/Files/hjf1223/LumaQQ.NET.rar">文档和源码下载</a></p> <p><font color="#ff0000">更新：增加了for vs 2005的Preview3。&nbsp; 04/24/2008</font></p><img src ="http://www.cnblogs.com/hjf1223/aggbug/1166331.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41265/" target="_blank">[新闻]Google在线百科工具Knol今日正式上线</a>]]></description></item><item><title>不定时的间隔线程和线程排队执行(LumaQQ.NET异步线程处理)</title><link>http://www.cnblogs.com/hjf1223/archive/2008/04/17/1156596.html</link><dc:creator>阿不</dc:creator><author>阿不</author><pubDate>Thu, 17 Apr 2008 11:18:00 GMT</pubDate><guid>http://www.cnblogs.com/hjf1223/archive/2008/04/17/1156596.html</guid><wfw:comment>http://www.cnblogs.com/hjf1223/comments/1156596.html</wfw:comment><comments>http://www.cnblogs.com/hjf1223/archive/2008/04/17/1156596.html#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://www.cnblogs.com/hjf1223/comments/commentRss/1156596.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/hjf1223/services/trackbacks/1156596.html</trackback:ping><description><![CDATA[<p>在我的这篇文章《<a href="http://www.cnblogs.com/hjf1223/archive/2008/03/06/Framework_Timer.html">.NET Framework中的计时器对象</a>》中，讨论了几种.NET Framework定时器异同之处，以及使用场合。我当时的初忠也是在为<a href="http://www.cnblogs.com/hjf1223/archive/2008/03/11/qq_net.html">LumaQQ.NET</a>寻找一种最合理的线程定时执行和线程排队的方案。因为在LumaQQ中，有需要定时执行的线程，比如发送KeepLive包；有需要不同间隔时间，间隔时间是动态的且不应该是“可重入”（前一个执行还没有完成，又再次进行执行定时任务），比如重发包；有需要在一个独立线程上不定期执行的任务，比如收到包后的事件处理（收到数据包后，程序主线程需要继续去监听数据，而不能在主线程上去进行包的处理工作，这样如果事件代理的执行时间很长的话，主线程的执行周期被占用了，而造成无法及时接收和发送数据包）。在这三种情况下，直接使用Timer组件肯定无法完全满足我们的要求。</p> <p>通过分析Timer组件，我们就很容易发现，他们都是通过<span style="color: #2b91af">ThreadPool</span>这个类的功能来实现定时器的功能。ThreadPool类，提供了对当前进程内的后台线程统一管理，集中调配和资源重用的线程池实现。利用ThreadPool可以实现任务的延迟处理，I/0 异常操作，线程间的互斥执行，定时任务等功能。</p> <p>ThreadPool提供了一系列管理和维护线程池的接口。在LumaQQ.NET中，我需要的功能就是利用：QueueUserWorkItem 和RegisterWaitForSingleObject 这两个接口来实现的。</p> <p>QueueUserWorkItem :让我们可以注册一个排队的异步任务，等到线程池有剩余的线程资源时去异步执行任务。</p> <p>RegisterWaitForSingleObject :让我们可以注册一个等待信号就绪的异步任务，等到该线程等待的信号就绪后异步执行该任务。这个接口等待信号是一个WaitHandle对象，同时还可以指定等待超时（间隔时间），而通过设置executeOnlyOnce参数的值可以指定是否重复执行该任务。</p> <p>了解了ThreadPool的基本情况后，我们就可以来设计我们的异步线程执行框架。首先对异步任务和间隔任务，我们分别定义了两个接口<span style="color: #2b91af">ICallable</span>和<span style="color: #2b91af">IRunable</span>来描述：</p> <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 98.7%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bott