无论是在ASP.NET Web表单还是在MVC框架中,用户界面都要经历一个呈现的过程。在Web表单中,Page类使用一个呈现进程实现把控件层次翻译成浏览器端的HTML内容。隐藏代码文件负责提供影响这些控件状态的属性及方法,最终把每一个控件转换成浏览器端对应物。当然,页面生命周期也会影响这一过程。

  ASP.NET MVC则从根本上改变了上述过程。MVC不再是操作一个控件层次结构,而是采用自顶向下的模式进行直接呈现,这很类似于早期的ASP工作模式。然而,ASP.NET MVC和早期ASP之间的核心区别在于,MVC的业务逻辑是与视图层是分离的,而不是缠绕在一起的。每个视图都可以有自己对应的模型,可以直接访问“模型”(其中包含自控制器返回的数据)中的属性,从而实现直接引用特定于视图的数据。在这篇文章后面的示例中,你会看到我们将频繁地使用这一过程。

  对大多数开发人员而言,构建用户界面的方法可能是一个巨大的转变。例如,在Web表单中,如果你想通过编程方式在HEAD元素中添加一个样式表,他可以通过把代码放到Load事件处理程序中实现这一目的。但在MVC框架下,只能在HEAD元素被呈现时把样式表注入到视图中。你不能直接把样式表引用为对象。

  一、创建用户界面

  MVC程序在用户界面构建方面与以前的Web表单仍然使用类似的结构,例如,它也使用@Page指令,而且设置参数是一致的(但是,隐藏代码引用指向一个标准的ASP.NET MVC类)。它仍然使用HTML标记与服务器端代码混合模式。但是,为了使整个服务器端处理更加容易,MVC不再使用控件方式而是使用HtmlHelper类。以前是服务器端控件的功能现在变换为一个HtmlHelper类的方法。例如,为了在浏览器中呈现一个文本框元素,我们不必再使用TextBox控件,而是通过下面的代码来实现。

<%= Html.TextBox(“Control”).ToHtmlString() %>

  上面这一句能够把一个<input type="text">元素直接呈现到响应流中。请注意这里的ToHtmlString方法调用。这是ASP.NET MVC 2中提供的一个新功能—不再是以前那样直接返回一个字符串。但是,如果你喜欢你可以省略这个方法调用,代码会像以前一样工作(即方法将被隐式调用)。

  下面展示了一个使用这些助理类的用户界面示例:

  清单1—在MVC框架下定义表单的代码示例

<div>
    Name: <%= Html.TextBox("Name") %>
</div>
<div>
    State: <%= Html.DropDownList("State", new SelectListItem[]
         {
            new SelectListItem { Text = "Pennsylvania", Value = "PA" },
            new SelectListItem { Text = "Ohio", Value = "OH" },
            new SelectListItem { Text = "Maryland", Value = "MD" }
         }) %>
</div>
<div>
    <%= Html.ActionLink("View State Codes", "Index", "Home") %>
</div>
<div>
    <%= Html.CheckBox("SecurityAgreement", true) %>
    Reviewed security agreement
</div>

  上述每一个方法都返回一个描述HTML控件的字符串。使用这些方法是考虑到MVC的内置工作特征,因为MVC可以使用某些模式把这些特征连接起来。如果你喜欢的话,你当然可以直接定义这些控件的HTML代码。

   二、新的“For”后缀助理方法

  MVC 2中又提供了一组新的带有For后缀的助理方法(这实质上都是一些扩展方式,你可以通过在这些方法上单击右键并转到对应定义的方式来跟踪观察),诸如TextBoxFor,CheckBoxFor等等。这些方法通过一个lambda表达式来选择模型内的属性并最终用于显示到用户界面中。例如,Html.TextBoxFor(i=>i.FirstName)语句就会提取模型中第一个姓名的值。

  清单2—使用带有For后缀的助理方法(扩展方法)的代码示例

<%= Html.HiddenFor(i => i.ProjectStoryScenarioKey) %>
<%= Html.HiddenFor(i => i.ProjectStoryKey) %>
<div>
    <div>
        <%= Html.TextBoxFor(i => i.ScenarioNumber) %>
        <%= Html.ValidationMessageFor(i => i.ScenarioNumber, "*") %>
    </div>
    <div>
        <%= Html.TextAreaFor(i => i.Description) %>
        <%= Html.ValidationMessageFor(i => i.Description, "*") %>
    </div>
</div>

  归纳来看,上面的代码做了两件事情:第一是使用模型中提供的内在值呈现基本的HTML元素;第二,元素的ID和name都使用了lambda表达式中提供的文本(在这个例子中是ScenarioNumber和Description)。借助于这些方法,我们可以很方便地呈现直接对应于模型部分的内容,并且有助于控制模型绑定。

  三、数据注解

  数据注解有利于在界面中呈现数据时从数据模型中提取特定的内容。其实,远不止这些。通过使用lambda表达式,ASP.NET MVC框架还会搜索任何添加于属性上的数据注解。数据注解其实是一个你在模型上指定的属性。这些注解可以控制辅助方法如何以不同的方式工作。例如,让我们来分析一下下面的示例属性:

  清单3—数据注解的代码示例

[
DisplayName("Boolean Val"),
Required
]
public bool BoolValue { get; set; }

  在这里,我们的模型类中定义了一个属性BoolValue,其上添加了两个注解,后者用于进行验证(以后的文章中会专门讨论这个问题),前面那个注解用于存储字段的显示名称。你会注意到,如果你想使用接下来的扩展方法输出一个相应于这个属性的标签元素的话,那么使用上面的DisplayName属性是非常方便的。

  清单4—呈现标签的代码示例

<div><% // Renders Boolean Val %>
<%= Html.LabelFor(i => i.BoolValue) %>
<%= Html.CheckBoxFor(i => i.BoolValue) %>
</div>

  上面的代码使用“Boolean Val”名字生成一个标记元素,接着生成一个名称为模型值中对应名字的复选框元素。

  四、模型绑定综合举例

  现在,我们通过一个较完整的例子来分析模型绑定的整个工作过程。一开始,我们必须先有一个指向我们的视图的控制器。下面的示例中提供的第一个行为方法通过引用一个SampleForm/ForIndex网址返回视图。第二个行为方法则简单地响应一个表单回寄。

  清单5—定义控制器的代码示例

public class SampleFormController : Controller
{
    [HttpGet]
    public ActionResult ForIndex()
    {
        return View(new SampleFormTestClass
        {
            AltBoolValue = "No",
            BoolValue = true,
            ComboValue = "PA",
            DateValue = DateTime.Now,
            DecimalValue = 3.4M,
            IntValue = 23,
            StringValue = "A Test"
        });
    }
    [HttpPost]
    public ActionResult ForIndex(SampleFormTestClass test)
    {
        return View();
    }
}

  上面定义的这个控制器非常简单。只是,请特别注意一下其中提供的初始值。相应于ForIndex视图所使用的模型是SampleFormTestClass,其中包含了一些数据注解。MVC框架中针对验证支持定义了大量的注解。但是篇幅所限,本文不再列举。接下来给出的是模型部分的定义。

  清单6—定义模型的代码示例

public class SampleFormTestClass
{
    [DisplayName("Alternative Boolean Val (Yes/No)")]
    public string AltBoolValue { get; set; }
    [
    DisplayName("Boolean Val"),
    Required
    ]
    public bool BoolValue { get; set; }
    public string ComboValue { get; set; }
    [DataType(DataType.DateTime)]
    public DateTime DateValue { get; set; }
    public decimal DecimalValue { get; set; }
    public int IntValue { get; set; }
    public string StringValue { get; set; }
}

  在下面的表单定义中,用户界面部分正是使用了上面模型中定义的属性。在此我想逐段进行介绍。第一部分是表单的定义。你可以使用下面的语法之一来指定一个表单。

  清单7—定义表单的内联代码示例

1.<% Html.BeginForm(); %>
2.     Form Content
3.<% Html.EndForm(); %>
4.<% using (Html.EndForm()) { %>
5.<% } %>

  在表单标签内的所有内容都被回调给服务器端带有[HttpPost]属性标记的ForIndex行为方法。首先呈现的是对应于BoolValue属性的标签和复选框控件。你应当还记得,它有一个DisplayName属性标记,所以在呈现文本时文本内容将是“Boolean Val”而不是实际的属性名字。

  清单8—构建单标签和复选按钮元素的内联代码示例 

<div>
<%= Html.LabelFor(i => i.BoolValue) %>
<%= Html.CheckBoxFor(i => i.BoolValue) %>
</div>

  另外,如果你喜欢使用单选按钮来表达yes/no字段,下面的代码给出了一种选择。虽然没有提供类似于RadioButtonList这样的控件,但是每一个单选按钮都可以映射到一个布尔型或者其他类型的属性(本例是一个字符串),并最终呈现为单选按钮列表。第二个参数并不是单选按钮的文本。实际上,它是与从列表中选择的项相匹配的值。因为模型中没有定义任何值,第二个单选按钮便被选中。

  清单9—构建单选按钮元素的内联代码示例

<div>
    <%= Html.RadioButtonFor(i => i.AltBoolValue, "Yes") %>
    <%= Html.RadioButtonFor(i => i.AltBoolValue, "No") %>
</div>

  在上面的代码中,我们讨论了如何把文本框和文本区呈现到屏幕上。其实,接下来还有一个隐藏的字段和一个密码框。对于这些控件,仅需注意的是,如果你有一个专门的数据类型(如日期时间型或一个整数)要呈现到一个文本框中,那么,MVC框架尚未提供针对这些类型数据值的任何隐含错误检查。为此,你可以在这些值上使用验证机制来防止上述错误。如果由于某种原因,输入了一个无效的值,那么该值将被省略,代之以默认值(例如默认日期为1/1/0001)。

  清单10—构建文本元素的内联代码示例

<div>
<%= Html.TextBoxFor(i => i.DateValue) %>
</div>
<div>
    <%= Html.TextAreaFor(i => i.StringValue) %>
</div>
<div>
    <%= Html.HiddenFor(i => i.IntValue) %>
</div>
<div>
    <%= Html.PasswordFor(i => i.StringValue) %>
</div>

  MVC也支持标准列表类型。以下方法能够使用一个数据列表来呈现一个下拉列表和列表框元素(可以使用静态数据也可以使用数据绑定实现)。注意,其中是如何提取基本值作为默认选择项的。这可能是发生在控制器内而不是用户界面上的一个典型的操作,但为了说明问题,我特意把它们放到了用户界面部分。

  清单11—构建列表的内联代码示例

<div>
    <%= Html.DropDownListFor(i => i.ComboValue, new SelectListItem[]
         {
            new SelectListItem { Text = "Ohio", Value = "OH" },
            new SelectListItem { Text = "Pennsylvania", Value = "PA" },
            new SelectListItem { Text = "Maryland", Value = "MD" }
         }) %>
</div>
<div>
    <%= Html.ListBoxFor(i => i.ComboValue, new SelectListItem[]
         {
            new SelectListItem { Text = "Ohio", Value = "OH" },
            new SelectListItem { Text = "Pennsylvania", Value = "PA" },
            new SelectListItem { Text = "Maryland", Value = "MD" }
         }) %>
</div>

  值得注意的是,并不是每一个HTML元素都有一个关联的HTML辅助方法。举例来说,任何类型的按钮元素就没有相应的ButtonFor方法。而且,也没有为超链接按钮提供相应的支持。这是一个重大的改变,这也是由于MVC框架工作方式与Web表单框架根本形式不同所决定的。

通过使用我们的lambda表达式,表单中回寄的值被自动映射到类的属性上,而该类对应于行为方法的参数。因此,既然字段回寄与我们的模型类相关联,所以,MVC会自动把这些值提供给我们的对象,而不必由我们手动执行此任务。如果你喜欢,你可以创建一个定制的模型绑定器。但是,有关这个内容已经超出了我们的主题了。

  如果你不喜欢以这种方式直接使用对象引用,而且想更多地控制上述过程,另一种方法是指定一个FormCollection集合作为行为方法参数,其中可以包含所有被回寄的表单值。这样,您就可以更多地控制其中的数据。你还可以使用UpdateModel或TryUpdateModel方法把这个表单集合应用到一个模型对象上。

  五、小结

  正如你所见,ASP.NET MVC框架提供了强大的功能。一旦你理解了这篇文章中提到的构建模式,你就可以开始创建复杂的用户界面。关键是理解MVC怎样控制整个生命周期/API/层次结构,并使用内联呈现方式,以及理解MVC所利用的逻辑分离原理。

http://www.liangchi.com.cn

转载于:https://www.cnblogs.com/webearly/archive/2010/08/19/1803777.html

ASP.NET MVC2用户界面的巨大改变相关推荐

  1. Asp.net MVC2使用第三方控件

    ASP.net MVC框架提供了大量的HTML渲染的方法和控件,但是使用起来有诸多的不便.对于有经验的设计者使用HTML helpers可以构建一个简单的用户界面,然后加上一些HTML和css就能构建 ...

  2. Asp.net MVC2.0系列文章-运行Web MVC2.0 Demo

    安装VS2010 首先安装VS2010,安装过程请参考文章: http://www.cnblogs.com/ywqu/archive/2010/01/27/1657450.html. 创建第一个MVC ...

  3. Asp.Net MVC2.0 Url 路由入门---实例篇

    本篇主要讲述Routing组件的作用,以及举几个实例来学习Asp.Net MVC2.0 Url路由技术. 接着上一篇开始讲,我们在Global.asax中注册一条路由后,我们的请求是怎么转到相应的Vi ...

  4. ASP.NET MVC2+MSSQL+Godaddy

    先感谢一下博客园,在网上浪了这么长时间,现在发现还是博客园的文章技术含量要高一点! 现在言归正传,最近在课外学习ASP.NET MVC,也在微软的官网上学了一些例子教程,现在刚好有机会可以实践一下,一 ...

  5. Asp.net MVC2.0系列文章-MVC简介篇

    使用微软VS工具开发Web应用程序主要有两种方式:一种是常用的创建Asp.net Web Forms,另外一种就是今天着重介绍的Asp.net  MVC. <?XML:NAMESPACE PRE ...

  6. Oxite移植到ASP.NET MVC2 BETA 笔记(关于Html.RenderPartialFromSkin)

    在将Oxite移植到asp.net mvc2 beta平台后,经过一系列有关"方法调用"变更的修正后,终于能够通过编译运行起来了!(移植后的源码参见:http://ecubecms ...

  7. Asp.net MVC2.0系列文章-编辑和删除新闻操作

    上一篇文章,我们简单地完成了新闻内容的展示功能(Asp.net MVC2.0系列文章-显示列表和详细页面操作),此篇文章,我们使用Asp.net MVC2.0实现新闻记录的编辑和删除功能. 创建Vie ...

  8. [ASP.NET MVC2 系列] ASP.NET MVC 之如何创建自定义路由约束

     [ASP.NET MVC2 系列]      [ASP.NET MVC2 系列] ASP.Net MVC教程之<在15分钟内用ASP.Net MVC创建一个电影数据库应用程序>      ...

  9. 【飞秋】Asp.net MVC2 model验证 看似美好,实则让人失望。

    最近几天看了一下Asp.net MVC2的model验证,初始的感觉让我眼前一亮,于是去看了看它的源代码,Validation和Metadata部分应该是从Dynamic Data哪里得到的灵感,一切 ...

最新文章

  1. mysql 最小日期函数_MySQL 日期加减函数汇总
  2. GAN眼中的图像翻译(附神奇歌单)
  3. 思科无线AP胖瘦互转
  4. 图解http-ping使用
  5. 5分钟了解Mockito
  6. Maven-学习笔记06【基础-Maven工程servlet实例】
  7. 系统制成docker镜像_docker镜像原理 镜像制作 dockerfile
  8. LeetCode题库整理【Java】—— 1两数之和
  9. 使用datareader检索数据
  10. Update From 用法
  11. python对seo有什么用_现在做seo会运用到python吗
  12. 收藏!50个帮你自我提升的网站
  13. 26岁零基础转行学习前端可以找到工作吗?
  14. python打包exe_Python | 用Pyinstaller打包发布exe应用
  15. NLPIR python测试
  16. 计算机配件对比,基本参数 尺寸对比 接口对比
  17. 噪音分贝测试软件在线,分贝测试(在线分贝测试仪)
  18. 浙江大学计算机考研真题及答案,浙江大学计算机考研真题-20210531140358.docx-原创力文档...
  19. mysql:设有一数据库,包括四个表:学生表(Student)、课程表(Course)、成绩表(Score)以及教师信息表(Teacher)。四个表的结构分别如表1-1的表(一)表(四)所示
  20. 模仿blblblbl登录页面

热门文章

  1. jQuery的几种简单实用效果
  2. [每天一个知识点]20-Java语言-菱形运算符
  3. 12.present perfect(2)
  4. Flink流处理中的表
  5. 即席查询Presto
  6. splice方法_Array中splice用法
  7. 《Python自动化》学习笔记:百度云智能实现提取身份证信息
  8. python 类命名空间,关于python:命名空间和类
  9. 机器数.原码 反码 补码比较理解
  10. java面向对象编程的思想_java面向对象编程思想