一起谈.NET技术,巨大转变!ASP.NET MVC2行为方法新改进

  在 上一篇文章中,我们看到了构建用户界面的基本实现。但在现实世界中,我们需要使用更加复杂的方法来开发出更复杂的用户界面。例如,用户不希望点击应用程序中的多个链接才浏览到他们想要的信息,他们希望能够很方便的在一个视图中便取得他们要求的所有信息。

  在ASP.NET MVC中,我们仍然可以使用用户控件来创建一个应用程序中的可重用组件—它们被称为部分视图(Partial View)。自从ASP.NET MVC 1.0始就提供了这一支持。在本文中,我们还要使用这种方法,并且结合MVC 2.0中提供的一个新功能—Html.Action,联合起来使用。

  一、创建用户界面

  在Web表单中,当用户界面变得极其复杂时,开发人员往往通过构建一个巨大的ASPX页面或者把复杂的逻辑分解成单独的用户控件或自定义控件的途径来克服这一复杂性。通常情况下,只有当非常有必要进行重用时才把自定义控件派上用场,而用户控件则被经常使用,这是因为它们易于使用且设计简单的缘故。

  在ASP.NET MVC中,上述这些类似功能可以借助于部分视图(相当于用户控件)或自定义HTML助理类(相当于自定义控件)来实现。

  借助于MVC 2.0中新引入的一个功能—Html.Action方法,可以使一个行为方法把它的响应直接注入到一个父级视图中。而第二个行为方法返回待注入的一个视图,我们可以把这个方法实现为一个自我包含的实体或类型。局部视图可以建立一个表单以回寄到它的控制器,而主视图可以回寄到另一个不同的控制器。这种实现表单间互动的思路可谓清晰易懂,但在实现这种方法时仍然有一些问题值得关注。下面,让我们研究一个具体的示例。

  清单1—使用Html.Action方法的表单示例


<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<p>
Main Action
</p>
<% Html.BeginForm(); %>
<div>
Name: <%= Html.TextBox("IndexName")%>
</div>
<div>
Value: <%= Html.TextBox("IndexValue")%>
</div>
<input type="submit" value="save" />
<% Html.EndForm(); %>
<%= Html.Action("Custom", new { title = "Test Title" })%>
</asp:Content>

  在上面代码中,我们有一个简单的表单。本表单包含了两个字段。接下来跟着的是调用一个名称为Custom的行为方法(位于相同的控制器内)。这个辅助行为方法以路由值形式调用控制器方法本身,并把控制器的名称(可选)和任何形式的数据传递到该控制器中。

  清单2中给出的部分视图已经被注入并成为主视图的一部分。注意,这个视图定义了自己的表单(这是一种使部分视图自包含的方式)。任何到服务器端的回寄都被重定向到这个Custom行为方法中,而不是重定向到主行为方法。这一点特别重要。

  清单2—注入部分视图的示例


<p>
Custom Action
</p>
<% Html.BeginForm("Custom", "RenderingActions"); %>
<div>
Name: <%= Html.TextBox("CustomName")%>
</div>
<div>
Value: <%= Html.TextBox("CustomValue")%>
</div>
<input type="submit" value="save" />
<% Html.EndForm(); %>

这个部分视图是自包含式的,除了可以使用与父视图所有相同的数据资源(例如HTTP上下文和路由数据)外,它并不知道父视图的其他内容。现在,我们创建了一个表单,它在浏览器中的样子如图1所示。


  图1—示例表单

    其中,Main Action部分是通过父视图创建的用户界面,而Custom Action被创建为一个局部视图。处理表单回寄的控制器如清单3所示。

  清单3—控制器代码


public class RenderingActionsController : Controller
{
[HttpGet, ChildActionOnly]
public ActionResult Custom()
{
return PartialView();
}
[HttpPost]
public ActionResult Custom(FormCollection form)
{
return PartialView();
}
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(FormCollection form)
{
return View();
}
}

你可能搞不清这究竟是如何工作的,毕竟我们有两个不同的过程在这里起作用:主表单的内容和子表单的内容。我们知道,在MVC中不存在任何ViewState的概念,回寄子视图不会自动保留父视图的数据,理解这一点是非常重要的。当点击相应于子控制器方法的提交按钮时,它回寄自身的内容却并不回寄父视图的内容。因此,针对这种情形应当预先规划一个很好的应对策略。

  在我们进一步讨论这一点之前,让我们来看一看把内容寄送回行为方法的基本标记代码。下面是我们的示例中的两个表单对应的标记代码。请注意其中的表单行为方法和控制引用。

  清单4—HTML标记代码


<form action="/RenderingActions" method="post">
<div>
Name: <input id="IndexName" name="IndexName" type="text" value="" />
</div>
<div>
Value: <input id="IndexValue" name="IndexValue" type="text" value="" />
</div>
<input type="submit" value="save" />
</form>
<p>
Custom Action
</p>
<form action="/RenderingActions/Custom" method="post">
<div>
Name: <input id="CustomName" name="CustomName" type="text" value="" />
</div>
<div>
Value: <input id="CustomValue" name="CustomValue" type="text" value="" />
</div>
<input type="submit" value="save" />
</form>

上述代码中,我们创建了两个不同的表单(你也可以建立更多的表单),它们将各自进行独立的回寄。另外,上述代码中包含了相对于Web表单框架的一个重要变更,因为以前只能是由一个Web表单包含所有的控件。

  二、使用AJAX技术

  前面的做法有可能导致为您的控制器添加大量额外的代码。被注入的局部视图执行一个到行为方法Custom的回寄操作,这反过来又导致第二阶段的再处理,并重定向回到原来的视图以显示新的数据。这其中会导致大量的工作。使用AJAX技术则能够节省一些处理时间。清单5取代了清单2中的部分视图,它能够以异步方式寄送表单数据。

  清单5—使用AJAX表单的代码


<p>
<div id="customresponse"></div>
<% using (Ajax.BeginForm("AjaxCustom", new AjaxOptions
 { UpdateTargetId = "customresponse" }))
{%>
<div>
Name: <%= Html.TextBox("CustomName")%>
</div>
<div>
Value: <%= Html.TextBox("CustomValue")%>
</div>
<input type="submit" value="save" />
<%}%>
</p>

请注意上面使用的UpdateTargetID属性。此属性用于指定要把响应信息注入到一个特定的HTML元素目标。此更新的目标是在以AJAX模式回寄时调用方法的返回结果对应指定的目标。表单本身在表单的元素内向服务器发出回寄,并在清单6中进行处理。这一点特别值得注意。

  清单6—返回一个响应


[HttpPost]
public ActionResult AjaxCustom(FormCollection post)
{
if (Request.IsAjaxRequest())
return Content("Success");
else
return PartialView();
}

当在一个视图中操作多个行为时,表单必须关注是以同步还是以异步方式发出的请求。如果请求是一个Ajax请求,结果的内容将被注入到更新的目标(一个DIV元素)。我们不希望返回部分视图,因为这会把用户界面复制到我们的自定义响应的DIV(更新目标)中。另外,我们并不需要使用更新目标来重新加载现有的用户界面,因为在AJAX请求模式下用户界面从未消失。 

     另一方面,当不使用AJAX方式时同步请求回寄到服务器端,需要你来处理整个请求。只返回成功的消息是不能按预期那样工作,因为那时用户界面会消失。当请求不使用Ajax回寄到服务器端时,你要自己处理整个的请求,而且为此您将拥有完全的控制权。这意味着,你必须针对每一个同步请求返回整个部分视图用户界面,并且要关注何时可能发生这种情况。处理上述两种情形可能要求您使用客户端JavaScript技术。

  在这个例子中,正是发生了上述情况,因为主视图中的提交按钮并没有使用AJAX表单提交其内容,因而引发了到服务器端的一个完整的回寄。由于MVC让我们全面控制相应于每一个请求所呈现的内容,所以我们必须负责返回相同的用户界面信息。  
  三、使用JQuery

  JQuery框架能够与ASP.NET MVC良好地协作。借助于JQuery,我们可以轻松地实现使用AJAX方式把数据以GET和POST寄送到服务器端。ASP.NET MVC框架能够以与ASP.NET MVC的客户端组件同样的方式检测一个AJAX请求。下面,让我们来看一下这样的例子。

  清单7—结合JQuery使用HTML.Action的代码


<p>
JQuery Ajax Index
</p>
<% Html.BeginForm(); %>
<div>
Name: <%= Html.TextBox("IndexName")%>
</div>
<div>
Value: <%= Html.TextBox("IndexValue")%>
</div>
<input type="submit" value="save" />
<% Html.EndForm(); %>
<div id="JQueryCustomParent">
<%= Html.Action("JQueryCustomIndex")%>
</div>

请注意上面代码中并没有使用一个DIV元素来包装部分视图(从JQueryCustomIndex返回),这使得我们可以更容易确定要更新的目标区域。

  在使用JQuery的时候应当注意几个问题。第一,要确保你替换掉更新区域中的全部内容,所以在我们的自定义DIV范围内的一切内容都必须清除并进行替换。第二,发生AJAX替代时部分视图中的JavaScript代码并不被执行;这意味着,脚本必须驻留在此视图中,并且视图必须要了解要更新的部分(这意味着视图和局部视图之间是紧耦合的,除非你做一些额外的工作来防止这一点)。清单8中提供了执行更新的脚本。

  清单8—更新部分视图的代码


<script type='text/javascript'>
function attachToForm(){
$("#JQueryCustomParent").find("form:first").submit(function(e){
e.preventDefault();
$.post($(this).attr("action"),$(this).serialize(),
function(data){
$("#JQueryCustomParent").replaceWith($("<div/>")
.attr("id", "JQueryCustomParent").html(data));
attachToForm();
});
});
}
$(document).ready(function(){
attachToForm();
});
</script>

JQuery在加载时会被关联到我们的目标DIV中的第一个表单中。当提交时,默认的提交执行将被取消,而由jQuery执行回寄。此回寄将使用新的DIV及其内容替换掉我们的目标DIV。当更换内容时,我们失去了对提交处理程序的控制权。之后,这一过程需要重新连接(虽然我们也可能通过使用jQuery中的另一个事件处理方法来纠正这个重新连接问题)。

  于是,局部视图提交数据,JQuery阻挡表单数据的提交并执行到服务器端的回寄,并使用从控制器行为方法返回的新内容替换原先的HTML内容,然而所有这些对用户来说都不会有任何异样的感觉。

  四、结论

  ASP.NET MVC 2中增加了一个Html.Action方法允许多个行为方法出现在同一个视图内,这是一个真正强有力的功能改进。但是,你必须小心注意在多个表单的情况下表单数据是如何回寄到服务器端的。这对开发人员提出了较高的要求。针对这个问题,你可以使用AJAX技术加以补救,你可以选择使用内置的MS AJAX,也可以是JQuery。

【相关文章】:

巨大转变!ASP.NET MVC2行为方法新改进

巨大转变!教你使用ASP.NET MVC2新功能

巨大转变!ASP.NET MVC2用户界面新实践

时间: 2024-12-10 06:51:24

一起谈.NET技术,巨大转变!ASP.NET MVC2行为方法新改进的相关文章

巨大转变!ASP.NET MVC2行为方法新改进

在 上一篇文章中,我们看到了构建用户界面的基本实现.但在现实世界中,我们需要使用更加复杂的方法来开发出更复杂的用户界面.例如,用户不希望点击应用程序中的多个链接才浏览到他们想要的信息,他们希望能够很方便的在一个视图中便取得他们要求的所有信息. 在ASP.NET MVC中,我们仍然可以使用用户控件来创建一个应用程序中的可重用组件-它们被称为部分视图(Partial View).自从ASP.NET MVC 1.0始就提供了这一支持.在本文中,我们还要使用这种方法,并且结合MVC 2.0中提供的一个新

一起谈.NET技术,巨大转变!ASP.NET MVC2调用AJAX新特征

在ASP.NET MVC编程中使用AJAX功能是非常简单的.借助于JQuery框架,你还可以增加其他的优秀特征并且使AJAX调用特别简单.本文中,我们将探讨这方面的编程内容. 一.检测一个AJAX请求 在Web表单中,创建AJAX请求典型的方法是使用一个更新面板.当更新面板回寄时,ScriptManager提供一个方法(通过其isInAsyncPostBack属性)来检测服务器上的AJAX回寄.ASP.NET MVC也提供了类似的机制.因为AJAX能够调用行为方法,所以我们需要一种方法来检测一个

巨大转变!ASP.NET MVC2调用AJAX新特征

在ASP.NET MVC编程中使用AJAX功能是非常简单的.借助于JQuery框架,你还可以增加其他的优秀特征并且使AJAX调用特别简单.本文中,我们将探讨这方面的编程内容. 一.检测一个AJAX请求 在Web表单中,创建AJAX请求典型的方法是使用一个更新面板.当更新面板回寄时,ScriptManager提供一个方法(通过其isInAsyncPostBack属性)来检测服务器上的AJAX回寄.ASP.NET MVC也提供了类似的机制.因为AJAX能够调用行为方法,所以我们需要一种方法来检测一个

一起谈.NET技术,在ASP.NET MVC中进行TDD开发

TDD介绍 TDD是一种开发方法,全称是Test-Driven development,中文是测试驱动开发.作者是Kent Beck.首先让我介绍一下三种常见的开发方式: 第一种:先Coding,然后Bug Fix. 第二种:先Coding,然后Unit Test,最后Bug Fix.很显然用了单元测试的比第一种开发方式要好不少. 第三种:就是本文要说的TDD,它的方式和第二种恰恰相反.TDD先设计单元测试,然后再Coding,最后修复Bug.看下图: TDD开发过程可以看成:给制自己制定一个目

一起谈.NET技术,走向ASP.NET架构设计——第一章:走向设计

前言:很多做开发的人都在不断的摸索着,积极的学习,试图找出一条走向架构设计的成功法则.每当有人问起我们的职业,我们也常常在说:"软件设计".有时,我就在想:"设计",这个已经被我们嚼烂了的词,到底有多少人真正懂"设计"的含义. 自动进入IT,走在开发这条路上,就一直在不断的摸索,寻找,苦思:如何能够才能成为架构师.于是在网络上不断的收集和阅读架构设计方面的书籍和资料,到处在找一些架构师的传记,文章和甚至是采访资料..... 同时一直不断的请教自己

一起谈.NET技术,[翻译]ASP.NET MVC 3 RC 发布通告

今天早上,ASP.NET组发布了ASP.NET 3 RC版(release candidate).你们可以从这里进行下载here. ASP.NET MVC 3是个很完美的发布,增加了大量的功能改进.它可以向后兼容ASP.NET MVC V1 和 V2,可以轻易的升级你现有的项目(可以阅读发布须知,根据里面的步骤去做).你还可以通过我之前发表的博客文章来学习ASP.NET MVC 3的很多功能.  今天的ASP.NET MVC 3 RC build 包含了一些附加的功能改进(除了修正了一些bug外

一起谈.NET技术,实战ASP.NET大规模网站架构:Web加速器

大规模网站瓶颈之一就是性能问题,如何让你的网站飞速运转起来,一直是架构师和开发人员苦于思考的问题.文章将针对基于ASP.NET开发的网站交互性非实时部分进行讨论. 一.WEB加速通常有如下方案: 1.基于ASP.NET技术的页面缓存 基于ASP.NET技术的页面缓存,通常有如下两种应用方式: 一.基于数据库触发(设置缓存依赖策略,当数据库中数据发生变化时,触发缓存失效;但微软提供的解决方案目前仅支持SQL Server,如果是ORACLE需要自己实现触发接口). 二.基于文件依赖的策略(可以设置

一起谈.NET技术,跟ASP.NET MVC一起使用jQuery

藉由ASP.NET MVC内置的扩展性,开发人员便可以使用第三方库,例如jQuery.在使用ASP.NET Webforms的时候,如果使用jQuery而不是ASP.NET AJAX,难度会比较大. 刚开始撰写本文的时候,ASP.NET MVC的版本是Preview 4,有些在Preview 4中使用的技术可能无法在早期版本中正常工作.Preview 4可以在CodePlex上下载. 初步配置 我不打算把它写成一篇完整的jQuery指南,只是简单给出几个跟ASP.NET MVC一起使用这款Jav

一起谈.NET技术,提高ASP.NET应用程序性能的十大方法

一.返回多个数据集 检查你的访问数据库的代码,看是否存在着要返回多次的请求.每次往返降低了你的应用程序的每秒能够响应请求的次数.通过在单个数据库请求中返回多个结果集,可以减少与数据库通信的时间,使你的系统具有扩展性,也可以减少数据库服务器响应请求的工作量. 如果你是用动态的SQL语句来返回多个数据集,那我建议你用存储过程来替代动态的SQL语句.是否把业务逻辑写到存储过程中,这个有点争议.但是我认为,把业务逻辑写到存储过程里面可以限制返回结果集的大小,减小网络数据的流量,在逻辑层也不用在过滤数据,