Asp.Net Core MVC 案例系列二

阻止控制器中方法被公开为Action方法

  在控制器类中,默认会将所有公共Action方法视为操作方法,但在某些特殊情况下,不希望被作为Action方法公开。就需要在方法上加上NonAction特性禁止公开,也就不能通过URL访问了。

重命名Action方法

  MVC框架默认指定Action方法名与成员方法名一致,但如果控制器类成员方法上应用了ActionName特性并指定了另一个名称,那就是重命名了,与Action方法相对应的视图文件也要使用指定的名称。

  • 本例中,Action名称GetItems重命名为get-items。
public class HomeController : Controller
{
[ActionName("get-items")]
public ActionResult GetItems()
{
return View();
}
}

使用布局页

  布局页可作为项目内各视图母版,用于排版被重复使用的内容。
  在布局页中,可在内容页出现位置用RenderBody方法来生成占位符,内容页HTML元素将会填满。
  在内容页中,通过Layout属性可以设置布局页名称。如果布局页位于可被查找位置,就不需要指定路径和扩展名,否则就要明确指定。
  一般在命名有特殊用途的视图文件时都会以下划线开头,所以布局页通常命名为_Layout.cshtml。

  在View目录下建Shared目录,Shared目录下添加布局页_Layout.cshtml。

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div style="height:100px; background-color:slateblue;position:relative">
<p style="color:white;font-size:40px;position:absolute;margin-left:15px">
清新小站
</p>
</div>
<div style="margin-top:35px;margin-bottom:45px">
@RenderBody()
</div>
<div>
<hr/>
© 2018 - 2018 版权所有
</div>
</body>
</html>

  在View目录下建Test目录,Test目录下添加布局页Default.cshtml。

@{
Layout = "_Layout";
}
<div>
网站主页
</div>

  添加控制器

public class TestController : Controller
{
public ActionResult Default()
{
return View();
}
}

_ViewStart视图与_ViewImports视图

  _ViewStart视图与_ViewImports视图不用于定义可视化内容,而是用于声明一些在视图中重复使用的指令。

  _ViewImports视图专门用于导入命名空间,SystemSystem.Threading.TasksMicrosoft.AspNetCore.Mvc等,这样不需要每个视图文件都写一遍using指令。

  _ViewStart视图用来放置各个视图中都可能重复使用的指令,例如引用页_Layout,后面就不用重复写了,在执行每个视图文件时都会先执行_ViewStart视图中的代码。

  _ViewStart_ViewImports并不要求放置到/View/Shared目录下,它们可以放到任何存有视图文件的目录下,只对当前目录及子目录下的视图起作用。

  定义Demo控制器,对应五个视图。

public class DemoController : Controller
{
public ActionResult Index() => View();
public ActionResult Desc() => View();
public ActionResult News() => View();
public ActionResult Products() => View();
public ActionResult ContactUs() => View();
}

  在View目录下建Shared子目录,并在Shared中存放_Layout。
  nav标签所定义的导航栏包括指向五个视图的链接,此处可使用 asp-controllerasp-action 两个标签帮助器使框架自动生成导航的URL。

@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<nav>
<a asp-controller="Demo" asp-action="Index">主页</a>
<a asp-controller="Demo" asp-action="Desc">公司简介</a>
<a asp-controller="Demo" asp-action="News">新闻</a>
<a asp-controller="Demo" asp-action="Products">产品信息</a>
<a asp-controller="Demo" asp-action="ContactUs">联系我们</a>
</nav>
<div>
@RenderBody()
</div>
</body>
</html>

  在View目录下建Demo子目录对应控制器,在建对应的五个视图(内容为此形式<h3>主页</h3>)。

  在Demo目录下添加 _ViewStart 视图文件,导入可能会被用到的命名空间。

@{
Layout = "_Layout";
}
@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers

  在Demo目录下添加 _ViewImports 视图文件,写入会被重复使用的代码。

@using System
@using Microsoft.AspNetCore.Mvc
@using Microsoft.AspNetCore.Mvc.TagHelpers

在控制器中接收服务列表的注入

  服务类型有时使用“接口-实现类”的方式来开发,因此一个服务接口可能有多个实现类。

services.AddScoped<ITestService, MD5CrtTest>();
services.AddScoped<ITestService, SHA256Test>();

  一种方法时以接口实现类依赖注入。

public DemoController(MD5CrtTest svs1, SHA256Test svs2)
{
_svs1 = svs1;
_svs2 = svs2;
}

  另一种方法是用IEnumerable<T>接口一同依赖注入。

public DemoController(IEnumerable<ITestService> svs)
{
_encoders = svs;
}

使用IFormCollection组件来提取form表单数据

  可以通过<form>元素收集用户输入的内容,提交服务器后转由指定控制器中的某个操作方法进行处理。操作方法通过参数来接收所提交的表单数据。

  操作方法将参数声明为IFormCollection类型,表单提交的会存放在IFormCollection实例中,其数据结构类型字典。

  定义Demo控制器。PostUp方法在客户端提交后从form参数提取数据存到字典中,再把字典传递给Show视图。

public class DemoController : Controller
{
public ActionResult Default() => View();
public ActionResult PostUp(IFormCollection form)
{
IDictionary<string, string> dic = new Dictionary<string, string>();
foreach(string k in form.Keys)
{
string v = form[k];
dic[k] = v;
}
return View("Show", dic);
}
}

  Default视图。

<html>
<body>
<table>
<tr>
<td><label for="city">城市:</label></td>
<td><input type="text" name="city" form="form"/></td>
</tr>
<tr>
<td> <label for="name">姓名:</label></td>
<td><input name="name" type="text" form="form"/></td>
</tr>
</table>
<form id="form" asp-controller="Demo" asp-action="PostUp">
<input type="submit" value="提交"/>
</form>
</body>
</html>

  Show视图显示内容。@model指令用于声明该视图接收的模型对象为字典类型,随后Model属性可获取字典的实例引用,并用foreach语句枚举出子项中Key与Value值。

@model IDictionary<string, string>
<html>
<body>
<h3>你输入的内容</h3>
@{
foreach(var i in Model)
{
<p>@i.Key : @i.Value</p>
}
}
</body>
</html>
posted @   一纸年华  阅读(21)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示

目录导航

阻止控制器中方法被公开为Action方法
重命名Action方法
使用布局页
_ViewStart视图与_ViewImports视图
在控制器中接收服务列表的注入
使用IFormCollection组件来提取form表单数据