[转载]Jumony入门(三)初探解析器

mikel阅读(1297)

[转载]Jumony入门(三)初探解析器 – Ivony… – 博客园.

首先介绍一下Jumony是什么,Jumony是一个.NET的开源项目,项目主页位于:http://jumony.codeplex.com/,采用LGPL协议发布。

Jumony 试图提供在传统Web开发模型中许多难以解决问题的解决方案。一言蔽之,Jumony的一切基础建立在服务器端的HTML DOM之上。在服务器端将HTML(文件或动态网页技术的输出)按照客户端浏览器的处理方式解析为HTML DOM。操纵和处理HTML DOM,就像我们在客户端用JavaScript干的那些事情一样,不同的是,Jumony可以使你依托强大的.NET Framework,来解决以前用脚本和服务器端技术都难以解决的事情。

系列目录:

Jumony入门(一)从这里开始

Jumony入门(二)初识选择器

这是系列文章的第三篇,这个系列尝试一步步从一些最简单的例子开始了解怎么玩转Jumony。建议先从第一篇开始学习搭建Jumony环境,在本文的开始的时候,假设大家已经搭建好了Jumony的运行环境。

这一次我要谈到Jumony的HTML解析器,显然我自己写的简单的符合规范的HTML并不能说明解析器的功能。所以这一次我直接从互联网上随便抓一个页面来完成示范。

首先在项目中添加一个aspx文件,然后在上面放一个DataGrid来展示我们一会儿要抓取的成果,像是这样:

imageimage

那 么接下来,我们到Code Behind里面来添加一些代码,首先是要下载一个互联网的页面,我用新浪的首页来做示范,事实上你也可以换成任何你喜欢网站(例如博客园),下载网页最 简单的方式当然是WebClient,不过记得添加using System.Net哦,同时我也把Jumony的一些引用都添加上了,像这样:

image

然后创建JumonyParser的实例,并调用其Parse方法将html分析成一个IHtmlDocument:

image

Jumony Milestone 1除了提供Jumony Parser分析HTML文档之外,还可以把HtmlAgilityPack分析的文档转换成Jumony的标准DOM模型。这使得 HtmlAgilityPack也可以当作Jumony的一个Parser来使用,下面的代码展示了这一点:

image

不过,这么做之前要确保你引用了Ivony.Web.Html.HtmlAgilityPackAdaptor命名空间,AsDocument扩展方法便是在其中定义的。

HtmlAgilityPackAdaptor 为HtmlAgilityPack的DOM对象提供了一个适配器,使得其可以满足Jumony标准DOM的要求,从而使用Jumony的方法来操作。理论 上所有的HTML DOM和Parser都可以通过适配项目与Jumony适配。

这两种HTML Parser各有优劣,大家可以任选一种来完成这一次的例子。在这里我使用Jumony Parser来继续下面的例子。

分 析了新浪的首页后,接下来就要干坏事了,首先把新浪首页上所有的链接全部取出来。由于链接都是<a>定义的,所以简单的用Find( “a” )就可以选择出来。但<a>除了可以定义链接,还可以定义锚点,我们并不需要取出页面上的锚点。所以我们用”a[href]”,即包含 href属性的a标签:

image

然 后我们分析这些链接,将其目标URL取出来(即href属性),由于href可能是一个相对链接,所以我们用页面的地址 “http://www.sina.com.cn/” 作为基地址,重新计算出绝对的URL,然后我用LINQ表达式来对所有URL完成这样的操作,再放在一个匿名对象中:

image

可以看得出来,这些工作在服务器端完成的时候,是多么的简洁流畅,一气呵成。如果在客户端来完成这种事情,没有强大的.NET Framework作为后盾,一个简单的URL计算就可以难倒无数英雄好汉。

然后再为匿名对象添加一些其他有趣的属性,对链接排序,最后绑定到DataGrid上,最终的代码像这样:

image

由于DataGrid有自动生成列的特性,所以我们并不需要做些什么,它会自动的弄一个表格来展现这些数据,效果像是这样:

imageimage

把抓取的网页换成博客园首页:

image

写在最后

Jumony的确可以用来干各种各样的坏事,譬如说抓取页面,分析数据,或是新闻小偷什么的。从这一点来说,你可以说Jumony是邪恶的,但软件本来就是邪恶的,Jumony将一些很复杂的事情,提供了简单的解决方案,也许,这降低了干坏事的成本,但更多的时候,Jumony带来了生产力的飞跃。借助Jumony,我们能做的好玩的事情,要比这些邪恶的事情多多了不是么?

谢谢大家。

[转载]房产信息类网站DEDE与51地图结合的办法!

mikel阅读(994)

我所举例不需要修改任何原文件! 在原5.5基础上直接设置即可!
目标:以地图方式显示房产所处位置和信息,并以地图坐标方式控制显示信息!

设置办法:
1建立房产模型
2并建立自定义字段 “h_x”和”h_y” 这两个字段为 坐标传递数值使用!
3但是由于表单页是生成字段为了美观和操作性对两个坐标字段进行设置,经过多次试验在字段修改页“模型字段配置(文本模式) 中”对
<field:h_y itemname=”y” autofield=”1″ notsend=”0″ type=”int” isnull=”true” islist=”0″ default=”” maxlength=”250″ page=””>
</field:h_y>
<field:h_x itemname=”x” autofield=”1″ notsend=”0″ type=”int” isnull=”true” islist=”0″ default=”” maxlength=”250″ page=””>
</field:h_x>

修改成

<field:h_y itemname=”y” autofield=”1″ notsend=”0″ type=”int” isnull=”true” islist=”0″ default=”” maxlength=”250″ page=””>
<table width=”100%” border=”0″ cellpadding=”0″ cellspacing=”0″>
<tr>
<td width=”35%” bgcolor=”#FFFFFF”></font>将您的房屋在地图中标示出来以便浏览。<br>
请完成标注后再进行下面信息的填写。 </td>
<td width=”17%” bgcolor=”#FFFFFF”><div id=”info”><span style=”cursor:pointer;” onClick=”window.open(‘/images/zuobiao.html’,’aa’,’height=500, width=700, top=200, left=100, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no’);”><img src=”/images/bz.gif” width=”147″ height=”38″></span></div></td>
<td width=”48%” bgcolor=”#FFFFFF”> <input name=”h_x” type=”text” class=”yinshang” value=”” size=”1″><span class=”4a” style=”cursor:pointer;” onClick=”window.open(‘/images/zuobiao.html’,’aa’,’height=500, width=700, top=200, left=100, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no’);”><img src=”/images/bzyes1.gif”></span></tr>
</table>
</field:h_y>
<field:h_x itemname=”x” autofield=”1″ notsend=”0″ type=”int” isnull=”true” islist=”0″ default=”” maxlength=”250″ page=””>
<table width=”100%” border=”0″ cellpadding=”0″ cellspacing=”0″>
<tr>
<td width=”35%” bgcolor=”#FFFFFF”> </td>
<td width=”17%” bgcolor=”#FFFFFF”> </td>
<td width=”48%” bgcolor=”#FFFFFF”><input name=”h_y” type=”text” class=”yinshang” value=”” size=”1″></tr>
</table></field:h_x>

这样就可以传递坐标了!
期中使用的文件zuobiao.html 和两张图片我直接打包提供下载!
在zuobiao.html 中注意 字段的位置 对于聪明的人会明白期中的意义的!

4下面就是内容页了!
icon1.setImageUrl(“/images/1.png”);
icon1.setWidth(38);
icon1.setHeight(24);
icon后面的1是我手动填进去的 你可以将1替换成标签来 控制 出租还是出售或楼盘对应的 坐标图片!
内容页很重!
这一步修改好了以后对于首页繁多的地图信息控制就非常了解了~我也就不用举例说明首页怎么修改了!

由于是在本机做的而且没有美工所以没有浏览地址,等美化完成后打包放出!不过以上的例子和文件已经够用了!
如果想看地址实际我是以前修改的,NET版的CMS 将文件直接转嫁给了DEDE,在表单页痛疼了短时间 但是解决了!
看原地址 http://www.aiximi.cn 效果是完全一样,单DEDE多了可以控制信息数量和控制区域的设置因为DEDE更方便!

7_205714_66c4555feceecf9.gif

7_205714_82ac4d613cdf8c0.gif

7_205714_aa8c3835ff3fce0.gif

7_205714_d925ab0cc492037.gif

zb.rar (35.98 KB, 下载次数: 82)

[转载]oData另一种不用写代码就在网上提供数据服务的方法

mikel阅读(902)

[转载]oData – 另一种不用写代码就在网上提供数据服务的方法 – Footprints on the sands of time – 博客园.

先看两个例子:

这里还有更多提供/支持这种服务的链接:http://www.odata.org/blog/2010/10/28/new-odata-producers-and-consumers

这是什么?

开放数据协议(oData)让你重新认识 HTTP 协议并且简化数据在网上的发布和更新过程。参看在 cnblogs 查到的唯一介绍它的新闻:http://news.cnblogs.com/n/69756/ 和一篇写在 VS 2010 RC 时候的简介:http://www.cnblogs.com/shanyou/archive/2010/02/11/1667381.html

说正题: 用 VS 2010 + .NET V4,几乎可以不用写代码就把完整的数据服务发布到网上步骤如下:

假设你已经有一个数据库,用户可以发围脖和订阅别人的围脖,数据结构如下,

要把它变成一个网络数据服务:

1、在VS 2010 建一个Web应用或网站,加一个数据模型:

2、把数据库里的表加进来:

把默认生成的关联属性名字改改,改好就像右边这样:

3、加一个新的 WCF Data Service 网页:

4、打开它的 CS 文件,

代码

1 public class messages : DataService< /* TODO: put your data source class name here */ >
2 {
3 // This method is called only once to initialize service-wide policies.
4 public static void InitializeService(DataServiceConfiguration config)
5 {
6 // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
7 // Examples:
8 // config.SetEntitySetAccessRule(“MyEntityset”, EntitySetRights.AllRead);
9 // config.SetServiceOperationAccessRule(“MyServiceOperation”, ServiceOperationRights.All);
10 config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
11 }
12 }

改成下面这个样子(基本上就是把注释去掉,把刚才的数据模型加进来):

代码

1 public class messages : DataService<MessageEntities>
2 {
3 public static void InitializeService(DataServiceConfiguration config)
4 {
5 config.SetEntitySetAccessRule(*, EntitySetRights.AllRead);
6 config.SetServiceOperationAccessRule(*, ServiceOperationRights.All);
7 config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
8 }
9 }

5、没了,你的数据服务已经在网上。

浏览你的SVC网页,可以看到:

代码

1 <?xml version=”1.0″ encoding=”utf-8″ standalone=”yes” ?>
2 <service xml:base=”http://localhost:38791/messages.svc/” xmlns:atom=”http://www.w3.org/2005/Atom” xmlns:app=”http://www.w3.org/2007/app” xmlns=”http://www.w3.org/2007/app”>
3 <workspace>
4 <atom:title>Default</atom:title>
5 <collection href=”Posts”>
6 <atom:title>Posts</atom:title>
7 </collection>
8 <collection href=”Subscriptions”>
9 <atom:title>Subscriptions</atom:title>
10 </collection>
11 <collection href=”Users”>
12 <atom:title>Users</atom:title>
13 </collection>
14 </workspace>
15 </service>
16

浏览service.svc/Users,可以看到用户列表:

代码

<?xml version=”1.0″ encoding=”utf-8″ standalone=”yes” ?>

<feed xml:base=”http://localhost:38791/messages.svc/” xmlns:d=”http://schemas.microsoft.com/ado/2007/08/dataservices” xmlns:m=”http://schemas.microsoft.com/ado/2007/08/dataservices/metadata” xmlns=”http://www.w3.org/2005/Atom”>
<title type=”text”>Users</title>
<id>http://localhost:38791/messages.svc/Users</id>
<updated>2010-12-20T19:22:12Z</updated>
<link rel=”self” title=”Users” href=”Users” />
<entry>
<id>http://localhost:38791/messages.svc/Users(1)</id>
<title type=”text” />
<updated>2010-12-20T19:22:12Z</updated>
<author>
<name />
</author>
<link rel=”edit” title=”User” href=”Users(1)” />
<link rel=”http://schemas.microsoft.com/ado/2007/08/dataservices/related/Posts” type=”application/atom+xml;type=feed” title=”Posts” href=”Users(1)/Posts” />
<link rel=”http://schemas.microsoft.com/ado/2007/08/dataservices/related/Followers” type=”application/atom+xml;type=feed” title=”Followers” href=”Users(1)/Followers” />
<link rel=”http://schemas.microsoft.com/ado/2007/08/dataservices/related/Subscriptions” type=”application/atom+xml;type=feed” title=”Subscriptions” href=”Users(1)/Subscriptions” />
<category term=”Message.DataModel.User” scheme=”http://schemas.microsoft.com/ado/2007/08/dataservices/scheme” />
<content type=”application/xml”>
<m:properties>
<d:id m:type=”Edm.Int32″>1</d:id>
<d:name>Test</d:name>
</m:properties>
</content>
</entry>
</feed>

总结

为什么叫开放数据协议?因为它跨语言和平台的,基于http地址的数据服务。

例子:

列出所有的用户:service.svc/Users

找一个叫张三的用户:service.svc/Users?$filter=Name eq ‘张三’

他发的围脖(假设前一个查询返回了他的ID):service.svc/Users(1)/Posts

他的Fans: service.svc/Users(1)/Followers

他发的关于cnblogs的围脖:service.svc/Posts?$filter=userId eq 1 and indexof(content, ‘cnblogs’) ge 0

这些看起来并不难,但好处是,它们都不需要写任何代码,而且它是RESTful的,任何可以访问URL的语言,平台都可以用它。除此以外,这只是GET操作,POST,DELETE等其他标准HTTP操作也是原生支持的。所以,它是完整的数据服务,并不仅仅是数据查询。

如果大家有兴趣,我会继续写这个主题,比如在WPF使用这种服务,在JavaScript使用(Built in JSON support, 哈哈),并涉及一些更深的,实际项目的内容,比如数据安全,数据事务。

题外话, 为什么是另一个?很久很久以前,SQL Server曾经有过Web Service 的服务,但M$做了一个艰难的决定,把它在后续版本中移除了。由于 Entity Framework, WCF data service in .NET V4的加持,这种服务又换了一个方式回来了。

题外外话,斗转星移,离上一篇文章又两年过去了,地方没变,人老了。

人老记性就不好,这个给忘了:要修给IE的一个设置,让它不自动 turn on feed view,不然你看到就是IE格式化过的内容了,odata返回的是,人也可以吃,IE也可以吃的 Atom xml.

[转载]Jumony入门(二)初识选择器

mikel阅读(1242)

[转载]Jumony入门(二)初识选择器 – Ivony… – 博客园.

首先介绍一下Jumony是什么,Jumony是一个.NET的开源项目,项目主页位于:http://jumony.codeplex.com/,采用LGPL协议发布。

Jumony 试图提供在传统Web开发模型中许多难以解决问题的解决方案。一言蔽之,Jumony的一切基础建立在服务器端的HTML DOM之上。在服务器端将HTML(文件或动态网页技术的输出)按照客户端浏览器的处理方式解析为HTML DOM。操纵和处理HTML DOM,就像我们在客户端用JavaScript干的那些事情一样,不同的是,Jumony可以使你依托强大的.NET Framework,来解决以前用脚本和服务器端技术都难以解决的事情。

系列目录:

Jumony入门(一)从这里开始

这是系列文章的第二篇,这个系列尝试一步步从一些最简单的例子开始了解怎么玩转Jumony。建议先从第一篇开始学习搭建Jumony环境,在本文的开始的时候,假设大家已经搭建好了Jumony的运行环境。

首先我们来看一个页面:

image

这个页面的源代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Ranks</title>
  <style>
    table
    {
      font-size: 12px;
    }
    .ranks th
    {
      height: 30px;
      font-size: 15px;
      font-family: Arial;
    }
    
    .ranks td, .ranks th
    {
      border-top: solid 1px;
    }
    
    .ranks .name
    {
      font-weight: bold;
    }

    .ranks table td
    {
      border: 0px;
    }
  </style>
</head>
<body>
  <table cellpadding="5" cellspacing="0" class="ranks">
    <tr>
      <td colspan="2" class="top">
        <table cellpadding="3" border="0">
          <tr>
            <td rowspan="3"><img src="http://pic.cnblogs.com/avatar/a14218.jpg" width="50" height="50" /></td>
            <td class="name">Jumony</td>
          </tr>
          <tr>
            <td>得票数: <span style="color: red;">100</span></td>
          </tr>
          <tr>
            <td>主页地址: <a href="http://jumony.codeplex.com/">http://jumony.codeplex.com/</a></td>
          </tr>
        </table>
      </td>
    </tr>
    <tr>
      <th>
        № 2
      </th>
      <td><span class="name">Jumony</span>( <span style="color: red;">100</span> ) <a href="http://jumony.codeplex.com/">http://jumony.codeplex.com/</a></td>
    </tr>
    <tr>
      <th>
        № 3
      </th>
      <td><span class="name">Jumony</span>( <span style="color: red;">100</span> ) <a href="http://jumony.codeplex.com/">http://jumony.codeplex.com/</a></td>
    </tr>
  </table>
</body>
</html>

请先将份源代码保存为一个叫做ranks.htm的文件,然后我们开始对这个页面干点儿坏事。

这种页面,就是一种在传统的技术下,怎么也不好处理的页面,第一名的呈现方式与后面的呈现方式完全不同。即使用模版引擎,这种模版改起来怕也是件烦心事儿。

但强大CSS的选择器可以完全的抹平这些区别,使得我们的逻辑变得非常简单。

当然,首先,我们要建立一个这个页面的处理程序,也就是ranks.htm.ashx文件。然后添加using和继承基类,完成后的样子像这样:

imageimage

那么首先,我们要选择到class为ranks的那个table,再选择其每一行,选择器像是这样的:”.ranks > tr”。

中间的>符号表示只选择.ranks的直接子集中的tr,因为在第一名的行中,HTML里面又被嵌了一个table来做绑定,里面也有一些tr元素。所以我们使用>选择符来避免选择到这些:

image

关于选择器的语法,是完全遵循CSS Selector 3的标准的(部分实现)。如有不清楚的地方可以移步W3C的网站http://www.w3.org/TR/2009/PR-css3-selectors-20091215/

另外需要注意的是这里我们是直接用Find方法的,而不是Document.Find,嗯,这是JumonyHandler提供的一个便利,对于 Document的Find操作实在是太常用了,所以,Handler上定义了一个Find方法来对Document进行查找。当然,这和 Document.Find是完全一样的效果。

然后我们编造一些数据,例如:

image

接下来是将两个列表绑定在一起,Ivony.Fluent里面提供了一个方法:BindTo,这个方法可以方便的进行两个列表的绑定,使用方法像是这样:

image

这里我使用的是lambda表达式,如果你喜欢也可以写成一个额外的方法,当然,在这个例子中,由于上面的数据类型我用的是匿名类型,所以这里没有办法拆出另一个方法出来,那么,我继续用lambda来示范。

获取了每一个绑定的元素后,我们需要进一步考察每一个项(即Name、Votes和Url)要绑定的位置。只要是有规律的界面,那么其HTML就一定是有规律的,其实这个规律并不难找:

Name位于class=”name”的元素中,而Votes则总是在一个style=”color: red”的span里面,至于url,则总是在<a>那里,因为这是一个链接。当然,这个页面也可以说是事先设计好的,因为这里才第二篇,我 们只考虑一些简单的示范,在后面,我们再来看在代码中的筛选逻辑能够做到怎样的智能。那么我们可以简单的写出选择器:

image

注意这里的element直接就有Find方法,事实上Find方法并不是Document的专利,在Jumony中,只要是一个容器(IHtmlContainer),就可以Find,这实在非常便利。

OK,现在数据就已经全部绑定到页面了,打开页面来看看效果。

image

很完美不是么?看看HTML源代码:

image

怎么样,有没有一种在服务器端用JQuery的感觉?

这里有几个问题需要注意一下:

  1. CSS选择器的关系选择符,如”>”或是”+”这些,在标准中两边是不必留有空白的,即可以写成”.ranks>tr”。但Jumony不允许,是刻意如此,并非技术所限不能支持。因为Jumony认为强制性的留白可以提高这些选择符的可读性。
  2. 现有的版本中,不支持CSS Selector 3标准中的:not伪类和,选择符,其余的全部支持。JQuery的私有伪类则全部不支持。
  3. 如果你觉得linkContainer.SetAttribute( “href” ).Value( dataItem.Url )这种写法很恶心,那么不必担心。下个版本就可以这样写了:
    linkContainer.SetAttribute( “href” ,dataItem.Url )
    还可以这样:linkContainer.href = dataItem.Url

[转载]Asp.net mvc 集成Autofac和FluentValidation

mikel阅读(1174)

[转载]Asp.net mvc 集成Autofac和FluentValidation – 爱因斯坦的小脑 – 博客园.

PS:关于更多DevText的文章请到这里查看:

http://www.n-pei.com/blog/devtext_widget_Create

http://www.n-pei.com/blog/devtextdesign3

http://www.n-pei.com/blog/tools-introduce

等等。。。。。。

昨天大家很多人抱怨没有用过AutoFac,所以今天我就在把CR部署上线后,给大家说明下如何在ASP.NET mvc中集成Autofac这个IoC工具。并顺带着说明下在DevText中使用的FluentValidation。。。。

1.创建一个ASP.NET Mvc应用程序:

image

2.添加autofac引用

如果你安装了NuGet,这里你就不需要从autofac官网下载生成的dll包,而直接用vs2010自动获取。

image

这里说明下如何使用NuGet来自动添加autofac的引用。

image

再次罗嗦下,呵呵,list-package是列出所有nuget已经打包好的package。你可以在上图中看到autofac.

接下来是使用install-package来自动添加引用。

因为我们使用的是NuGet自动添加dll所以原来需要手动配置Web.Config。在httpModule中添加如下配置:

image

3.配置Gobal.asax文件

首先需要需要让这个类继承IContainerProviderAccessor接口,并声明一个IContainerProver作为应用程序的容器。

image

第二步是在Application_Start方法中注册Controller和一些model,以及modelBinder等,并使用Autofac中的自定义ControllerFactory。

image

以上就完成了Autofac的ASP.NET mvc集成。

接下来结合Autofac以及FluentValidation来给大家说明下FluentValidation如何工作。

我们使用接口IPerson和类Person来说明。

image

在Global.asax中register Person。

image

Validation部分:

先添加引用:

image

Validation的代码风格:

image

最后是Controller部分和VIew部分:

image

在Controller中注意,因为我们使用的是Autofac的ControllerFactory,所以默认Controller的Construcotr是可以有n个参数的,而不是不允许有参数。

View部分代码:

image

最后是别忘了在Global.asax中注册我们的Validation Provider。

image

搞定,直接按F5运行试试:

image

BRs

Nic

[转载]使用ASP.NET MVC MvcHandler设计自定义系统权限

mikel阅读(1010)

[转载]使用MvcHandler设计自定义系统权限 – RyanDing – 博客园.

周末稍微研究了下MVC2.0的系统框架。现将学习成果拿来和网友们分享,对MVC2.0框架研究的还不够深入。如果存在不足的地方,希望您指出,以达到共同学习的目的。

我对MVC2.0的框架的理解简单概括如下:

一、MVC2.0使用ASP.NET System.Web.Routing


画了张示意图,有点简陋:

mvc 的核心在RouteBase 这个抽象类上,该抽象类提供了两个抽象方法GetRouteData和GetVirtualPath,前者根据RouteData负责解析url后者负责生成url。


二、System.Web.Routing 的 IRouteHandler 接口


系统是如何使用IRouteHandler进入MVC框架的呢?

我的理解:MvcRouteHandler -> 通过当前的RequestContext对象生成MvcHandler对象 -> MvcHandler对象 从 RouteData 中找到 controller 通过ControllerFactory实例化MVC Controller。

MSDN上的解释:MvcRouteHandler . 此类实现了 IRouteHandler,因此可以与 ASP.NET 路由集成。 MvcRouteHandler 类将路由与 MvcHandler 实例关联。 当您使用 MapRoute 方法时,向路由注册 MvcRouteHandler 实例。 当 MvcRouteHandler 类被调用时,该类使用当前的 RequestContext 实例产生 MvcHandler 实例。 然后它会将控制委托给新 MvcHandler 实例。详情请见MSDN的MvcRouteHandler


三、加强对IRouteHandler、 MvcRouteHandler理解


为加强对MVC框架的理解,个人认为还得通过代码实践,光靠理论知识远远不够。为了加强理解以上两个对象按以下步骤模拟即可:

1.自定义HelloWorldHandler类(模拟MvcRouteHandler对象)该类实现IRouteHandler接口,代码如下:

1 public class HelloWorldHandler : IRouteHandler
2 {
3 public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
4 {
5 return new MyHandler(requestContext);
6 }
7 }

2.以上代码中的MyHandler类它模拟了MvcHandler 类,MvcHandler在RouteData中根据controller的名字创建了controller实例。MyHandler代码如下:

01 public class MyHandler : MvcHandler
02 {
03 public MyHandler(RequestContext requestContext)
04 : base(requestContext)
05 {
06
07 }
08
09 protected override System.IAsyncResult BeginProcessRequest(System.Web.HttpContext httpContext, System.AsyncCallback callback, object state)
10 {
11 if (1 == 1)
12 {
13 //当条件满足时可以跳转到一个自定义的httphandler,比如(Error.aspx)等。
14 httpContext.Response.Redirect("http://www.cnblogs.com/ryanding");
15 return null;
16 }
17 return base.BeginProcessRequest(httpContext, callback, state);
18 }
19 }

以上代码第12行这个if分支通过相应的逻辑判断,决定了是否进入MVC框架。下一篇文章中,我们就从该处着手,将权限功能注入到MyHandler的BeginProcessRequest方法内。

3.HelloWorldHandler 这个IRouteHandler调用方法如下:

在Global.asax内Application_Start改造成一下代码:

1 protected void Application_Start()
2 {
3 AreaRegistration.RegisterAllAreas();
4
5 RouteTable.Routes.Add(new Route("{controller}/{action}", new HelloWorldHandler()));
6
7 RegisterRoutes(RouteTable.Routes);
8 }


四、最后


经过以上设置,运行MVC程序后,所有的链接都将跳转到本文的3.2第14行硬编码的url。

[转载]陈成的iDebug v1.0 发布

mikel阅读(1181)

[转载]陈成的博客 » iDebug v1.0 发布.

iDebug 就像是一个魔术桶,把页面倒进去,可以出来任意你想要的东西。

Github:https://github.com/kissyteam/kissy-tools/tree/master/idebug

T181VUXeBrXXXXXXXX-876-566.png

他包含以下功能:

  • 抓网页:
    通过点击 Bookmarklet 把网页抓过来,或修改,或存档
  • responder:
    模拟 Fiddler 的 Responder 功能,对 HTML 内容进行替换
  • 查看所有 CSS 和 JS:
    模拟 YSlow 里包含的一个功能,对于不常开 Firefox 的 Chrome 用户来说非常有用
  • JS Beautify:
    格式化压缩后的脚本文件(不支持 Packer 解压缩),格式化 JSON
  • HTML Beautify:
    格式化HTML
  • Demo 模式:
    切换到 Demo 模式,保存后可在本页刷新 Demo

以下为淘宝特色功能:

  • 还原 Combo:
    把 http://a.tbcdn.cn/??a.js,b.js 替换成 http://a.tbcdn.cn/a.js 和 http://a.tbcdn.cn/b.js
  • 删除 assets 路径上的 -min
    把 http://a.tbcdn.cn/a-min.css 替换成 http://a.tbcdn.cn/a.css
  • 切换 Hosts
    不用修改 Hosts 文件,直接切换 Taobao 环境的日常/预发/线上等环境

使用方法:

  1. 确认配有 PHP 环境,并支持 SQLite
  2. 上 github 把 iDebug clone 或 下载下来
  3. 修改 idebug.SQLite.sample 为 idebug.sqlite
  4. 访问  idebug/idebug.php
  5. 根据引导,添加页头的 bookmarklet 到收藏夹
  6. — 准备完毕 —
  7. 访问要抓取/测试的页面
  8. 点击刚才添加的 bookmarklet
  9. — 剩下的大家应该都会了 —

快捷键:

Shift + A:查看所有 CSS 和 JS
Shift + V:查看 Demo
Shift + ?:查看帮助
Shift + H:切换 Demo Mode
Ctrl + Enter:保存

规则示例:

a.css
----
b.css
====
c.js
----
d.js
e.js

说明PPT:

见 docs/idebug_20101030.pdf

[转载]sql 2005超时时间已到,但是尚未从池中获取连接

mikel阅读(913)

问题描述
超时时间已到。超时时间已到,但

是尚未从池中获取连接。出现这种

情况可能是因为所有池连接均在使

用,并且达到了最大池大小。


说明: 执行当前 Web 请求期间,出

现未处理的异常。请检查堆栈跟踪

信息,以了解有关该错误以及代码

中导致错误的出处的详细信息。

异常详细信息: System.InvalidOperationException: 超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。

这是个老问题了!你就查两点:
一、看所有open的连接是否都close了。
二、如果访问量很大,加上Max   Pool   Size=512这一句,当然这是要以损失系统性能为代价的!
这样以后一定可以解决你的问题!

解决方案一

我想原因可能是并发操作。DataReader是独占连接的,就是说你的程序可能设计上有问题。比如说最大连接设100,假设有100个人同时使用 DataReader正在读取数据库内容,那么当第101人读取的时候,连接池中的连接已经没有了,就会出现上面的错误。DataReader是独占连接 的,每个DataReader都要占用一个连接。当然这个情况是偶尔出现的,所以会很长时间出现一次,因为只有同时有超过连接池最大连接数量的并发操作才 会发生。而且你加大并发数量只能暂时缓解问题,如果你加大到200个并发连接,如果有201 人同时操作怎么办?你说了你使用Connection对象的Close()方法,这是不行的,因为Close()方法仅仅是关闭连接,但这个连接没有释 放,还是被这个对象占用,要释放必须使用Connection的Dispose()方法显式释放连接才可以,否则这个对象占用的连接只能等到垃圾收集的情 况下才能被释放。这种情况肯定会出现“超时时间已到”的错误。

解决方法:
1 修改几个关键页面或访问比较频繁的数据库访问操作,使用DataAdapter和DataSet来获取数据库数据,不要使用DataReader。
2 在访问数据库的页面上使用数据缓存,如果页面的数据不是经常更新(几分钟更新一次)的话,使用Cache对象可以不用访问数据库而使用缓存中的内容,那么可以大大减少连接数量。
3 修改代码,把使用Connection对象的地方都在Close()后面加上Dispose()调用。
4 建议对数据库操作进行大的修改,建立自己的数据库操作代理类,继承System.IDisposable接口,强迫释放资源,这样就不会出现连接数量不够的问题了。

解决方案二

解决方法(*):WEB.config 里面:在数据库连接加 Max Pool Size = 512;server=local;uid=;pwd=;database=2004;Max Pool Size = 512;”>一劳永逸。

解决方案三

估计是连接(Connection)对象没有Close。倒是不必Dispose,而DataReader用完后应该关闭,但不关闭也没问题,只是不关闭的话此连接对象就一直不能用,只要你最终关闭了连接对象就不会出问题。

连接对象在Open后的操作都放在try块中,后面跟一个finally块:conn.Close();

[转载]Sql技巧之快速得到表的记录总数

mikel阅读(1251)

[转载]Sql技巧之快速得到表的记录总数 – EricHu’s Tech Space – 博客园.

判断某一个表的记录总数,对于一个开发者来说是最再常见不过的事,我想大家都常用的作法就是:

select count(*) from 表名;

这种做法没做,我这儿主要说的是效率问题。当一个数据表的记录数不是太多时, 这样得到记录总数的效率不是问题。但试想,如果一个表的记录总数超过几百万或者几千万,要再用上面的SQL语句得到表的记录总数,速度会慢得让人难以忍 受。有人会说了,可以一表上建立聚簇集索引呀,不错,若在表的某个字段上建立聚簇索引,第一次执行该语句的时间和没有索引的时间差不多,之后执行上述语 句,速度很快。但如果要经常做增删改操作,建立聚簇索引不是一个明智的做法,将会极大的影响增删改的速度。得到一个数据表的记录总数经常用在以下几个方 面:

一、做数据分页时要得到总记录数。

二、判断数据表的记录数是否过大,是否需要备份数据。

三、用户要求等等。

说了这么多,那么到底如何快速得到一个数据表的记录总数呢?答案是:利用SQLServer数据库的系统视图sys.sysindexes

在MS SQL数据库中,每个数据表都在sys.sysindexes系统表中拥有至少一条记录,记录中的rows 或rowcnt字段会定时记录表的记录总数。注意是定时,这说明了用这个方法得到的总记录数不是一个精确值,原因是MsSQL并不是实时更新该字段的值,而是定时更新,但从实践来看该值和精确值误差不大,如果你希望快速粗略估算表的记录总数,建议你采用该方法。

SQLSEVER帮助文件对sys.sysindexes系统视图的说明为:当前数据库中的每个索引和表在表中各对应一行。说了这么多,直接动手操作便一目了然。

打开SQLServer,执行如下语句:

1 useAdventureWorks 2  select id,object_name(id) as tableName,indid,rows,rowcnt 3  from sys.sysindexes where indid in(0,1)

得到:

© 2010 EricHu

原创作品,转贴请注明作者和出处,留此信息。

[转载]Jumony入门(一)从这里开始

mikel阅读(1123)

[转载]Jumony入门(一)从这里开始 – Ivony… – 博客园.

首先介绍一下Jumony是什么,Jumony是一个.NET的开源项目,项目主页位于:http://jumony.codeplex.com/,采用LGPL协议发布。

Jumony 试图提供在传统Web开发模型中许多难以解决问题的解决方案。一言蔽之,Jumony的一切基础建立在服务器端的HTML DOM之上。在服务器端将HTML(文件或动态网页技术的输出)按照客户端浏览器的处理方式解析为HTML DOM。操纵和处理HTML DOM,就像我们在客户端用JavaScript干的那些事情一样,不同的是,Jumony可以使你依托强大的.NET Framework,来解决以前用脚本和服务器端技术都难以解决的事情。

下载部署

Jumony现在最稳定的版本是Milestone 1,其下载地址在:http://jumony.codeplex.com/releases/view/51380,对于第一次接触Jumony的朋友来说,建议先下载编译好的DLL,即Binary选项:

image

点击Binary链接后,会出现Jumony的许可协议(也就是LGPL),点击image,开始下载。下载后是一个ZIP文件包,打开后可以看到里面有一个目录Binary,将其随便展开到一个文件夹,例如C:\Jumony。然后清点一下DLL的数量,正常情况下应该包含如下DLL:

  • Ivony.Core.dll,包含基础接口,和一些提高编程体验基础扩展方法
  • Ivony.Web.Html.dll,Jumony的核心DLL,定义了抽象HTML DOM模型。并提供大量扩展方法来操纵HTML DOM
  • Ivony.Web.Html.Binding.dll,提供数据绑定支持
  • Ivony.Web.Html.Parser.dll,即Jumony Parser,一个优秀的Html Parser,可以分析HTML文本并创建HTML DOM。
  • HtmlAgilityPack.dll,HtmlAgilityPack 是另一个开源项目,与Jumony Parser一样,是另一个可以分析HTML文本并创建DOM的工具,理论上Jumony可以使用任何HTML分析器来分析HTML并为自己所用,只要有 合适的Adapter。HtmlAgilityPack的项目主页位于:http://htmlagilitypack.codeplex.com/
    值 得注意的是,当你下载Jumony的源代码包或是直接查看Jumony的源代码时,将不会有HtmlAgilityPack的任何源代码,可以去 HtmlAgilityPack的主页下载。HtmlAgilityPack的授权许可协议与Jumony是不同的,这一点要特别注意。
  • HtmlAgilityPack.Adapter.dll,HtmlAgilityPack 的适配器,使得HtmlAgilityPack可以当作Jumony的一个分析器来使用。事实上在M1版本中,Jumony Parser甚至不如HtmlAgilityPack成熟。

除了DLL文件外,pdb文件是用于调试的,而xml文件则是智能提示所必须的,建议都不要删除,保留。

然 后我们需要新建一个网站来玩一下,在这之前,首先要确保你的VS至少是2008或以上,Jumony的最低.NET Framework版本要求是3.5。还在2.0的朋友,就只能说一声抱歉了,因为Jumony的选择器和导航扩展方法乃至于绑定支持,都是极度依赖于 LINQ技术的。几乎不可能在.NET Framework 2.0之下提供简单的实现。

那么我们先新建一个网站(Web项目也行,这里用网站作为示范):

image

这里我把网站建立在了P:\WebSite\JumonyDemo,然后添加引用,找到刚才存放DLL的文件夹,将六个DLL一股脑全部添加引用:

image

然后我们需要配置web.config文件来添加Jumony的环境支持,在Jumony的下载页面上,有现成的已经配置好的web.config下载:

image

根据ASP.NET的版本,可以选择不同的web.config下载。然后替换系统默认的web.config即可,我这里默认创建的网站便是ASP.NET 4的,所以我下载ASP.NET 4的web.config,其内容是这样的:

image

httpHandlers和httpModules里面的内容便是新增的,如果你需要在现有的一个web.config文件中增加Jumony的环境配置,则只需要下载ASP.NET 4的web.config文件,然后将这两段拷贝整合即可。

然 后就可以开始测试Jumony环境了,首先确认一下Web服务器使用的是VS自带的默认ASP.NET Development Server还是IIS,如果是使用IIS调试,则建议先换为VS自带的默认服务器,因为Jumony需要截获html和htm文件的请求,这已经在 web.config中配置,但如果使用IIS作为服务器,则还需要配置IIS这两个扩展名的映射,这很麻烦,而我们在这里只是先玩一下Jumony,所 以建议先用默认的服务器。

来干点坏事

先随便找一个HTML文件来测试一下Jumony是否已经正常工作,这里我写一个Hello World:
image

将其保存为index.htm:

image

然 后添加这个HTML文件的处理程序,Jumony的处理程序事实上就是一个ashx文件,然后要求文件名除了ashx这个扩展名之外的前段与被处理的文件 的文件名一模一样,这样Jumony的RewriteModule就会自动映射。所以这里我要添加的处理程序的文件名是index.htm.ashx。首 先在添加项的对话框中选择一般处理程序(Generic Handler),然后输入文件名index.htm.ashx:

image

系统会帮我们自动添加一些代码,除了类型声明和using之外的代码都是多余的,直接删掉:

image

系统默认的类型名称是index,但为了避免冲突,Jumony建议类名还是命名为index_htm比较妥当,当然这不是必须的。然后我们要添加许多using,以及修改继承的基类型:

image

JumonyHandler是一个抽象类,有一个Process方法需要我们实现:

image

通过实现这个方法,可以让我们对HTML进行操控,当进入这个方法时,HTML文档(index.htm)已经被分析完毕成为一个IHtmlDocument对象静静的躺在一个叫做Document的属性里,等着我们来操控。

首先我们来了解Find方法,这个方法和JQuery的一样,使用CSS选择器来选择元素,在这里我们把Hello World的body元素找出来:

image

Single是LINQ中的方法,所以我说没有LINQ将寸步难行,因为Find方法的结果是一个元素(IHtmlElement)集合,这里用Single方法取出唯一的元素,因为我们知道body一定是唯一的元素。

然后我们干点什么好呢?要不把Hello World改为Hello Jumony!如何?

image

这就完成了我们的第一件“坏事”,赶紧来看看成果。在解决方案中右键点击index.htm,然后选择在浏览器中查看,不出意外的话,应该会看到这样的效果:

image

哦耶,真的变成了Hello Jumony。

来查看一下源代码:

image

清楚的看到了index.htm文件输出被Jumony引擎精确篡改。

再看看原始的文件(即index.htm这个文件原始的样子)是不是还是原来的样子:

image

确实没有变化,还是Hello World。

Jumony截获了htm的请求,并篡改了其结果,完成。