【翻译】Building a Simple Blog Engine with ASP.NET MVC and LINQ - Part 2

摘要

在该ASP.NET MVC Framework系列文章的第二篇里,Keyvan介绍了如何在ASP.NET MVC中使用Controller。他在Blog系统添加了Controller并讨论了一些细节。首先介绍了URL Routing的概念,然后对Controller类进行深入剖析,最后研究了如何在简单Blog系统中实现Controller。
原文地址:Building a Simple Blog Engine with ASP.NET MVC and LINQ - Part 2

内容

  • 简介
  • 默认URL Routing模式
  • 剖析Controller类
  • Action方法
  • Action方法的参数
  • 实现KBlog的Controller
  • 小结

简介

在本系列的第一篇文章中,我简单介绍了MVC模式、ASP.NET MVC以及KBlog(在本系列文章中创建的简单Blog系统)的基本结构。在第二篇文章中,我们将涵盖MVC模式中三个主要元素之一的Controller。

Controller是MVC模式中最普遍的元素,它负责处理用户输入、执行合适的代码以加载数据并呈现给用户。

你可以认为Controller是用户和视图的中间组件,试图处理用户输入并返回恰当的输出,尽管这个定义并不是100%正确。

通常情况下,我们在Web应用中使用模板文件来处理不同的请求。这意味着如果用户要发布(Post)一篇文章,就对应一个Post.aspx页面,如果有其它操作就有应的页面与之对应。在MVC Framework中就完全不同了,我们使用Controller类还处理请求。换句话说,你不必再用.aspx页面来处理用户请求,而是通过编写Controller类,处理请求并将恰当的数据传递给最终用户所看到的视图页面。

但是,Controller类是如何接收请求的呢?ASP.NET使用了URL Routing机制,该机制使用路径选择(routes)将请求定位到恰当的Controller类上。对于Routing,ASP.NET MVC Framework中有默认的定义,但你也可以按需修改,就想我在KBlog中所做的那样。以后的文章中将涵盖整个Routing机制,而本文只对必要部分进行快速浏览。

本文涉及的另一个话题是分析Controller类及其结构,包括Action方法和如何向Action方法中传递参数以便发送请求。

默认URL Routing模式

正如我所说,ASP.NET MVC Framwork的Routing机制中包含默认的Routing模式,用户也可以在ASP.NET应用程序类(Global.asax文件)中自己修改该机制。

但本文我们并不关心Routing机制的细节以及如何修改它们, 本系列以后的文章中将详细的阐述这些内容。在此我们只是简单的谈谈默认的Routing模式。

默认情况下,ASP.NET MVC Framework将对于路径/Url/的请求定位到名为UrlController的Controller类上。例如,对URL为/Post/的请求会定位到PostController上。

此外,所有对于以/Url/开头的路径的请求也同样将定位到UrlController类。例如,对于/Post/Technology/Surface的请求将定位到PostController类。

剖析Controller类

Controller类与其它类没有什么区别,没有必要去继承一个特殊的类或实现一个接口。但是在我们实际开发Controller类时,可以从System.Web.MVC.Controller(译注:此处应为System.Web.Mvc.Controller)基类继承,以简化开发。

Controller类提供了很多工具,可以辅助我们开发ASP.NET MVC应用,我想任何开发者都不会拒绝它吧。Controller类被应用于Visual Studio的所有项目和文件模板中,当使用Visual Studio创建新的MVC Controller类时,该类就出现在代码中了。

可以通过“Add New Item”对话框添加新的MVC Controller类文件,如下图所示:

Listing 1为名为SampleController类的默认代码:

Listing 1

using System;
using System.Web;
using System.Web.Mvc;
 
namespace KBlog.Controllers
{
    
public class SampleController : Controller
    
{
        [ControllerAction]
        
public void Index()
        
{
            
//Add action logic here
        }

    }

}

如你所见,程序引用了System.Web.Mvc命名空间(安装了ASP.NET 3.5 Extensions后即可),并且该类继承了Controller基类。

Action方法

Controller类最重要的部分是它的Action方法。Action方法是不返回任何值的公共方法,在方法前用ControllerAction属性进行标记即可将其转换为Action方法。

那么Action方法的职责是什么呢?一个Action方法接收请求,触发适当的逻辑从数据模型中获取数据,并将其传递给视图以向最终用户显示适当的结果。因此Action方法相当于Controller类的心脏。

那么Action方法是如何工作的呢?它是基于传入的参数的。显然,URL意味着用户需要的内容,以及将各个请求定位到适当的Controller类的Routing机制。而这里,参数指定了调用哪一个Action方法。

例如,当用户访问/Post?ID=5这个页面时,请求将被定位到PostController类,该类中的Action方法Post将处理该请求。

Listing 2在Listing 1的基础上增加了一个Action方法。(译注:Lising 2和Listing 1一模一样)

Listing 2

using System;
using System.Web;
using System.Web.Mvc;
 
namespace KBlog.Controllers
{
    
public class SampleController : Controller
    
{
        [ControllerAction]
        
public void Index()
        
{
            
//Add action logic here
        }

    }

}

默认情况下ASP.NET MVC项目中包含一个HomeController类,来处理对默认主页的请求。

下一节中我们将更多的讨论Action方法中的参数。

Action方法的参数

参数是Controller类的关键部分,它将用户的选择指定到Action方法。参数可以直接从URL及其查询参数中得到,你要决定如何在自己的逻辑中使用它们。

在Action方法中处理参数有几种不同的方式,如何决定取决于开发者。

第一种方法是在URL中使用查询参数,并在Action方法中获取这些参数。显然,这种情况下Action方法是不需要任何参数的。Listing 3展示了这样一个Action方法,它从查询字符串中获取参数ID。

Listing 3

// Sample URL: /Page/Article?ID=5
[ControllerAction]
public void Article()
{
    
int id = Convert.ToInt32(Request["ID"]);
}

这种方法我们可以在所有的ASP.NET Web应用程序中使用。第二种方法将URL参数作为Action方法的参数传入,参数类型已经由方法定义好了。

如Lising 4中所示,你可以在Action方法中使用id参数来编写逻辑。

Listing 4

// Sample URL: /Page/Article?ID=5
[ControllerAction]
public void Article(int id)
{
    
// Implement the logic to handle the
    
// request based on the id parameter
}

第三种方法与第二种类似,同样是通过Action方法的参数来处理,所不同的是参数是通过子路径来得到的。例如路径若为/Page/Acticle/5,那么5可以认为 是传递给Controller的ID参数。

Listing 5

// Sample URL: /Page/Article/5
[ControllerAction]
public void Article(int id)
{
    
// Implement the logic to handle the
    
// request based on the id parameter
}

可以使用可空类型的变量来为Action方法传递可选参数。例如,假设你有一篇由多个小节组成的文章, 在某种情况下用户可以请求整篇文章,而在另一种情况下,他也可以传递Section参数,通过唯一的标题字符串来得到某一特定小节。

Listing 6为其实现:

Listing 6

// Sample URL 1: /Page/Article/5
// Sample URL 2: /Page/Article/5?section=introduction
[ControllerAction]
public void Article(int id, string? section)
{
    
// Implement the logic to handle the request
    
// based on the id and/or section parameters
}

实现KBlog的Controller

既然已经熟悉了Controller类、Action方法以及Action参数的原理,我们就可以在KBlog中用它们来修改代码。

KBlog需要三个Controller(注意,在这里我们为了展示一些概念仅仅建立一个非常简单的Blog系统):

  • 首页的Controller:加载最新的N篇文章和所有类别的列表。
  • 单独一篇文章的Controller:通过ID加载某篇文章的数据。
  • 单独一个种类的Controller:通过唯一的类别名加载属于某一类别的所有文章。

Listing 7是HomeController的代码,我们不需要传递任何参数。 稍后我将对其进行修改,以加载最新的文章和所有的类别,并将其传递给适当的View。目前,我们只需关注代码的Controller部分。

Listing 7

using System;
using System.Web;
using System.Web.Mvc;
 
namespace KBlog.Controllers
{
    
public class HomeController : Controller
    
{
        
// Sample URL: /Default.aspx
        [ControllerAction]
        
public void Index()
        
{
 
        }

    }

}

另一个Controller是PostController,它处理对单独某篇文章(通过唯一的ID)的请求(Listing 8)。注意,为了将请求定位到该Controller,稍后我们需要修改默认的Routing定义。

Listing 8

using System;
using System.Web;
using System.Web.Mvc;
 
namespace KBlog.Controllers
{
    
public class PostsController : Controller
    
{
        
// Sample URL: /Post/25
        [ControllerAction]
        
public void Post(int id)
        
{
 
        }

    }

}

最后一个Controller是CategoriesController,它处理对单独某一类别(通过唯一的名称)的请求,并加载属于该类别的所有文章(Listing 9)。和PostController类似,我们需要修改默认的Routing定义,来将请求定位到该Controller。

Listing 9

using System;
using System.Web;
using System.Web.Mvc;
 
namespace KBlog.Controllers
{
    
public class CategoriesController : Controller
    
{
        
// Sample URL: /Category/DotNet
        [ControllerAction]
        
public void Category(string name)
        
{
 
        }

    }

}

小结

在ASP.NET 3.5 MVC Framework系列文章的第二部分,我们讨论了MVC模式的重要组成部分——Controller。

首先,我们介绍了Controller,然后分析了ASP.NET MVC中的Controller类。接下来谈到了Action方法以其参数。最后我将这些理论应用到KBlog(我在这个系列文章中编写的简单示例Blog系统)中,使得开发更进一步。

在接下来的文章中,我们将讨论数据模型(Model)、视图(View)、MVC应用中的单元测试、URL Routing以及其他相关概念。

posted @ 2008-02-01 16:12 麒麟.NET 阅读(...) 评论(...) 编辑 收藏