[MVC]构建不带Web窗体的应用

mikel阅读(879)

构建不带 Web 窗体的 Web 应用程序
Chris Tavares
本文基于 ASP.NET MVC Framework 的预发布版本撰写而成。文中的详细信息均可能会有所变更。
本文讨论:

  • 模型视图控制器模式
  • 创建控制器和视图
  • 构建窗体和回发
  • 控制器工厂和其他扩展点
本文使用了以下技术:
ASP.NET

代码下载位置: MVCFramework2008_03.exe (189 KB)
Browse the Code Online

我 从事专业开发迄今为止已有 15 年,在此之前,我利用业余时间从事开发至少也有 10 年了。与我这一代的大多数人一样,我是从 8 位计算机起步,然后转用 PC 平台的。随着计算机的复杂性日益增加,我编写的应用程序涵盖了从小型游戏到个人数据管理再到控制外部硬件的各项功能。
不过,在我职业生涯的前半段,我编写的所有软件都有一个共同点:即,都是运行在用户桌面上的本地应用程序。我最早是在 90 年代初期听说万维网这件新生事物。那时我发现,通过构建 Web 应用程序,可以让我输入我的考勤卡信息而不必再费时费力从工作场所赶回办公室。
一言以蔽之,我感觉很是困惑。我当时满脑子是面向桌面的理念,很难接纳这种无状态的 Web。要添加很多让人头疼的调试、我没有 UNIX 服务器的超级用户访问权限,再加上这个奇怪的角括号,这些因素使年轻时的我止步不前,又重返桌面开发渡过了几年时光。
我远离了 Web 开发领域,虽然这领域显然很重要,但我并没有真正理解其编程模型。然后,Microsoft® .NET Framework 和 ASP.NET 发行了。尽管它与桌面应用程序编程有许多相似之处,但终于有了可以让我从事 Web 应用程序编程的框架。我可以构建窗口(页面),将控件与事件挂钩,而设计器使我不必处理那些讨厌的角括号。最妙的是,ASP.NET 会通过查看状态自动为我处理 Web 的无状态性质!我又重新找回了程序员的快乐 … 至少在一段时间内是如此。
随着经验的增加,我的设计内容也随之丰富。我早已掌握了几种最佳实践,并将其应用到桌面应用程序编程。其中的两种就是:
  • 分离关注点:不要将 UI 逻辑与基础行为混合在一起。
  • 自动单元测试:编写自动测试以验证您的代码是否按预期执行。
这 些是适用于任何技术的基本原则。分离关注点是一项可帮助您处理复杂问题的基本原则。在同一个对象内混合多种责任(如计算剩余的工时、设置数据格式并绘图) 会给维护带来很大的负担。而自动测试对于获得生产质量的代码同时仍保持条理性至关重要,尤其是当您更新现有项目时更是如此。
ASP.NET Web 窗体使入门变得非常简单,但另一方面,要将我的设计理念应用到 Web 应用程序却并非易事。Web 窗体坚持以 UI 为侧重点;其基本单位为页面。首先设计 UI 并拖曳控件。只需将应用程序逻辑融入页面的事件处理程序(与为 Windows® 应用程序启用的 Visual Basic® 非常相似)就万事大吉,这一点非常吸引人。
但 进一步的页面单元测试常常有很大困难。您必须先启动所有 ASP.NET,然后才能在“页面”对象的生命周期内运行该对象。尽管可以通过发送 HTTP请求到服务器或自动化浏览器来测试 Web 应用程序,但这类测试非常脆弱(更换一个控制 ID 测试就会中断)、难以设置(您必须以完全相同的方式在每位开发人员的计算机上设置该服务器)并且运行缓慢。
当 我开始构建更复杂的 Web 应用程序时,Web 窗体提供的抽象概念(如控件、视图状态和页面生命周期)就开始添乱而不是帮忙了。我需要花越来越多的时间来配置数据绑定(并编写大量的事件处理程序对其进 行正确配置)。我不得不想办法缩减视图状态的大小以便更快加载我的页面。Web 窗体要求每个 URL 均存在物理文件,这对于动态站点(例如 wiki)非常困难。而成功编写一个自定义的 WebControl 是一个非常复杂的过程,需要全面了解页面生命周期和 Visual Studio® 设计器。
自从在 Microsoft 工作开始,我就一直与其他人分享关于各种 .NET 难题的体验并希望可以解决一些难题。最近,作为开发人员参加有关模式与实践的 Web 客户端软件工厂项目 (codeplex.com/websf) 时,我遇到了一个这样的机会。特别是,模式与实践交付的内容之一就是自动单元测试。在 Web 客户端软件工厂中,我们建议使用 Model View Presenter (MVP) 模式构建可测试的 Web 窗体。
简 而言之,MVP 并非将您的逻辑放入页面中,而是让您构建自己的页面,页面 (View) 只需调用单独的对象,即 Presenter。Presenter 对象随即执行响应视图上活动必需的任何逻辑,通常通过使用其它对象 (Model) 访问数据库、执行业务逻辑等。一旦这些步骤完成后,Presenter 会更新视图。这种方法提供了可测试性,因为表示器从 ASP.NET 管道中隔离出来;它与视图通过界面进行通信并可脱离页面独立进行测试。
MVP 的这种功能实现有点笨;您需要单独的视图界面,并且您必须在源代码文件中编写许多事件转发函数。但如果您想要在 Web 窗体应用程序中得到可测试的 UI,这差不多是最佳途径。任何改进均需要在基础平台中做出更改。
模型视图控制器模式
幸运的是,ASP.NET 团队听取了象我这样的开发人员的意见,并且已经着手开发一种新的 Web 应用程序框架,该框架与您所熟知并喜爱的 Web 窗体处于同一层级,但采用一组完全不同的设计目标:
  • 使用 HTTP 和 HTML—不隐藏。
  • 可测试性贯穿整个框架之内。
  • 几乎在每个点均可扩展。
  • 对输出进行总体控制。
由 于此新框架基于模型视图控制器 (MVC) 模式,因此其名称为 ASP.NET MVC。MVC 模式最初在 70 年代发明,是 Smalltalk 技术的一部分。正如我将在本文中所展示的,它实际上非常适合 Web 的性质。MVC 将您的 UI 分为三种不同的对象:用于接收和处理输入的控制器;包含您域逻辑的模型;以及用于生成输出的视图。在 Web 环境中,输入为 HTTP 请求,而请求流程与图 1 类似。

Figure 1 MVC 模式请求流程 (单击该图像获得较大视图)
这实际上与 Web 窗体中的过程完全不同。在 Web 窗体模型中,输入进入页面(视图),然后视图负责处理输入并生成输出。而 MVC 中这些责任是分开的。
因 此,您可能立即会产生以下一种想法:“嘿,这太好了。我应该如何使用它?”或“为什么我要编写这些对象,以前只需要编写一个对象?”这两个问题都问得很 好,最好通过示例来进行解释。因此,我将使用 MVC Framework 编写一个小型 Web 应用程序以说明其优点。
创建控制器
要 继续进行,您将需要安装 Visual Studio 2008 并获得 MVC Framework 的副本。在撰写本文时,ASP.NET 扩展的 2007 年 12 月社区技术预览 (CTP) 中已提供了这些内容 (asp.net/downloads/3.5-extensions)。您可能想要获取扩展 CTP 和 MVC 工具包,其中包括一些非常有用的帮助程序对象。一旦下载并安装 CTP 后,您将在“新建项目”对话框中获得名为“ASP.NET MVC Web 应用程序”的新项目类型。
选择“MVC Web 应用程序”项目后,会为您提供一个与常用网站或应用程序稍有不同的解决方案。该解决方案模板会创建一个带有一些新目录的 Web 应用程序(如图 2 中所示)。特别是 Controllers 目录包含各种控制器类,而 Views 目录(及其所有子目录)包含了各种视图。

Figure 2 MVC 项目结构 
我 将会编写一个非常简单的控制器,返回 URL 中传递的名称。右键单击 Controllers 文件夹并选择“添加项目”以显示常用的“添加项目”对话框以及一些新增加的内容,包括 MVC 控制器类和几个 MVC 视图组件。在此例中,我将添加一个非常富有想象力、名为 HelloController 的类:
using System;
using System.Web;
using System.Web.Mvc;
namespace HelloFromMVC.Controllers
{
public class HelloController : Controller
{
[ControllerAction]
public void Index()
{
...
}
}
}
控制器 类比页面简单得多。实际上,唯一真正必需做的就是从 System.Web.Mvc.Controller 中衍生并将 [ControllerAction] 属性置于您的操作方法中。操作是调用以响应特定 URL 请求的一种方法。操作负责执行所需的一切处理,然后呈现一个视图。我将通过编写一个将名称传递到视图的简单操作着手,如下所示:
[ControllerAction]
public void HiThere(string id)
{
ViewData["Name"] = id;
RenderView("HiThere");
}
操作方法会通过 ID 参数从 URL 接收该名称(稍后会介绍方法),将其存储在 ViewData 集合中,然后呈现名为 HiThere 的视图。
在 讨论如何调用此方法,或该视图的显示内容之前,我希望说一说可测试性。还记得我之前关于测试 Web 窗体页面类有多难的评论吗?控制器的测试简单得多。实际上,控制器可以直接实例化,而调用操作方法无需任何附加的基础结构。您不需要 HTTP 上下文,也不需要服务器,只要测试工具即可。作为示例,我在图 3 中为此类包括了 Visual Studio Team System (VSTS) 测试单元。
下 面将进行几项操作。实际的测试相当简单:实例化该控制器,使用预期的数据调用该方法,然后检查呈现的视图是否正确。我通过创建测试专用的子类覆盖 RenderView 方法进行检查。这可以缩短实际创建 HTML 的时间。我只关心是否将正确的数据发送到视图以及是否呈现了正确的视图。我不关心此测试视图本身的底层详细信息。
创建视图
当 然,最终我必须生成一些 HTML,因此,让我们创建该 HiThere 视图。要进行此操作,首先,我将在解决方案中的 Views 文件夹下创建名为 Hello 的新文件夹。默认情况下,控制器将在 Views\<控制器前缀> 文件夹(控制器前缀为控制器类的名称去掉 "Controller" 字样)中查找视图。因此,对于 HelloController 呈现的视图,它会在 Views\Hello 中查找。解决方案的查找结果如图 4 所示。

Figure 4 将视图添加到项目中 (单击该图像获得较大视图)
视图的 HTML 如下所示:
<html  >
<head runat="server">
<title>Hi There!</title>
</head>
<body>
<div>
<h1>Hello, <%= ViewData["Name"] %></h1>
</div>
</body>
</html>
应注意以下几件事。没有 runat="server" 标记。没有 form 标记。没有控件声明。实际上,这看起来更象传统的 ASP 而不是 ASP.NET。请注意,MVC 视图仅负责生成输出,因此其不需要任何 Web 窗体页面所需的事件处理或复杂控件。
MVC Framework 借用了 .aspx 文件格式作为一种有用的文本模板语言。如果需要,甚至可以使用源代码,但默认情况下,源代码文件如下所示:
using System;
using System.Web;
using System.Web.Mvc;
namespace HelloFromMVC.Views.Hello
{
public partial class HiThere : ViewPage
{
}
}
没有页 面初始化或加载方法,没有事件处理程序,除了基类声明以外没有任何内容,基类声明为 ViewPage 而不是 Page。这就是 MVC 视图所需的一切。运行该应用程序,导航至 http://localhost:<端口>/Hello/HiThere/Chris,您将看到如图 5 所示的内容。

Figure 5 成功的 MVC 视图 (单击该图像获得较大视图)
如果您看到的并非如图 5 所示,而是难以理解的意外情况,请不要惊慌。如果您将 HiThere.aspx 文件设置为 Visual Studio 中的活动文档,则当按 F5 后,Visual Studio 将尝试直接访问 .aspx 文件。由于 MVC 视图要求控制器在显示前运行,因此尝试直接导航至该页面将不起作用。只需将该 URL 编辑为与图 5 中所示的内容相匹配,即可正常工作。
MVC Framework 如何知道调用我的操作方法?该 URL 甚至没有文件扩展名。答案是 URL 路由。如果您仔细查看 global.asax.cs 文件,则会看到如图 6 所示的代码段。全局 RouteTable 会存储 Route 对象的集合。每个 Route 说明一个 URL 窗体以及对其进行何种操作。默认情况下,会向该表中添加两个路由。第一个是该方法的内容。它说明每个 URL 在服务器名后均由三部分组成,第一部分应为控制器名,第二部分为操作名称,而第三部分为 ID 参数。
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
// Change Url= to Url="[controller].mvc/[action]/[id]"
// to enable automatic support on IIS6
RouteTable.Routes.Add(new Route
{
Url = "[controller]/[action]/[id]",
Defaults = new { action = "Index", id = (string)null },
RouteHandler = typeof(MvcRouteHandler)
});
RouteTable.Routes.Add(new Route
{
Url = "Default.aspx",
Defaults = new {
controller = "Home",
action = "Index",
id = (string)null },
RouteHandler = typeof(MvcRouteHandler)
});
}
}
Url = "[controller]/[action]/[id]"
此默认 路由是能让我的 HiThere 方法得以调用的路由。请记住此 URL:http://localhost/Hello/HiThere/Chris?此路由将 Hello 与控制器、HiThere 与操作以及 Chris 与 ID 一一对应。MVC Framework 随即创建 HelloController 实例,调用 HiThere 方法,然后将 Chris 作为 ID 参数的值传递。
此默认路由为您提供了许多功能,但您也可以添加自己的路由。例如,我想要一个真正友好的站点,好友们只需输入他们的姓名即可获得个性化的问候。如果我在路由表的顶部添加以下路由
  RouteTable.Routes.Add(new Route
{
Url = "[id]",
Defaults = new {
controller = "Hello",
action = "HiThere" },
RouteHandler = typeof(MvcRouteHandler)
});
随后,我只需访问 ,我的操作仍处于调用状态,而我将会看到熟悉的友好问候。
系 统如何知道调用哪个控制器和操作?答案是 Defaults 参数。它利用新的 C# 3.0 匿名类型语法来创建一个伪词典。Route 上的 Defaults 对象可包含任意附加的信息,对于 MVC,它还可以包含一些众所周知的条目:即控制器和操作。如果 URL 中没有指定控制器或操作,则其将使用 Defaults 中的名称。这就是为什么即使我在 URL 中忽略它们,但仍可以将我的请求映射到正确的控制器和操作。
还 有一件事需要注意:还记得我说过“添加到表格的顶部”吗?如果您将其置于底部,将会出现错误。路由根据先到先得的原则进行工作。当处理 URL 时,路由系统会自上至下浏览表格,并且使用第一个匹配的路由。在本例中,默认路由 "[controller]/[action]/[id]" 匹配,因为它们是操作和 ID 的默认值。这样,它会继续查找 ChrisController,但我没有控制器,因此会出现错误。
稍大的示例
现 在,我已经说明了 MVC Framework 的基础知识,将为您展示一个更大的示例,实现比仅显示字符串更多的功能。wiki 是一种可以在浏览器中进行编辑的网站。可以轻松地添加或编辑页面。我使用 MVC Framework 编写了一个小型的示例 wiki。“编辑此页面”屏幕如图 7 所示。

Figure 7 编辑主页 (单击该图像获得较大视图)
您可以检查本文的代码下载以查看如何实现底层 wiki 逻辑。现在我想重点说明 MVC Framework 如何使 Web 上的 wiki 获取变得简单。让我们先设计 URL 结构。我想要以下各项:
  • /[pagename] 显示该名称的页面。
  • /[pagename]?version=n 显示页面的请求版本,其中 0 = 当前版本,1 = 以前的版本,以此类推。
  • /Edit/[pagename] 打开该页的编辑屏幕。
  • /CreateNewVersion/[pagename] 是为提交编辑而传入的 URL。
让我们从 wiki 页面的基本显示开始。我为它创建了一个名为 WikiPageController 的新类。接下来,我会添加一个名为 ShowPage 的操作。启动的 WikiPageController 如图 8 所示。ShowPage 方法相当简单。WikiSpace 和 WikiPage 类分别表示一组 wiki 页面和特定的页面(及其修订)。此操作只需加载模型并调用 RenderView。但此处的 "new WikiPageViewData" 行是什么意思?
我前面的示例说明了一种将数据从控制器传递到视图的方法:即 ViewData 词典。词典非常方便,但也很危险。它们几乎包含一切内容,您不能获取内容的任何 IntelliSense®,并且由于 ViewData 词典属于 Dictionary<string, object> 类型,它将消耗内容,您必须计算所有一切。
当您了解在视图中将需要什么数据后,就可以传递强类型化的 ViewData 对象。在我的示例中,我创建了一个简单的对象 (WikiPageViewData),如图 9 中所示。此对象将 wiki 页面信息带到视图,同时还携带了一些实用工具方法,执行获取 wiki 标记的 HTML 版本这类任务。
现在,我已经定义了视图数据,那么,我如何使用它呢?在 ShowPage.aspx.cs 中,您将看到以下内容:
namespace MiniWiki.Views.WikiPage {
public partial class ShowPage : ViewPage<WikiPageViewData>
{
}
}
请注意,我将基类类型定义为 ViewPage<WikiPageViewData>。这意味着页面的 ViewData 属性为 WikiPageViewData 类型,而不是象以前示例中的“Dictionary”。
.aspx 文件中的实际标记非常简单:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
AutoEventWireup="true" CodeBehind="ShowPage.aspx.cs"
Inherits="MiniWiki.Views.WikiPage.ShowPage" %>
<asp:Content
ID="Content1"
ContentPlaceHolderID="MainContentPlaceHolder"
runat="server">
<h1><%= ViewData.Name %></h1>
<div id="content" class="wikiContent">
<%= ViewData.HtmlBody %>
</div>
</asp:Content>
请注意,当引用 ViewData 时,我没有使用索引操作符 []。由于我现在有强类型化的 ViewData,我可以直接访问该属性。不需要进行任何计算,而 Visual Studio 会提供 IntelliSense。
目光敏锐的读者将会注意到此文件中的 <asp:Content> 标记。没错,“母版页”确实可以与 MVC 视图配合使用。并且“母版页”还可以成为视图。让我们看看“母版页”的源代码:
namespace MiniWiki.Views.Layouts
{
public partial class Site :
System.Web.Mvc.ViewMasterPage<WikiPageViewData>
{
}
}
相关标记如图 10 中所示。现在,“母版页”将获得与视图完全相同的 ViewData 对象。我已经将“母版页”的基类声明为 ViewMasterPage<WikiPageViewData>,因此,我拥有了正确类型的 ViewData。我会在那里设置各种 DIV 标记以对页面进行布局,填写版本列表,然后以常用内容占位符收尾。
另 一件需要注意的事是对 Html.ActionLink 的调用。以下是呈现帮助程序的一个示例。各种视图类均具有两种属性,Html 和 Url。每种均有输出 HTML 代码块的有用方法。在本例中,Html.ActionLink 获取一个对象(此处为匿名类型)并通过路由系统将其返回。这将会生成一个 URL,该 URL 将路由至我指定的控制器和操作。这样一来,无论我如何更改路由,“编辑此页面”链接将始终指向正确的位置。
您可能还注意到,我还不得不依靠手动构建链接(到先前页面版本的链接)。遗憾的是,当前的路由系统在涉及查询字符串时生成 URL 的功能不是十分完善。这应会在框架的后续版本中得到修复。
创建表单和回发
现在,让我们看看控制器上的 EditPage 操作:
[ControllerAction]
public void EditPage(string pageName)
{
WikiSpace space = new WikiSpace(Repository);
WikiPage page = space.GetPage(pageName);
RenderView("editpage",
new WikiPageViewData {
Name = pageName,
Page = page });
}
同样,该操作所做的不多—它只是呈现指定页面的视图。视图中的内容变得更加有趣,如图 11 中所示。此文件构建了一个 HTML 表单,但没有出现 Runat="server"。Url.Action helper 用于生成表单回发的 URL。其中还使用了几种不同的 HTML 帮助程序(如 TextBox、TextArea 和 SubmitButton)。它们会出色完成您的预期目标:为各种输入字段生成 HTML。
处 理 Web 编程最头疼的事情之一就是表单中的错误。更确切地说,您想要显示错误信息,但同时想要保留原来输入的数据。我们都有过那种经历,在填写一张有 35 个字段的表单时出现一个错误,程序却只是提供一堆错误信息和一张新的空白表单。MVC Framework 使用 TempData 存储以前输入信息,以便可以重新填入表单。这是 ViewState 实际上在 Web 窗体中变得非常简单的原因,因为保存控件的内容几乎是自动的。
我想在 MVC 中如法炮制,因此引入了 TempData。TempData 是一种词典,与非类型化的 ViewData 很相似。不过,TempData 的内容仅针对单一请求存在,随后就会被删除。要了解如何使用此方法,请参阅图 12,NewVersion 操作。
首 先,它创建一个 NewVersionPostData 对象。这是另一个帮助程序对象,具有存储记入的内容和进行某些验证的属性和方法。为加载 postData 对象,我将使用 MVC 工具包的帮助程序。UpdateFrom 实际上是工具包提供的扩展方法,它使用反射将表单字段的名称与我的对象中属性的名称相对映。最终结果是,所有字段值均载入到我的 postData 对象中。不过,UpdateFrom 使用起来确实有缺点,由于它直接从 HttpRequest 获取表单数据,使单元测试变得更为困难。
NewVersion 检查的第一项是 SubmitAction。如果用户单击“确定”按钮并确实想要发布编辑的页面,则此项检查将通过。如果此处有任何其它值,操作会重定向回 ShowPage,只是重新显示原来的页面。
如果用户确实单击了“确定”,则检查 postData.Errors 属性。这将在记入内容上运行一些简单的验证。如果没有任何错误,我会将新版本的页面重新写入 wiki。不过,如果出现错误,情况会变得饶有趣味。
如果出现错误,我会设置 TempData 词典的各个字段,以便其包含 PostData 的内容。然后,我会重定向回“编辑”页面。现在,由于已设置 TempData,页面将重新显示以用户上次记入的值初始化的表单。
处 理记入、验证和 TempData 的这个过程现在变得有些烦琐,并且需要多做一些手动工作。将来发行的版本应包括至少会将一些 TempData 检查自动化的帮助程序方法。关于 TempData 的最后一个注意事项是:TempData 的内容存储在用户的服务器端会话中。如果您关闭会话,TempData 将无法正常工作。
创建控制器
现 在,wiki 的基础已在发挥功效,但继续进行之前,我想要明确实现中的以下几个要点。例如,Repository 属性用于分离 wiki 的逻辑与物理存储。您可以提供在文件系统(正如我所做的那样)、数据库或您想要的任何位置中存储内容的存储库。遗憾的是,我需要解决两个问题。
首先,我的控制器类与具体的 FileBasedSpaceRepository 类紧密地连在一起。我需要一个默认值,以便在属性没有设置时,也能合理使用。更糟的是,磁盘上文件的路径在这里也是硬编码的。最起码,它应取自配置。
其次,我的对象必须依赖存储库,否则无法运行。对于良好的设计,存储库实际应为构造函数参数,而不是属性。但我无法将其添加到构造函数中,因为 MVC Framework 要求控制器上的构造函数不能有参数。
幸 运的是,我可以通过一个扩展性挂接摆脱此限制:即控制器工厂。控制器工厂的功能正如其名称所指:它创建 Controller 实例。您只需要创建一个类实现 IControllerFactory 接口并向 MVC 系统注册即可。您可以为所有控制器或仅为指定的类型注册控制器工厂。图 13 所示为 WikiPageController 的控制器工厂,其现在将存储库作为构造函数参数传递。 在这种情况下,实现非常烦琐,但它可以创建能使用更强大工具(特别是依赖关系注入容器)的控制器。 无论如何,现在我拥有了将控制器依赖关系分离到对象中(易于管理和维护)的所有详细信息。
此工作的最后一步是向框架注册工厂。通过 ControllerBuilder 类可进行此操作,方法是将以下行添加到 Application_Start 方法中的 Global.asax.cs(路由前后均可):
ControllerBuilder.Current.SetControllerFactory(
typeof(WikiPageController), typeof(WiliPageControllerFactory));
这将注 册 WikiPageController 的工厂。如果此项目中有其他控制器,它们不会使用此工厂,因为此工厂仅针对 WikiPageController 类型进行了注册。如果您想要将工厂设置为供所有控制器使用,还可以调用 SetDefaultControllerFactory。
其他扩展点
控 制器工厂只是框架扩展性的起点。本文中无法详述所有的细节,因此我将仅仅说明要点。首先,如果您想要输出的内容不是 HTML,或想要使用其他模板引擎而不是 Web 窗体,可将控制器的 ViewFactory 设为其他项。您可以实现 IviewFactory 界面,然后即可完全控制如何生成输出。这对于生成 RSS、XML 或图形非常有用。
正 如您所见到的,路由系统非常灵活。但路由系统中没有任何内容是 MVC 专用的。每个路由均有一个 RouteHandler 属性;目前为止,我始终将其设为 MvcRouteHandler。但可以实现 IRouteHandler 界面并将路由系统与其他 Web 技术挂接。将来推出的框架将附带 WebFormsRouteHandler,并且其他技术也会在将来利用通用路由系统的优势。
控 制器并非必须从 System.Web.Mvc.Controller 衍生。控制器需要做的仅仅是实现 IController 界面,该界面只有称为 Execute 的一种方法。您可以从中进行任何操作。另一方面,如果您想将 Controller 基类的几种行为组合在一起,您可以覆盖 Controller 的许多虚拟函数:
  • OnPreAction、OnPostAction 和 OnError 可让您将每个已执行操作上的预处理和后处理连接起来。OnError 为您提供在控制器内处理错误的机制。
  • 当 URL 路由到控制器但控制器没有实现路由中请求的操作时,会调用 HandleUnknownAction。默认情况下,此方法会抛出一个异常,但您可以用所需的操作覆盖默认值。
  • InvokeAction 是一种方法,它负责解决调用何种操作方法并进行调用。如果您想要自定义过程(例如,除去 [ControllerAction] 属性的要求),应使用该方法。
还有其他几种针对 Controller 的虚拟方法,但这些方法主要是测试挂接而不是作为扩展点。例如,RedirectToAction 是虚拟的,因此您可以创建实际并不进行重定向的衍生类。这样,您不需要完全运行 Web 服务器就能测试重定向操作。
要告别 Web 窗体吗?
现 在您可能在想:“Web 窗体会面临怎样的命运?MVC 会取代它吗?”答案是否定的!Web 窗体是一种普及技术,Microsoft 将继续支持并改进它。它在许多应用程序中发挥着重要的作用;例如,可使用 Web 窗体创建典型的 Intranet 数据库报表应用程序,所花的时间比使用 MVC 编写短得多。此外,Web 窗体支持大量的控件,许多控件均具备非常先进的功能,可以大大提高效率。
那 么,什么时候应该选择 MVC 呢?这主要取决于您的要求和喜好。您是否正在为获得想要的 URL 格式而烦恼?您是否想要对 UI 进行单元测试?以上情况均需要依靠 MVC。反之,如果您要显示许多数据,提供可编辑的网格和优良的树形视图控件?那么,您暂时最好还是使用 Web 窗体。
今后,MVC Framework 很可能在 UI 控制部分有所改进,但在便利性上,它可能始终不及 Web 窗体,因为后者具备大量拖曳功能。同时,ASP.NET MVC Framework 为 Web 开发人员提供了一种在 Microsoft .NET Framework 中构建 Web 应用程序的新方法。Framework 针对可测试性设计、推倡使用 HTTP 并且几乎在每个点均可扩展。对于那些想要完全控制其 Web 应用程序的开发人员来说,这是一个对 Web 窗体的诱人补充。
Chris Tavares 是 Microsoft 模式和实施方案小组的一名开发人员,他致力于帮助开发社区了解在 Microsoft 平台上构建系统的最佳实践。他还是 ASP.NET MVC 小组的虚拟成员,帮助您设计新的框架。可以通过 cct@tavaresstudios.com 与 Chris 取得联系。

[正则表达式]用正则表达式剔除文本中的HTML标记

mikel阅读(647)

函数虽然简单,但是对处理HTML文档还是很有效的
<%
Function RemoveHTML(strHTML)
Dim objRegExp, Match, Matches
Set objRegExp = New Regexp
objRegExp.IgnoreCase = True
objRegExp.Global = True
'取闭合的<>
objRegExp.Pattern = "<.+?>"
'进行匹配
Set Matches = objRegExp.Execute(strHTML)
' 遍历匹配集合,并替换掉匹配的项目
For Each Match in Matches
strHtml=Replace(strHTML,Match.Value,"")
Next
RemoveHTML=strHTML
Set objRegExp = Nothing
End Function
%>

[MVC].net中“检测到有潜在危险的Request.Form 值”错误解决方法

mikel阅读(653)

由于在.net中,Request时出现有HTML或JavaScript等字符串时,系统会认为是危险性值。立马报错上面的错误。6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
解决办法:6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
解决方案一: 6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
在.aspx文件头中加入这句: 6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
<%@ Page validateRequest="false"  %> 6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
解决方案二: 6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
修改web.config文件: 6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
<configuration> 6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
  <system.web> 6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
    <pages validateRequest="false" /> 6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
  </system.web> 6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
</configuration> 6jZÁªÉÞ¯‚www.orpai.com&decäs¢?$
因为validateRequest默认值为true。只要设为false即可

[MVC]整合FCKEditor到Asp.Net MVC

mikel阅读(782)

Integrating FCKeditor in ASP.Net

Introduction

In Basic ASP.NET, FCKeditor can be easily integrated. Here is the link where I found that. http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Integration/ASP.NET

However, to integrate FCKeditor in ASP.NET MVC environment, we have to follow some tricky steps. Here I will show how to integrate using core JavaScript as well as using JQuery.

Using JavaScript:

Step 1

Download the FCKeditor from http://www.fckeditor.net/download.

Step 2

Unzip the package and put in your project content directory. I liked to make a directory “Javascript” under “Content” directory and put “unzipped fckeditor” here. I have also put fckeditorapi.js in “Javascript” folder. You can get more information on FCKeditor API here

http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/JavaScript_API

Step 3

I have added a MVC view file in Home folder and named it as “Fck.aspx”. To view this file, I included a method in HomeController, as follows.

/// <summary>
/// Show FCK Editor View Page
/// </summary>
public void Show()
{
RenderView("Fck");
}

Step 4

In Fck.aspx, include the fckeditor.js and fckeditorapi.js file:

<script type="text/javascript" src="../../Content/Javascript/fckeditor/fckeditor.js"></script>
<script type="text/javascript" src="../../Content/Javascript/fckeditorapi.js"></script>

Include the following to replace textarea (named ‘content’) by FCKeditor. Here I have included InsertContent(), ShowContent() and ClearContent() methods to perform some extra actions.

<script type="text/javascript">
window.onload = function()
{
var oFCKeditor = new FCKeditor( 'content' ) ;
oFCKeditor.BasePath = "/Content/Javascript/fckeditor/" ;
oFCKeditor.Height = 300;
oFCKeditor.ReplaceTextarea() ;
}
function InsertContent()
{
var oEditor = FCKeditorAPI.GetInstance('content') ;
var sample = document.getElementById("sample").value;
oEditor.InsertHtml(sample);
}
function ShowContent()
{
var oEditor = FCKeditorAPI.GetInstance('content') ;
alert(oEditor.GetHTML());
}
function ClearContent()
{
var oEditor = FCKeditorAPI.GetInstance('content');
oEditor.SetHTML("");
}
</script>

Here is the html content:

<div>
<input id="sample" type="text" />
<input id="cmdInsert" type="button" value="Insert Content" onclick="InsertContent()" />
<input id="cmdClear" type="button" value="Clear Content" onclick="ClearContent()" />
<br /> <br />
<textarea id="content" cols="30" rows="10"></textarea>
<br />
<input id="cmdShow" type="button" value="Show Content" onclick="ShowContent()" />
</div>

Step 5

Now build the application and run. Click the “FCK Editor” link and get the result.

FCKEditor in ASP.Net

Using JQuery

Step 1

Download jQuery from http://www.jquery.com. I have put jQuery-1.2.6.pack.js and jQuery.FCKEditor.js in my “Javascript” folder”.

Step 2

I have added a MVC view file in Home folder and named it as “FckJquery.aspx”. To view this file, I included a method in HomeController, as follows.

/// <summary>
/// Show FCK Editor By JQuery
/// </summary>
public void View()
{
RenderView("FckJquery");
}

Step 3

In FckJquery.aspx, include the jquery-1.2.6.pack.js, fckeditor.js and jquery.FCKEditor.js file:

<script type="text/javascript" src="../../Content/Javascript/jquery-1.2.6.pack.js"></script>
<script type="text/javascript" src="../../Content/Javascript/fckeditor/fckeditor.js"></script>
<script type="text/javascript" src="../../Content/Javascript/jquery.FCKEditor.js"></script>

Include the following to replace textarea (named ‘content’) by FCKeditor. Here I have included InsertContent(), ShowContent() and ClearContent() methods to perform some extra actions.

<script type="text/javascript">
$(document).ready(function(){
$.fck.config = {path: '/Content/Javascript/fckeditor/', height: 300 };
$('textarea#content').fck();
});
function InsertContent()
{
var sample = document.getElementById("sample").value;
$.fck.insertHtml('fck1', sample);
}
function ShowContent()
{
alert($.fck.content('fck1', ''));
}
function ClearContent()
{
$.fck.clearHtml('fck1');
}
</script>

Here is the html content:

<div>
<input id="sample" type="text" />
<input id="cmdInsert" type="button" value="Insert Content" onclick="InsertContent()" />
<input id="cmdClear" type="button" value="Clear Content" onclick="ClearContent()" />
<br /> <br />
<textarea id="content" cols="30" rows="10"></textarea>
<br />
<input id="cmdShow" type="button" value="Show Content" onclick="ShowContent()" />
</div>

Step 4

In jquery.FCKEditor.js file, I have included two functions. Function insertHtml() inserts html content into fckeditor and clearHtml() clears the content.

// insert Html Content
insertHtml: function(i, v) {
try{
var x = FCKeditorAPI.GetInstance(i);
if(v) x.InsertHtml(v);
else return '';
}
catch(e) { return ''; };
},
// clear Html Content
clearHtml: function(i) {
try{
var x = FCKeditorAPI.GetInstance(i);
x.SetHTML('');
}
catch(e) { return ''; };
},

Step 5

Now build the application and run. Click the “FCK Editor By JQuery” link and get the result. Enjoy It!

Source Code

Here is the source code FCKeditorMvcDemo

References

http://docs.fckeditor.net

http://www.jquery.com

http://www.fyneworks.com/jquery/FCKEditor

Conclusion

Next I will try to give some demonstration on how to build plugins in FCKeditor. Till then bye.

[MVC]Asp.net MVC Fckeditor的扩展(支持PV3及自动绑定)

mikel阅读(738)

namespace System.Web.Mvc
{
    
using System;
    
using System.Globalization;
    
/// <summary>
    
/// Fckeditor的HTMLHelper
    
/// http://chsword.cnblogs.com/
    
/// </summary>
    static public class FckTextBoxExt
    {
        
/// <summary>
        
/// Fckeditor的HTMLHelper,可以与同名ViewData绑定
        
/// </summary>
        
/// <param name="u">HtmlHelper</param>
        
/// <param name="name">Html的NAME</param>
        
/// <returns></returns>
        public static string FckTextBox(this HtmlHelper u, string name)
        {
            
return u.FckTextBox(name, null);
        }
        
/// <summary>
        
/// Fckeditor的HTMLHelper
        
/// </summary>
        
/// <param name="u"></param>
        
/// <param name="name">Html name </param>
        
/// <param name="value">内容</param>
        
/// <returns></returns>
        public static string FckTextBox(this HtmlHelper u, string name, object value)
        {
            
return u.FckTextBox(name, value.ToString());
        }
        
/// <summary>
        
/// Fckeditor的HTMLHelper
        
/// </summary>
        
/// <param name="u"></param>
        
/// <param name="name">Html name</param>
        
/// <param name="value">内容</param>
        
/// <returns></returns>
        public static string FckTextBox(this HtmlHelper u, string name, string value)
        {
            
if (value == null)
            {
                value 
= Convert.ToString(u.ViewDataContainer.ViewData[name], CultureInfo.InvariantCulture);
            }
            
return string.Format(@"<textarea name=""{0}"" id=""{0}"" rows=""50"" cols=""80"" style=""width:100%; height: 600px"">{1}</textarea>
<script type=""text/JavaScript"">
    var oFCKeditor = new FCKeditor('{0}') ;
    //oFCKeditor.BasePath    = sBasePath ;
oFCKeditor.Height=400;
    oFCKeditor.ReplaceTextarea() ;
</script>
", name, value);
        }
    }
}

用法
View页写
<%=Html.FckTextBox("content")%>即可
Controller写
ViewData["content"]="<div>….</div>";
即可与之绑定
希望对大家自己扩展MVC的有帮助

[FCKEditor]FCKeditor2.2+ASP.NET2.0不完全攻略

mikel阅读(942)

 

作者:任搏软

Websitehttp://www.wrestsoft.com

技术Bloghttp://dsclub.cnblogs.com

My Spacehttp://www.myspace.com/dsclub

QQ9967030

 

前几天写了一篇关于基于ASP.NET2.0FCKeditor的使用心得,由于不少网友要求再写得详细些,今天再总结续写一些。本文所示用的FCKeditor版本是FCKeditor2.2,截至目前这个是最新版本。

 

FCKeditor相关资料简介:

官方网站http://www.fckeditor.net/

官方文档http://wiki.fckeditor.net/

下载地址http://www.fckeditor.net/download/default.html

官方演示http://www.fckeditor.net/demo/default.html

 

 

针对于ASP.NET开发者来说,你有两种选择:

1.        只使用FCKeditor,下载http://sourceforge.net/project/showfiles.php?group_id=75348&package_id=75845,然后自行配置其中的几个核心js文件。对此发开不作为本文所讨论的范畴。

2.        使用FCKeditor.Net,下载http://sourceforge.net/project/showfiles.php?group_id=75348&package_id=137125。需要声明的是,这个文件只是一个ASP.NET控件DLL文件,并不包括FCKeditor的编辑器内核。所以你还应该下载上一种方式中提到的文件包。

 

下面结合一个ASP.NET2.0的项目来具体看看FCKeditor的安装、配置。在开始之前请先下载FCKeditor文件包和FCKeditor.Net 服务器控件。启用VS2005新建一个C#WEB Site工程,取名FCKPro

 

FCKeditor安装:

所谓安装就是一个简单的拷贝过程。

把下载的FCKeditor_2.2.zip文件包直接解压缩到FCKPro的根目录下,这样根目录下就得到一个FCKeditor文件夹,里面富含所有FCKeditor的核心文件。

然后把下载的FCKeditor.Net_2.2.zip随便解压缩到你硬盘的一个空目录,里面是FCKeditor.Net的源代码(基于.NET1.1C#工程),你可以用VS2003来对它进行再度开发,本文尚不涉及本内容,我们只是直接使用FCKeditor.Net工程目录下的\bin\Release目录中的FredCK.FCKeditorV2.dll文件。

VS2005中添加对FredCK.FCKeditorV2.dll的引用:

1.        FCKPro工程浏览器上右键,选择添加引用(Add Reference…),找到浏览(Browse)标签,然后定位到你解压好的FredCK.FCKeditorV2.dll,确认就可以了。这时,FCKPro工程目录下就多了一个bin文件夹,里面包含FredCK.FCKeditorV2.dll文件。当然,你也可以完全人工方式的来做,把FredCK.FCKeditorV2.dll直接拷贝到FCKPro\bin\下面,VS2005在编译时会自动把它编译进去的。

2.        为了方便RAD开发,我们把FCKeditor控件也添加到VS的工具箱(Toolbox)上来,展开工具箱的常用标签组(General),右键选择组件(Choose Items…),在对话框上直接找到浏览按钮,定位FredCK.FCKeditorV2.dll,然后确认就可以了。这时工具箱呈现

我的经验告诉我,这样会省去很多在开发时使用FCKeditor控件时要添加的声明代码。

 

至此,你已经完成了FCKeditor的安装,并可以在你的项目中使用FCKeditor了,当然后面还有很多需要配置的东西。

 

FCKeditorASP.NET2.0 Web项目中的配置:

现在,我开始来把FCKeditor应用在我们的项目中。打开Default.aspx,切换到设计模式(Design),把FCKeditor控件从工具箱上拖动下来,在Default页上你就可以看到这个FCKeditor了,不过这时只能看到一个FCKeditor的站位框,不会看到运行时的效果,鼠标选中FCKeditor1后,在属性(Property)面板上可以设置这个FCKeditor对象的一些基本属性。比较重要的是BasePath属性,如果先前FCKeditor就定在了根目录的FCKeditor下,就设置成~/FCKeditor/,如果是别的目录名就换成相应的值(注意:控件默认值是/FCKeditor/,因为我们使用的是服务器控件设置了runat="server"属性所以要显式的声明BasePath="~/FCKeditor/")。把Default.aspx切换到源代码模式(Source),我们可以看到IDE自动生成的代码:

<%@ Register Assembly="FredCK.FCKeditorV2" Namespace="FredCK.FCKeditorV2" TagPrefix="FCKeditorV2" %>

 

<FCKeditorV2:FCKeditor ID="FCKeditor1" runat="server"></FCKeditorV2:FCKeditor>

 

如果当初没有把FCKeditor添加到工具箱上,那么应该在添加引用后自己手动来添加这些代码。

在源代码模式下,把鼠标点在FCKeditorV2:FCKeditor标签内容上,它会加粗显示,这时属性面板上显示出了FCKeditor服务器控件的全部属性,比在设计模式时多出了许多。

属性列表:

AutoDetectLanguage

BaseHref

BasePath

ContentLangDirection

CustomConfigurationsPath

Debug

DefaultLanguage

EditorAreaCSS

EnableSourceXHTML

EnableViewState

EnableXHTML

FillEmptyBlocks

FontColors

FontFormats

FontNames

FontSizes

ForcePasteAsPlainText

ForceSimpleAmpersand

FormatIndentator

FormatOutput

FormatSource

FullPage

GeckoUseSPAN

Height

ID

ImageBrowserURL

LinkBrowserURL

PluginsPath

runat

SkinPath

StartupFocus

StylesXMLPath

TabSpaces

ToolbarCanCollapse

ToolbarSet

ToolbarStartExpanded

UseBROnCarriageReturn

Value

Visible

Width

事件列表:

OnDataBinding

OnDisposed

OnInit

OnLoad

OnPreRender

OnUnload

 

以上属性和事件的使用在此不一一的赘述了,请先自行摸索一下,目前我也没找到相关资料,不过都不是很难,如果你有在asp下使用FCKeditor的经验,应该明白其中一些属性的意义,和fckconfig.js的设置项意义相同。以后有时间我会再把这部分整理好。需要说明的是FCKeditor2.2fckconfig.js2.0版本的有了较大改进,体积更小,配置方式也更加灵活,具体请自行下载比较。

针对这个示例我配置的代码如下:

<FCKeditorV2:FCKeditor

    ID="FCKeditor1"

    runat="server"

    AutoDetectLanguage="false"

    DefaultLanguage="zh-cn"

    BasePath="~/FCKeditor/">

</FCKeditorV2:FCKeditor>

好,现在运行一下这个页面,允许修改Web.Config(这样IDE会自动在工程下添加一个Web.Config文件)。看到效果了吧!

有人会问:怎么得到一个HTTP Error 404 – Not Found.的错误呢?得到这个错误一般是BasePath没有设置正确,参看上述提到的BasePath注意事项仔细检查!

到了这里,FCKeditor的配置并没有真正的完成,因为它里面的一个强大功能我们还没正确配置:文件上传。

Default.aspx的运行模式下,点FCKeditor的“插入/编辑图像”(又或者是Flash)功能,在弹出框点“浏览服务器”,又弹出一个对话框,此时随即出现的是一个错误提示框XML request error: Forbidden(403).

得到这样的错误有Web开发经验的都知道403应该是读写权限的问题。可是为什么呢?原因在于没有配置UserFiles路径。

我们在FCKPro根目录下,新建一个空目录Files。连同BasePath的设置通常的做法是这样的:

打开FCKPro工程的Web. Config文件,修改appSettings元素,配置如下:

<appSettings>

  <add key="FCKeditor:BasePath" value="~/FCKeditor/"/>

  <add key="FCKeditor:UserFilesPath" value="/FCKPro/Files" />

</appSettings>

设置了FCKeditor:BasePath后就不用再每次使用FCKeditor实例时指定BasePath属性了,FCKeditor:UserFilesPath则是制定我们所有上传的文件的所在目录。你也许会问为什么要设置成/FCKPro/Files这样而不是~/Files,因为FCKeditor使用这个值来返回你上传后的文件的相对路径到客户端,~/Files的形式是ASP.NET在服务可以编译解释的,但是在客户端的静态就不懂这是什么了。如果使用~/Files后,那么所有上传文件的返回路径都是~/Files形式的,你就会得到这样的链接http://~/Files/Image/logo.gif这样的链接解果就是路径为找到。所以才要我们上述那样设置,这是在开发阶段,如果在工程完成后发布时请记住把/FCKPro/Files改成/Files,道理不说大家也明白,开发阶段VS2005在运行项目时的URLhttp://localhost/项目名称/的形式,发布后在Server上建立站点,跟路径就是http://www.abc.com/的形式了,所以发布后一定要改过来。这些地方是在使用FCKeditor2.2+ASP.NET2.0时经常发错误而又莫名其所云的地方。

先不要高兴,这个上传的功能至此还差最关键的一步。在FCKeditor所在根目录下(FCKPro/FCKeditor/)找到fckconfig.js文件,用文本编辑器打开,在大概132行(大概是因为之前您也许参考其它资料更改过这个文件了)的地方找到:

 

var _FileBrowserLanguage    = 'asp' ;      // asp | aspx | cfm | lasso | perl | php | py

var _QuickUploadLanguage  = 'asp' ;      // asp | aspx | cfm | lasso | php

 

把这两行赋值代码的值由asp改成aspx,保存关闭这个文件。

好了,大功告成了!在此运行FCKPro项目,使用浏览服务器功能,OK了吧?

 

再提一下:

对于开发中使用文件上传功能遇到 XML request error: Internal Server Error(500) 错误的解决办法。

遇到500内部错误是怎么回事呢?

因为ASP.NET2.0新增了Theme功能,所以如果在你的工程中你对Web.config使用到了styleSheetThemetheme话那就要再多修改一下。

还是到FCKeditor所在的目录,分别打开\editor\filemanager\upload\aspx\upload.aspx\editor\filemanager\browser\default\connectors\aspx\connector.aspx两个aspx文件,在page标签中添加Theme=""StyleSheetTheme=""看你在工程使用的是什么就修改什么。修改后如下:

<%@ Page language="C#" Inherits="FredCK.FCKeditorV2.Uploader" AutoEventWireup="false" Theme="" %>

<%@ Page language="c#" Inherits="FredCK.FCKeditorV2.Uploader" AutoEventWireup="false" StylesheetTheme="" %>

这样就解决了500的内部错误。

 

有关对FCKeditor减肥的方法在此就不做说明了,网上很多资料都提到过,相信已经搞ASP.NET的你应该会正确使用Google的。

 

总之,对FCKeditor这样的好东西总应该好好研究一番的才OK,希望本文对你在实际开发中有所帮助。

[JQuery]JQuery插件

mikel阅读(786)

JQuery 是继 prototype 之后又一个优秀的 JavaScript 框架。其宗旨是—写更少的代码,做更多的事情。它是轻量级的 js 库(压缩后只有21k) ,这是其它的 js 库所不及 的,它兼容 CSS3,还兼容各种浏览器(IE 6.0+, FF 1.5+, Safari 2.0+, Opera 9.0+)。 JQuery 是一个快速的,简洁的 JavaScript 库,使用户能更方便地处理 HTML documents、events、实现动画效果,并且方便地为网站提供 AJAX 交互。 jQuery 还有一个比较大的优势是,它的文档说明很全,而且各种应用也说得很详细,同时还有许多成熟的插件可供选择。 jQuery 能够使用户的 html 页保持代码和 html 内容分离,也就是说,不用再在 html 里面插入一堆js来调用命令了,只需定义 id 即可。特推荐在Kollermedia.at上一篇jQuery插件列表的文章如下:

文件上传(File upload)

Ajax File Upload.

jQUploader.

Multiple File Upload plugin

jQuery File Style.

Styling an input type file.

Progress Bar Plugin.

表单验证(Form Validation)

jQuery Validation.

Auto Help.

Simple jQuery form validation.

jQuery XAV – form validations.

jQuery AlphaNumeric.

Masked Input.

TypeWatch Plugin.

Text limiter for form fields.

Ajax Username Check with jQuery.

表单-选取框(Form – Select Box stuff)

jQuery Combobox.

jQuery controlled dependent (or Cascadign) Select List.

Multiple Selects.

Select box manipulation.

Select Combo Plugin.

jQuery – LinkedSelect

Auto-populate multiple select boxes.

Choose Plugin (Select Replacement).

表单基本、输入框、选择框等(Form Basics, Input Fields, Checkboxes etc.)

jQuery Form Plugin.

jQuery-Form.

jLook Nice Forms.

jNice.

Ping Plugin.

Toggle Form Text.

ToggleVal.

jQuery Field Plugin.

jQuery Form’n Field plugin.

jQuery Checkbox manipulation.

jTagging.

jQuery labelcheck.

Overlabel.

3 state radio buttons.

ShiftCheckbox jQuery Plugin.

Watermark Input.

jQuery Checkbox (checkboxes with imags).

jQuery SpinButton Control.

jQuery Ajax Form Builder.

jQuery Focus Fields.

jQuery Time Entry.

时间、日期和颜色选取(Time, Date and Color Picker)

jQuery UI Datepicker.

jQuery date picker plugin.

jQuery Time Picker.

Time Picker.

ClickPick.

TimePicker.

Farbtastic jQuery Color Picker Plugin.

Color Picker by intelliance.fr.

投票插件(Rating Plugins)

jQuery Star Rating Plugin.

jQuery Star Rater.

Content rater with asp.net, ajax and jQuery.

Half-Star Rating Plugin.

搜索插件(Search Plugins)

jQuery Suggest.

jQuery Autocomplete.

jQuery Autocomplete Mod.

jQuery Autocomplete by AjaxDaddy.

jQuery Autocomplete Plugin with HTML formatting.

jQuery Autocompleter.

AutoCompleter (Tutorial with PHP&MySQL).

quick Search jQuery Plugin.

编辑器(Inline Edit & Editors)

jTagEditor.

WYMeditor.

jQuery jFrame.

Jeditable – edit in place plugin for jQuery.

jQuery editable.

jQuery Disable Text Select Plugin.

Edit in Place with Ajax using jQuery.

jQuery Plugin – Another In-Place Editor.

TableEditor.

tEditable – in place table editing for jQuery.

多媒体、视频、Flash等(Audio, Video, Flash, SVG, etc)

jMedia – accessible multi-media embedding.

JBEdit – Ajax online Video Editor.

jQuery MP3 Plugin.

jQuery Media Plugin.

jQuery Flash Plugin.

Embed QuickTime.

SVG Integration.

图片(Photos/Images/Galleries)

ThickBox.

jQuery lightBox plugin.

jQuery Image Strip.

jQuery slideViewer.

jQuery jqGalScroll 2.0.

jQuery – jqGalViewII.

jQuery – jqGalViewIII.

jQuery Photo Slider.

jQuery Thumbs – easily create thumbnails.

jQuery jQIR Image Replacement.

jCarousel Lite.

jQPanView.

jCarousel.

Interface Imagebox.

Image Gallery using jQuery, Interface & Reflactions.

simple jQuery Gallery.

jQuery Gallery Module.

EO Gallery.

jQuery ScrollShow.

jQuery Cycle Plugin.

jQuery Flickr.

jQuery Lazy Load Images Plugin.

Zoomi – Zoomable Thumbnails.

jQuery Crop – crop any image on the fly.

Image Reflection.

Google地图(Google Map)

jQuery Plugin googlemaps.

jMaps jQuery Maps Framework.

jQmaps.

jQuery & Google Maps.

jQuery Maps Interface forr Google and Yahoo maps.

jQuery J Maps – by Tane Piper.

游戏(Games)

Tetris with jQuery.

jQuery Chess.

Mad Libs Word Game.

jQuery Puzzle.

jQuery Solar System (not a game but awesome jQuery Stuff).

表格等(Tables, Grids etc.)

UI/Tablesorter.

jQuery ingrid.

jQuery Grid Plugin.

Table Filter – awesome!.

TableEditor.

jQuery Tree Tables.

Expandable “Detail” Table Rows.

Sortable Table ColdFusion Costum Tag with jQuery UI.

jQuery Bubble.

TableSorter.

Scrollable HTML Table.

jQuery column Manager Plugin.

jQuery tableHover Plugin.

jQuery columnHover Plugin.

jQuery Grid.

TableSorter plugin for jQuery.

tEditable – in place table editing for jQuery.

jQuery charToTable Plugin.

jQuery Grid Column Sizing.

jQuery Grid Row Sizing.

统计图(Charts, Presentation etc.)

jQuery Wizard Plugin .

jQuery Chart Plugin.

Bar Chart.

边框、圆角、背景(Border, Corners, Background)

jQuery Corner.

jQuery Curvy Corner.

Nifty jQuery Corner.

Transparent Corners.

jQuery Corner Gallery.

Gradient Plugin.

文字和超链接(Text and Links)

jQuery Spoiler plugin.

Text Highlighting.

Disable Text Select Plugin.

jQuery Newsticker.

Auto line-height Plugin.

Textgrad – a text gradient plugin.

LinkLook – a link thumbnail preview.

pager jQuery Plugin.

shortKeys jQuery Plugin.

jQuery Biggerlink.

jQuery Ajax Link Checker.

鼠标提示(Tooltips)

jQuery Plugin – Tooltip.

jTip – The jQuery Tool Tip.

clueTip.

BetterTip.

Flash Tooltips using jQuery.

ToolTip.

菜单和导航(Menus, Navigations)

jQuery Tabs Plugin – awesome! . [demo nested tabs.]

another jQuery nested Tab Set example (based on jQuery Tabs Plugin).

jQuery idTabs.

jdMenu – Hierarchical Menu Plugin for jQuery.

jQuery SuckerFish Style.

jQuery Plugin Treeview.

treeView Basic.

FastFind Menu.

Sliding Menu.

Lava Lamp jQuery Menu.

jQuery iconDock.

jVariations Control Panel.

ContextMenu plugin.

clickMenu.

CSS Dock Menu.

jQuery Pop-up Menu Tutorial.

Sliding Menu.

http://stilbuero.de/jquery/tabs_3/

幻灯、翻转等(Accordions, Slide and Toggle stuff)

jQuery Plugin Accordion.

jQuery Accordion Plugin Horizontal Way.

haccordion – a simple horizontal accordion plugin for jQuery.

Horizontal Accordion by portalzine.de.

HoverAccordion.

Accordion Example from fmarcia.info.

jQuery Accordion Example.

jQuery Demo – Expandable Sidebar Menu.

Sliding Panels for jQuery.

jQuery ToggleElements.

Coda Slider.

jCarousel.

Accesible News Slider Plugin.

Showing and Hiding code Examples.

jQuery Easing Plugin.

jQuery Portlets.

AutoScroll.

Innerfade.

拖放插件(Drag and Drop)

UI/Draggables.

EasyDrag jQuery Plugin.

jQuery Portlets.

jqDnR – drag, drop resize.

Drag Demos.

XML XSL JSON Feeds

XSLT Plugin.

jQuery Ajax call and result XML parsing.

xmlObjectifier – Converts XML DOM to JSON.

jQuery XSL Transform.

jQuery Taconite – multiple Dom updates.

RSS/ATOM Feed Parser Plugin.

jQuery Google Feed Plugin.

浏览器(Browserstuff)

Wresize – IE Resize event Fix Plugin.

jQuery ifixpng.

jQuery pngFix.

Link Scrubber – removes the dotted line onfocus from links.

jQuery Perciformes – the entire suckerfish familly under one roof.

Background Iframe.

QinIE – for proper display of Q tags in IE.

jQuery Accessibility Plugin.

jQuery MouseWheel Plugin.

对话框、确认窗口(Alert, Prompt, Confirm Windows)

jQuery Impromptu.

jQuery Confirm Plugin.

jqModal.

SimpleModal.

CSS

jQuery Style Switcher.

JSS – Javascript StyleSheets.

jQuery Rule – creation/manipulation of CSS Rules.

jPrintArea.

DOM、AJAX和其它JQuery插件(DOM, Ajax and other jQuery plugins)

FlyDOM.

jQuery Dimenion Plugin.

jQuery Loggin.

Metadata – extract metadata from classes, attributes, elements.

Super-tiny Client-Side Include Javascript jQuery Plugin.

Undo Made Easy with Ajax.

JHeartbeat – periodically poll the server.

Lazy Load Plugin.

Live Query.

jQuery Timers.

jQuery Share it – display social bookmarking icons.

jQuery serverCookieJar.

jQuery autoSave.

jQuery Puffer.

jQuery iFrame Plugin.

Cookie Plugin for jQuery.

jQuery Spy – awesome plugin.

Effect Delay Trick.

jQuick – a quick tag creator for jQuery.

Metaobjects.

elementReady.

英文:http://www.kollermedia.at/archive/2007/11/21/the-ultimate-jquery-plugin-list/

[Delphi]Delphi2009发布

mikel阅读(739)

一、启动界面,相比Delphi2007来说相对要简单。大家可以看到以前的“CodeGear From Borland”已经没有了,取而代之的是易博龙的LogoDelphi2009启动时间比Delphi2007快,甚至还比Delphi7快,据说Delphi2009由于不提供for .net,过滤掉了很多加载项。

虽然D2009启动很快,但是还是没有VS2005启动速度快。让人感觉Delphi是在启动的时候把所有可能需要到的资源启动时都加载完成,而VS则是用到功能的时候才加载资源,比如说打开“工具箱”面板VS才把工具列表载入工具箱。

 

 

 

二、IDE主界面,基本和Delphi2007类似

 

 

VS2005 IDE主界面,Delphi从D2005开始IDE就慢慢向着VS2005靠齐了

 

三、工具面板窗口,支持过滤器

 

 

VS2005的工具箱面板,并不支持控件过滤器

 

四、工程面板窗口,工具栏中的按钮为新增功能,“Activate”表示将工程设置为主项目,“Sync”表示同步,在这里起和文件夹同步(类似于刷新)的作用,“Expand”展开左右节点,“Collapse”关闭所有节点。

 

 

VS2005的解决方案管理器,工具栏功能比D2009更实用一些。D2009 pre-release版并没有提供类视图。 

 

五、Delphi2007 就已经提供的文件浏览器面板

 

VS2005没有提供相关功能。

 

 

六、窗体设计器界面

 

 

由于Delphi在RAD方面一直是非常棒的,所以这点可以说VS2005是效仿了Delphi:

 

七、代码视图。IDE原生只支持对象成员的智能感知,但是装上了国人编写的第三方插件cnPack后,就能达到类似于VS2005一样的智能感知效果。

 

 

毫无疑问,VS2005在智能感知方面的体验原生支持是最出色的,目前我没有发现其它哪款IDE能超越过它:

 

八、历史代码窗体。这个功能不常用,感觉是鸡肋,通常都把这个功能屏蔽掉。

 

 

VS2005没有类似的功能。

 

 

九、控件属性面板,这个面板从D2006开始用久了会出现一些重绘问题,在D2009 pre-release版仍然有这个问题。不知道在正式版是否已经解决。

 

 

VS2005的控件属性面板,对每个成员都有说明,这点小贴心功能Delphi没有提示,应该借鉴。但是.net中的说明是靠Attribute来实现的,在Delphi中没有提供相应的方法。

同时,VS2005的属性面板还提供工具栏,在D2009的属性面板中有右键菜单支持以上工具栏按钮的操作。

 

 

十、结构窗体,下面的截图分别表示代码界面下的结构和设计界面下的结构。

 

 

VS2005只提供设计界面结构面板,叫“Document Outline”,默认情况下没有打开:

 

十一、Delphi2009终于提供了资源编辑器,简单且直观

 

 

在工程属性里有专门的地方添加和设置资源,这一点比D2009做得更加专业:

 

总体来说,Delphi2009 IDE相比Delphi2007而言做了很多细节上的改进,整个IDE反应速度很快,也非常之稳定。对语言进行了改进(支持泛型、匿名方法、增强Exit等)以后还能完全支持以前的项目,用了几天也IDE也没有出现以前Delphi2007经常出现的Application Exception之类的异常和卡死现象,感觉非常“轻便”。

 

相对于VS2005,个人感觉D2009在很多细节上(如界面颜色、界面布局、图标样式等)做得不如VS,且智能感知的原生支持还有待加强。但是,Delphi2009是在逆境中成长起来的,我们并不能要求太多,毕竟两家公司实力不同。

[JQuery]JQuery的CheckBox操作控制

mikel阅读(725)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 2<HTML>
 3 <HEAD>
 4  <TITLE> New Document </TITLE>
 5  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 6  <link href="css/ingrid.css" rel="stylesheet" type="text/css">
 7<script language="JavaScript" src="JQuery-1.2.3.pack.js" type="text/JavaScript"></script>
 8  <SCRIPT LANGUAGE="JavaScript">
 9  <!–
10      $("document").ready(function(){
11          
12       $("#btn1").click(function(){
13           
14          $("[name='checkbox']").attr("checked",'true');//全选
15        
16       }
)
17       $("#btn2").click(function(){
18           
19          $("[name='checkbox']").removeAttr("checked");//取消全选
20        
21       }
)
22       $("#btn3").click(function(){
23           
24          $("[name='checkbox']:even").attr("checked",'true');//选中所有奇数
25        
26       }
)
27       $("#btn4").click(function(){
28           
29          $("[name='checkbox']").each(function(){
30              
31            
32              if($(this).attr("checked"))
33            {
34                $(this).removeAttr("checked");
35                
36            }

37            else
38            {
39                $(this).attr("checked",'true');
40                
41            }

42            
43          }
)
44        
45       }
)
46        $("#btn5").click(function(){
47       var str="";
48          $("[name='checkbox'][checked]").each(function(){
49              str+=$(this).val()+"\r\n";
50          }
)
51         alert(str);
52       }
)
53      }
)
54  //–>
55  
</SCRIPT>
56  
57 </HEAD>
58
59 <BODY>
60 <form name="form1" method="post" action="">
61   <input type="button" id="btn1" value="全选">
62   <input type="button" id="btn2" value="取消全选">
63   <input type="button" id="btn3" value="选中所有奇数">
64   <input type="button" id="btn4" value="反选">
65   <input type="button" id="btn5" value="获得选中的所有值">
66   <br>
67   <input type="checkbox" name="checkbox" value="checkbox1">
68   checkbox1
69   <input type="checkbox" name="checkbox" value="checkbox2">
70   checkbox2
71   <input type="checkbox" name="checkbox" value="checkbox3">
72   checkbox3
73   <input type="checkbox" name="checkbox" value="checkbox4">
74   checkbox4
75   <input type="checkbox" name="checkbox" value="checkbox5">
76   checkbox5
77   <input type="checkbox" name="checkbox" value="checkbox6">
78   checkbox6
79   <input type="checkbox" name="checkbox" value="checkbox7">
80   checkbox7
81   <input type="checkbox" name="checkbox" value="checkbox8">
82 checkbox8
83 </form>
84
85 </BODY>
86</HTML>
87