巨大转变!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行为方法新改进

时间: 2024-07-31 14:45:32

巨大转变!ASP.NET MVC2行为方法新改进的相关文章

一起谈.NET技术,巨大转变!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能够调用行为方法,所以我们需要一种方法来检测一个

对ASP动态包含文件方法的改进

动态 ASP 本身不支持动态包含文件,现在的动态包含是通过 FSO 把被包含的文件合并到主文件里再运行.以下也有把形如 <!--#include file="filename.asp" --> 的普通包含文件方式称作"传统引用",用函数实现的动态包含文件称作"动态引用".常见的程序如下: Function include(filename)Dim re,content,fso,f,aspStart,aspEndset fso=Crea

对ASP 动态包含文件方法的改进

ASP 本身不支持动态包含文件,现在的动态包含是通过 FSO 把被包含的文件合并到主文件里再运行.以下也有把形如 <!--#include file="filename.asp" --> 的普通包含文件方式称作"传统引用",用函数实现的动态包含文件称作"动态引用".常见的程序如下: Function include(filename) Dim re,content,fso,f,aspStart,aspEnd set fso=Creat

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

在本系列文章中,我们将针对微软最新推出的ASP.NET MVC 2.0中提供的新特征相关的基础性编程问题进行全面的探讨.在本文(第一篇)中,我们将通过对比ASP.NET MVC框架与ASP.NET Web表单框架的方式来学习ASP.NET MVC 2.0提供的新功能. 在2010年4月,微软正式发布了Visual Studio的下一个版本2010.ASP.NET MVC 2.0也作为其中的一个新框架成员一同发行.ASP.NET MVC如今已是一个成熟的产品,采用了全新的设计,大大提高了开发效率.

一起谈.NET技术,ASP.NET MVC2.0在Tab页中实现异步无刷新分页

概述 很多地方都存在以Tab页来呈现数据的方式,比如网易.新浪.搜狐.QQ等知名的门户网站的首页,还有大家熟知的博客园首页,都是用了tab页来显示数据.大家之所以喜欢用Tab,因为它能大大的增加显示数据的空间,能在固定的空间中显示更多的数据.分页也是为了方便数据的显示,在应用系统中必不可少.这篇文章使用Jquery在ASP.NET MVC中使用Tab页,以及在Tab页中实现异步无刷新的分页功能.估计这个大家都会用得到的. 在ASP.NET MVC中实现分页,在之前的一篇博文:ASP.NET MV

ASP 3.0中的新特性

    假如读者已经熟悉了ASP 2.0,并正在寻找3.0版本中的实际改变的列表,那么将在下面发现这些信息.假如读者是一个ASP的初学者,可以越过本章到下一章,那里循序渐进地介绍了ASP对象和它们的用法.    ASP 3.0新特性概要    在ASP 3.0中,有一些新的特性或经历较大的变化或改进的特性.    1. 无脚本的ASP    如早先提到的, ASP处理不包括任何脚本的.asp页的速度是很快的,假如你正在创建的站点或Web应用程序文件最终可能使用ASP,最好让这些文件使用.asp文

Linq to SQL加注Data Annotation在Asp.Net MVC2中的应用

一.写作前提 最近正在做一个Asp.Net MVC2的Project,用到了Linq to SQL,但是对于如何在MVC2中使用 Linq to SQL 生成的强类型加注Data Annotation,我们都知道在MVC2中我们可以定义自己的Model,然后给Model 加Data Annotation,从而在View中可以实现完美的Client Validation(这些Data Annotation也我们也可 以去自己定义).但是对于Linq to SQL 生成的强类型,我们有两个问题,第一