博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET MVC 入门4、Controller与Action【转】
阅读量:5058 次
发布时间:2019-06-12

本文共 4308 字,大约阅读时间需要 14 分钟。

本系列文章基于ASP.NET MVC Preview5.

Controller是MVC中比较重要的一部分。几乎所有的业务逻辑都是在这里进行处理的,并且从Model中取出数据。在ASP.NET MVC Preview5中,将原来的Controller类一分为二,分为了Controller类和ControllerBase类。Controller类继承自ControllerBase类,而ControllerBase实现是了IController接口。

ControllerBase实现了IController接口的Execute方法,在Route匹配到Controller之后,就会调用Execute方法来进入Controller的处理。这里还定义了一个抽象的方法ExecuteCore方法,该方法会在Execute方法的最后被调用。ControllerBase还定义了三个核心的属性。我们在后面会详细讨论TempData和ViewData。

Controller类除了继承自ControllerBase类以外,还实现了好几个Filter接口,Filter我们在后面再详细讨论。

public
 
abstract
 
class
 Controller : ControllerBase, IActionFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter{ }

Controller类还定义很多有用的方法,我们新建的Controller都必须继承自这个Controller类。例如我们新建一个AdminController:

public
 
class
 AdminController : Controller
{
}

 

Action方法

下面谈一下在Controller中比较重要的Action方法。在ASP.NET MVC中URL都是映射到Controller中的某个Action中,然后由匹配的Action来处理我们的业务逻辑并返回view的。

Controller中的public的方法都被当作是Action方法。Action方法通常返回一个ActionResult的结果。例如我们为前面的AdminController定义一个Setting的Action方法,用于设置Blog的一些基本参数:

public
 
class
 AdminController : Controller
{
    
public
 ActionResult Setting()
    {
        
throw
 
new
 NotImplementedException();
    }
}

 

默认情况下,Action方法的方法名就是这个Action的Action名(Action名指的是Route中匹配Action方法的URL的那部分。例如url:Home/Index,其中Index就是Action名)。这里为什么要提到这个Action名呢?应为Action名是可以定义的,使用ActionNameAttribute来定义。请看下面的示例:

public
 ActionResult Setting()
{
    
throw
 
new
 NotImplementedException();
} 
[ActionName(
"
Setting
"
)]
public
 ActionResult SaveSetting()
{
    
throw
 
new
 NotImplementedException();
}

 

这两个Action方法的Action名都为"Setting",即对于url:Admin/Setting ,能同时匹配到这两个Action方法。如果一个URL同时匹配到两个Action方法的话,程序会抛出一个错误:

如果我们希望这两个Action的Action名都为Setting,Setting()就用于显示一个表单页面给用户,而SaveSetting()就用于保存用户提交过来的表单数据,我们该怎么做呢?我们可以利用AcceptVerbsAttribute来设置,这个Attribute用来定义Action方法会匹配指定的HttpMethod。例如下面的代码:

[AcceptVerbs(
"
GET
"
)]
public
 ActionResult Setting()
{
    
throw
 
new
 NotImplementedException();
} 
[ActionName(
"
Setting
"
), AcceptVerbs(
"
POST
"
)]
public
 ActionResult SaveSetting()
{
    
throw
 
new
 NotImplementedException();
}

 

这样,对于HttpMethod为"GET"的客户端请求,就会匹配到Setting()来显示一个表单给用户,如果用户POST回来的表单数据,则会匹配到SaveSetting()上面去,我们就可以处理用户POST过来的数据并保存到数据库。

在这里AcceptVerbsAttribute是继承自ActionSelectionAttribute的,我们也可以继承自ActionSelectionAttribute来自定义自己想要实现的功能。这个我们后面会详细讲解。如果你比较心急,可以看下这篇文章。

如果你想将一个public的方法设置为不是Action方法,那么你就要为该public的方法添加NonAction的Attribute:

Action方法的参数

例如我们要在AdminController中定义一个编辑日志的Action方法:

public
 ActionResult EditPost(
int
?
 id)
{
    
throw
 
new
 NotImplementedException();
}

 

对于URL:Admin/EditPost/2 ,上面的参数会自动被赋值为2。ASP.NET MVC在匹配Route的时候会根据Route的设置自动为Action方法的参数赋值。所以前面的id参数会被自动赋值为2的前提是,在Route配置的时候,必须指定了id参数,例如:

routes.MapRoute(
    
"
Default
"
,                                              
//
 Route 的名称
    
"
{controller}/{action}/{
id}
"
,                           
//
 带有参数的URL
    
new
 { controller 
=
 
"
Home
"
, action 
=
 
"
Index
"
, id 
=
 
""
  
//
 设置默认的参数
);

 

如果我们将Route修改为:

routes.MapRoute(
    
"
Default
"
,                                              
//
 Route 的名称
    
"
{controller}/{action}/{
para}
"
,                           
//
 带有参数的URL
    
new
 { controller 
=
 
"
Home
"
, action 
=
 
"
Index
"
, para 
=
 
""
  
//
 设置默认的参数
);

 

则前面的Action方法的参数必须修改为public ActionResult EditPost(int? para){ },使Action方法的参数和Route中定义的参数名相同,ASP.NET MVC才能自动为Action方法的参数赋值。

ActionResult

Action方法返回ActionResult类型的结果。ASP.NET MVC为我们提供了几种ActionResult的实现,如下:

  • ViewResult. 呈现视图页给客户端。由View 方法返回.

  • RedirectToRouteResult. 重定向到另外一个Route。由RedirectToAction RedirectToRoute 方法返回.

  • RedirectResult. 重定向到另外一个URL。由 Redirect 方法返回.

  • ContentResult. 返回普通的内容。例如一段字符串。由 Content 方法返回.

  • JsonResult. 返回JSON结果。由 Json 方法返回.

  • EmptyResult. 如果Action必须返回空值,可以返回这个结果。Controller中没有实现的方法,可以return new EmptyResult();.

当然我们也可以自定一个我们的ActionResult返回给客户端,例如一个RssResult。可以参考这篇文章。

通常情况下,我们的Controller可能有一些相同的情况,例如我们在各个Controller中都有可能会在出错或者什么时候想要显示一条提示信息给用户,或者有一些共同的数据要呈现的。这时候,我们最好就定义一个我们自己的Controller的基类:

public
 
class
 BaseController : Controller
{
    
public
 BaseController()
    {
 
    } 
    
protected
 ActionResult ShowMsg(List
<
string
>
 msgs)
    {
        
throw
 
new
 NotImplementedException();
    } 
    
public
 ActionResult Message()
    {
        
throw
 
new
 NotImplementedException();
    }
}

 

然后,其他的Controller都继承自这个BaseController :

public
 
class
 AdminController : BaseController
{
    [AcceptVerbs(
"
GET
"
)]
    
public
 ActionResult Setting()
    {
        
throw
 
new
 NotImplementedException();
    } 
    [ActionName(
"
Setting
"
), AcceptVerbs(
"
POST
"
)]
    
public
 ActionResult SaveSetting()
    {
        
throw
 
new
 NotImplementedException();
    } 
    
public
 ActionResult EditPost(
int
?
 id)
    {
        
throw
 
new
 NotImplementedException();
    }
}

转载于:https://www.cnblogs.com/yewei798/archive/2011/04/12/2013303.html

你可能感兴趣的文章
实现多行显示省略号和兼容的解决办法
查看>>
Leetcode: Insert Delete GetRandom O(1)
查看>>
docker 私有仓库之Harbor搭建与使用
查看>>
Android(Linux) 网卡名修改
查看>>
使用JavaScript给对象修改注册监听器
查看>>
最详细的Vue Hello World应用开发步骤
查看>>
优秀博客集合
查看>>
SQL Server 分页
查看>>
sql 入门经典(第五版) Ryan Stephens 学习笔记 第五部分: 性能调整
查看>>
jQuery tag标签插件
查看>>
OpenCV2:大学篇 形态学技术-腐蚀与膨胀操作
查看>>
【转】如何管理自己?
查看>>
练习1-10 编写一个将输入复制到输出的程序,并将其中的制表符替换成\t,把回退符替换成\b,把反斜杠替换成\\,这样可以将制表符和回退符以可见的方式显示出来...
查看>>
10 个Javascript框架和丰富的UI组件
查看>>
IE11浏览器中的My97日历控件刷新后无法打开问题解决办法
查看>>
会话保持:粘滞会话
查看>>
Git免密码提交
查看>>
Android手机外置SD卡(TF卡)的获取方法
查看>>
LeetCode 132. 分割回文串 II(Palindrome Partitioning II)
查看>>
关于PHP的引用赋值
查看>>