public IActionResult NameofAction(){return View();}
IActionResult VS ActionResult - IActionResult 是一个接口 ,ActionResult是一个抽象类继承自IActionResult接口,在WebAPI中你将使用ActionResult返回客户端响应.
1 Action将Model传递给View
Action方法通常做一些特定的工作像数据库操作,数学计算等,最后将工作的结果输出给用户,因此工作结果返回到终端View,以至于能在UI上显示
一个Action方法能返回2种类型的Models到View:
1.1 Action方法返回String类型
using AspNetCore.Action.Models;using Microsoft.AspNetCore.Mvc;namespace AspNetCore.Action.Controllers{public class EmployeeController : Controller{public IActionResult Index(){return View();}[HttpPost]public IActionResult Index(int id, string name){string welcomeMessage = $"Welcome Employee: {name} with id: {id}";return View((object)welcomeMessage);}}}
Action方法返回IActionResult类型,调用View()方法返回一个字符串到View,注意我们如果将string类型传递到View,需要将它转换成object类型- View((object)string)
在Views->Employee文件夹下添加Index.cshtml视图,Index试图的代码如下
@model string;<h2>填充并且提交表单</h2>@{if (Model != null){<h3 class="p-3 mb-2 bg-success text-white">@Model</h3>}}<form class="form-horizontal" method="post"><div class="mb-3 row"><label class="col-sm-1 control-label">编号</label><div class="col-sm-11"><input class="form-control" name="id" /></div></div><div class="mb-3 row"><label class="col-sm-1 control-label">姓名</label><div class="col-sm-11"><input class="form-control" name="name" /></div></div><div class="mb-3 row"><div class="col-sm-11 offset-sm-1"><button type="submit" class="btn btn-primary">提交</button></div></div></form>
这里有几个值得注意的点:

通过这种方式,我们可以从action方法到视图传输另外一些数据类型像int,float等
namespace AspNetCore.Action.Models{public class Employee{public int Id { get; set; }public string Name { get; set; }public int Salary { get; set; }public string Designation { get; set; }public string Address { get; set; }}}
现在将类返回给视图,在EmployeeController中添加一个新的action方法Detail
[HttpGet]public IActionResult Detail(){return View();}[HttpPost]public IActionResult Detail(int id, string name){var employee=new Employee();employee.Id = id;employee.Name = name;employee.Salary = 1000;employee.Designation = "Manager";employee.Address = "New York";return View(employee);}
HttpGet 版本的 Detail方法不会向视图返回任何内容,HttpPost版本的Detail方法中给客户返回一个Employee对象,最后我们将该对象返回给视图
接下来在Views->Employee文件夹中创建Detail.cshtml的Razor视图
注意这次我们在视图的顶端定义了一个Employee类型-@model Employee
@model Employee;<h2>填充并且提交表单</h2>@{if (Model != null){<h3 class="p-3 mb-2 bg-success text-white">员工详细信息:@Model.Id,@Model.Name,@Model.Salary,@Model.Designation,@Model.Address</h3>}}<form class="form-horizontal" method="post"><div class="mb-3 row"><label class="col-sm-1 control-label">编号</label><div class="col-sm-11"><input class="form-control" name="id" /></div></div><div class="mb-3 row"><label class="col-sm-1 control-label">姓名</label><div class="col-sm-11"><input class="form-control" name="name" /></div></div><div class="mb-3 row"><div class="col-sm-11 offset-sm-1"><button type="submit" class="btn btn-primary">提交</button></div></div></form>

| 方法 | 描述 | 
| View() | 使用默认视图来渲染,例如:如果一个action方法是List并且你使用了没有参数View()方法,List.cshtml视图被呈现 | 
| View("name_of_view") | 这个版本在参数中传递一个视图名称并且呈现该视图,例如如果你使用View("Show"),然而你Show.cshtml视图将被呈现 | 
| View(model) | 这个版本给默认视图提提供model数据,这个通常被使用在View中呈现强类型 | 
| View("name_of_view",model) | 指定一个视图的名称并且给指定的视图提供model数据 | 
3 将数据从Action传递到View
我们可以使用Model传递任何类型的数据从action方法到view, 前面有例子,如果你不想使用这个方式传递数据,我们还可以使用下面几种方式将数据传输到View,我们这里介绍另外三种方式从Action方法传递数据到View
1 ViewBag
2 TempData
3 Session Variable
using Microsoft.AspNetCore.Mvc;namespace AspNetCore.Action.Controllers{public class ExampleController : Controller{public IActionResult Index(){return View();}public IActionResult ViewBagExample(){ViewBag.CurrentDateTime = DateTime.Now;ViewBag.CurrentYear = DateTime.Now.Year;return View();}}}
我们需要注意如下几点:
public IActionResult TempDataExample(){TempData["CurrentDateTime"] = DateTime.Now;TempData["CurrentYear"] = DateTime.Now.Year;return RedirectToAction("TempDataShow");}public IActionResult TempDataShow(){return View();}
TempDataExample方法给TempData添加当前时间和当年年份
1 CurrentDateTime
2 CurrentYear
<h2>Current DateTime & Year: @TempData["CurrentDateTime"] and @TempData["CurrentYear"]</h2>
ViewBag,ViewData和TempData之间有什么不同呢?ViewBag是一个动态对象,ViewData和TempData是一个字典类型,存储字典类型的值,ViewBag在发生跳转时值会丢失因此在这种情况下我们可以使用TempData
首先你需要启用Session在ASP.NET Core 应用程序中添加下面3行代码在Program.cs类中

public IActionResult SessionExample(){HttpContext.Session.SetString("CurrentDateTime", DateTime.Now.ToString());HttpContext.Session.SetInt32("CurrentYear", DateTime.Now.Year);return View();}
在Views->Example文件夹下创建一个新的视图文件SessionExample.cshtml,在视图中添加如下代码:
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor<h2>Current DateTime & Year:@HttpContextAccessor.HttpContext.Session.GetString("CurrentDateTime"),@HttpContextAccessor.HttpContext.Session.GetInt32("CurrentYear")</h2>
@HttpContextAccessor.HttpContext.Session.GetString("CurrentDateTime"),@HttpContextAccessor.HttpContext.Session.GetInt32("CurrentYear")
在Session中可以存储复杂类型的变量,例如类,你必须把类序列化成JSON,然后获取该值是再反序列化,我们添加一个新的类:
using System.Text.Json;namespace AspNetCore.Action.Models{public static class SessionExtensions{public static void Set<T>(this ISession session, string key, T value){session.SetString(key, JsonSerializer.Serialize(value));}public static T? Get<T>(this ISession session, string key){var value = session.GetString(key);return value == null ? default : JsonSerializer.Deserialize<T>(value);}}}
HttpContext.Session.Set<Employee>("Employee", new Employee{Name = "KK",Address= "Tokyo"});
@{var employee = HttpContextAccessor.HttpContext.Session.Get<Employee>("Employee");<p>@employee.Name, @employee.Address</p>}
我们可以在services.AddSession()方法中设置cookie的名字和过期时间,具体代码如下:
builder.Services.AddSession(sessionOption =>{sessionOption.Cookie.Name = ".myapp";sessionOption.IdleTimeout= TimeSpan.FromSeconds(10);});
4 Action方法的调转方式
ASP.NET Core指定了很多跳转方法,从相同的Controller不同的action方法的跳转以及不同Controller不同action方法的跳转,这些方法定义如下:
1 Redirect
2 RedirectPermanent
3 RedirectToRoute
4 RedirectToRoutePermanent
5 RedirectToAction
6 RedirectToActionPermanent
Redirect方法指定一个临时跳转(HTTP 302), 它使用跳转的url作为字符串参并且返回一个RedirectResult类
public RedirectResult RedirectAction(){return Redirect("/List/Search");}
该方法和Redirect方法类似,它执行一个永久调转(HTTP 301)
public RedirectResult RedirectPermanentAction(){return RedirectPermanent("/List/Search");}
如果你想使用基于应用程序路由的调转你可以使用RedirectToRoute()方法,它执行一个临时调转并且使用匿名类型作为参数,匿名类型的参数传递到路由系统来生成url
RedirectToRoute()方法返回RedirectToRouteResult,我们使用它来执行跳转
public RedirectToRouteResult Redirect(){return RedirectToRoute(new { controller = "Admin", action = "Users", ID = 10 });}
RedirectToRoutePermanent
RedirectToRoutePermanent和RedirectToRoute类似,它执行的是一个永久调转
public RedirectToRouteResult RedirectPermanent(){return RedirectToRoutePermanent(new { controller = "Admin", action = "Users", ID = 10 });}
RedirectToAction
RedirectToAction方法指定临时调转到给与的action方法,这个方法返回一个RedirectToActionResult的一个实例
我们修改一下HomeController控制器的Index方法
public IActionResult Index(){return RedirectToAction("Privacy");}
如何调用相同控制器下的action?使用RedirectToAction方法单个参数的重载,这个参数提供了相同控制器下的action方法的名称
如果你使用的RedirectToAction方法的单个参数,ASP.NET Core假设你指定的action方法在当前控制器中,因此调转到不同控制器的action方法你需要指定两个参数,在下面代码中,我们调转到Customer控制器的List方法
public RedirectToActionResult Index(){return RedirectToAction("Customer", "List");}
这种情况下调转的url是/Customer/List
注意:使用RedirectToAction方法时你不能传递Mode,但是你可以使用TempData或者Session变量
public IActionResult Index(){//return RedirectToAction("Privacy");return RedirectToActionPermanent("Privacy");}
5 Action方法返回不同类型的Content
截止到现在我们已经看到Action方法返回string和View,实际上Actions方法还可以返回JSON和HTTP状态码
public JsonResult ReturnJson(){return Json(new[] { "Brahma", "Vishnu", "Mahesh" });}
在Views->Example文件夹下创建一个ReturnJson.cshtml的视图并显示JSON文件
运行应用程序并测试

StatusCode()位于Microsoft.AspNetCore.Http命名空间,使用它可以返回任何类型的状态码,该方法返回类型StatusCodeResult类位于Microsoft.AspNetCore.Mvc命名空间
public StatusCodeResult ReturnBadRequest(){return StatusCode(StatusCodes.Status400BadRequest);}
例子:返回Unauthorized-401 Status Code
public StatusCodeResult ReturnUnauthorized(){return StatusCode(StatusCodes.Status401Unauthorized);}
public StatusCodeResult ReturnNotFound(){return StatusCode(StatusCodes.Status404NotFound);}
总结
这节我们主要讲解了Action方法以及Action和View之间的关联
源代码地址
https://github.com/bingbing-gui/Asp.Net-Core-Skill/tree/master/Fundamentals/AspNetCore.Action/AspNetCore.Action
