ASP.NET Core:ASP.NET MVC Core 入门






4.46/5 (15投票s)
本文将引导您完成使用 ASP.NET Core 中的 MVC 创建一个简单 Web 应用程序的基本步骤。
引言
本文将引导您完成使用 ASP.NET Core 中的 MVC 创建一个简单 Web 应用程序的基本步骤。
背景
如果您偶然发现这篇文章,那么我假设您已经熟悉旧版 MVC 的工作原理。我不会在这里介绍 MVC 本身的细节,因此如果您是 ASP.NET MVC 的新手,那么您可能需要查看我下面的系列文章:
- 使用 Entity Framework 和 MVC 5 构建 Web 应用程序:第 1 部分
- 使用 Entity Framework 和 MVC 5 构建 Web 应用程序:第 2 部分
- 使用 Entity Framework 和 MVC 5 构建 Web 应用程序:第 3 部分
您还可以下载我的电子书:ASP.NET MVC 5:初学者指南
使用代码
在我们开始动手之前,让我们先谈谈 MVC。
ASP.NET Core 统一框架
图 1:ASP.NET Core
ASP.NET Core 将把 MVC、Web API 和可能还有 Web Pages 合并到一个名为 ASP.NET Core 1.0 的框架中,该框架以前名为 ASP.NET 5 MVC 6。
在以前的 ASP.NET MVC 版本中,MVC 控制器与 Web API 控制器不同。MVC 控制器使用 System.Web.MVC.Controller 基类,Web API 控制器使用 System.Web.Http.ApiController 基类。在 MVC Core 中,MVC 和 Web API 控制器只有一个 Controller 基类,即 Microsoft.AspNetCore.Mvc.Controller 类。
这种合并也适用于 MVC 和 Web Pages 中以前实现方式不同的 HTML 助手。Web Pages 编程模型尚未在当前版本中提供,因此我们无法真正判断他们还将合并哪些其他功能,但我们可以假设传统的 MVC 模型绑定将可用于它。
既然您已经了解了 ASP.NET Core 的全部内容以及它与以前版本的 ASP.NET MVC 的区别,我们现在可以继续深入研究了。请记住,对于这个特定的演示,我只介绍 MVC 的内容。
开始吧!
让我们启动 Visual Studio 2015 并选择 文件 > 新建 > 项目。在“新建项目”对话框中,选择 模板 > Visual C# > ASP.NET Core Web 应用程序。请参见下图以获得清晰的视图。
图 2:新建项目对话框
将您的项目命名为您喜欢的任何名称,然后单击“确定”。为了这个演示的简单性,我将项目命名为“MVCCoreDemo”。现在之后,您应该能够看到“新建 ASP.NET Core 项目”对话框。
图 3:项目模板
新的 ASP.NET Core 项目有三个默认模板:空、Web API 和 Web 应用程序。
这里的目标是从头开始构建一个 MVC Core 应用程序,因此从上面的对话框中选择 ASP.NET Core 空模板。然后单击“确定”,让 Visual Studio 为您生成所需的文件和模板。
您应该能够看到如下图所示的内容。
图 4:新建解决方案项目
如果您之前使用过 ASP.NET 的早期版本,那么您会注意到新项目结构完全不同。项目现在包含以下文件:
- src 文件夹:包含构成您的应用程序的所有包含源代码的项目。
- Program.cs:此文件包含 ASP.NET Core RC2 应用程序的 Main 方法,负责配置和运行应用程序。
- global.json:在此处放置解决方案级别的设置,并允许您进行项目到项目的引用。
- wwwroot:这是一个文件夹,所有静态文件都将放置在此处。这些是 Web 应用程序将直接提供给客户端的资源,包括 HTML、CSS、图像和 JavaScript 文件。
- project.json:包含项目设置。
- Startup.cs:这是您放置启动和配置代码的地方。
- References:它包含 .NETCoreApp 版本 1 运行时引用。
有关 ASP.NET Core 新功能的详细信息,请查看此文章:ASP.NET Core:城镇中的新 ASP.NET!
设置 MVC 文件夹结构
为了遵循 MVC 标准模式和关注点分离,让我们创建“Models”、“Views”和“Controllers”文件夹,如下图所示:
图 5:M V C 文件夹
介绍 project.json 文件
“project.json”文件充当新的项目文件(.csproj/.vbproj)。我们在此处放置应用程序所需的所有依赖项。
project.json 文件的优点是,当您添加或编辑依赖项时,它为可用包提供智能感知。您从此文件添加的所有包都将自动从 NuGet 中拉取。相应地,当您删除包时,它会自动将它们从项目引用中删除。这真是太棒了!
到目前为止,我们的应用程序中还没有 MVC,因为我们正在创建一个空的 ASP.NET Core 模板。要将 MVC 依赖项添加到我们的项目中,只需通过在依赖项部分下添加“Microsoft.AspNetCore.MVC”来修改 project.json 文件。我们还需要添加“Microsoft.AspNetCore.Diagnostics”,以便在遇到任何问题时可以对应用程序进行故障排除。您的 project.json 应该如下所示:
{
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0-rc2-3002702",
"type": "platform"
},
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Diagnostics": "1.0.0-rc2-final"
},
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": {
"version": "1.0.0-preview1-final",
"imports": "portable-net45+win8+dnxcore50"
}
},
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"dnxcore50",
"portable-net45+win8"
]
}
},
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"runtimeOptions": {
"gcServer": true
},
"publishOptions": {
"include": [
"wwwroot",
"web.config"
]
},
"scripts": {
"postpublish": [ "dotnet publish-iis
--publish-folder %publish:OutputPath%
--framework %publish:FullTargetFramework%" ]
}
}
截至本文撰写之时,MVC 1.0.0-rc2-final 是最新版本。现在保存 project.json 文件以恢复所需的 NuGet 包。MVC 框架现在应该已添加到我们的应用程序中,如下图所示:
图 6:恢复 NuGet 包
配置应用程序管道
由于我们已经添加了 MVC 依赖项,下一步是将 MVC 框架添加到管道中。因此,打开 Startup.cs 文件并在 Configure 方法下添加以下代码:
public void Configure(IApplicationBuilder app){
app.UseDeveloperExceptionPage();
app.UseMvc(m => {
m.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action="Index"});
});
}
上面的代码与旧版 MVC 定义路由的方式非常相似,只是我们现在使用 UseMvc 方法来设置路由。您可能还想查看 MVC Core 中的属性路由。
我们还没有完成。
将 MVC 添加到管道并不意味着我们现在就可以开始了。我们仍然需要通过添加 MVC Core 所需的依赖项来连接 MVC 的各个部分。因此,您的 ConfigureServices 方法现在应该如下所示:
public void ConfigureServices(IServiceCollection services){
services.AddMvc();
}
AddMvc() 是一个扩展方法,它为您完成所有魔术。它基本上添加了 MVC Core 所需的依赖项。
添加模型
现在让我们添加一个可以测试的简单模型。在此示例中,我将在“Models”文件夹下创建以下类:
namespace MVCCoreDemo.Models
{
public class DOTAHero
{
public int ID { get; set; }
public string Name { get; set; }
public string Type { get; set; }
}
}
然后添加了管理“DOTAHero”类的以下类:
using System.Collections.Generic;
using System.Linq;
namespace MVCCoreDemo.Models
{
public class HeroManager
{
readonly List<DOTAHero> _heroes = new List<DOTAHero>() {
new DOTAHero { ID = 1, Name = "Bristleback", Type="Strength"},
new DOTAHero { ID = 2, Name ="Abbadon", Type="Strength"},
new DOTAHero { ID = 3, Name ="Spectre", Type="Agility"},
new DOTAHero { ID = 4, Name ="Juggernaut", Type="Agility"},
new DOTAHero { ID = 5, Name ="Lion", Type="Intelligence"},
new DOTAHero { ID = 6, Name ="Zues", Type="Intelligence"},
new DOTAHero { ID = 7, Name ="Trent", Type="Strength"},
new DOTAHero { ID = 8, Name ="Axe", Type="Strength"},
new DOTAHero { ID = 9, Name ="Bounty Hunter", Type="Agility"},
new DOTAHero { ID = 10, Name ="Chaos Knight", Type="Strength"}
};
public IEnumerable<DOTAHero> GetAll { get { return _heroes; } }
public List<DOTAHero> GetHeroesByType(string type)
{
return _heroes.Where(o => o.Type.ToLower().Equals(type.ToLower())).ToList();
}
}
}
“HeroManager”类包含一个只读属性,其中包含一个英雄列表。为了简单起见,数据显然是静态的。在实际场景中,您可能需要从存储介质(例如数据库或存储数据的任何文件)中获取数据。它还包含一个 GetAll 属性,该属性返回所有英雄,最后是一个 GetHeroesByType() 方法,该方法根据英雄类型返回英雄列表。
添加控制器
添加控制器与在旧版 MVC 中添加控制器大致相同。只需右键单击“Controllers”文件夹,然后选择“添加”>“新建项”。在对话框中选择“MVC 控制器类”,如下图所示:
图 7:添加控制器
然后继续单击“添加”为您生成控制器类。这是 HomeController 类:
using Microsoft.AspNetCore.Mvc;
using MVCCoreDemo.Models;
namespace MVCCoreDemo.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
HeroManager HM = new HeroManager();
var heroes = HM.GetAll;
return View(heroes);
}
}
}
上面的代码并没有什么特别之处。它只是一个控制器,其中包含一个 IActionResult() 方法,该方法返回来自模型的英雄列表。
添加视图
右键单击控制器的操作名称不会弹出“添加新项”对话框。因此,要添加视图,只需执行与添加控制器相同的操作。但在此之前,我们必须在“Views”文件夹下添加一个“Home”文件夹,以遵循 MVC 约定。右键单击“Home”文件夹并选择“添加”>“新建项”>“MVC 视图页面”
图 8:添加视图
单击添加以生成文件。现在,创建我们的视图没有什么神奇之处,因为我们没有使用任何 scaffolding 模板。相反,我们需要手动设置视图。我的视图如下所示:
@model IEnumerable<MVCCoreDemo.Models.DOTAHero>
<h3>My Favorite DOTA 2 Heroes</h3>
<ul>
@foreach (var p in Model)
{
<li>@($"{p.Name} {p.Type}")</li>
}
</ul>
上面的视图是一个强类型视图。通过在视图模板文件的顶部包含 @model 语句,您可以指定视图期望的对象类型。在这种情况下,它使用 IEnumerable<MVCCoreDemo.Models.DOTAHero>。
输出
以下是在浏览器中运行应用程序时的简单输出。
图 9:输出
就是这样!现在让我们看看 MVC Core 中的其他一些新酷功能。
引入 Inject
ASP.NET MVC Core 有一些我们可以用于应用程序的新指令。在这里,我们将了解如何使用 @inject。@inject 指令允许您将类或服务中的一些方法调用直接注入到您的视图中。为了看到它的实际效果,我在 Models 文件夹下创建了一个名为“HeroStats”的新类。这是一个公开一些异步方法的简单类:
using System.Linq;
using System.Threading.Tasks;
namespace MVCCoreDemo.Models
{
public class HeroStats
{
private HeroManager _manager = new HeroManager();
public async Task<int> GetHeroCount()
{
return await Task.FromResult(_manager.GetAll.Count());
}
public async Task<int> GetHeroCountByType(string type)
{
return await Task.FromResult(_manager.GetHeroesByType(type).Count);
}
}
}
上面的类初始化 HeroManager 对象的新实例。它还包含两个主要的异步方法。GetHeroCount() 返回英雄的总数,GetHeroCountByType() 根据给定类型返回英雄的数量。非常简单,该类中没有太多内容。以下是如何将类注入到视图中:
@model IEnumerable<MVCCoreDemo.Models.DOTAHero>
@inject MVCCoreDemo.Models.HeroStats Stats
<h3>My Favorite DOTA 2 Heroes</h3>
<ul>
@foreach (var p in Model)
{
<li>@($"{p.Name} {p.Type}")</li>
}
</ul>
<div>
<h4>Stats</h4>
<p>Number of Strength Heroes: @await Stats.GetHeroCountByType("strength")</p>
<p>Number of Agility Heroes: @await Stats.GetHeroCountByType("agility")</p>
<p>Number of Intelligence Heroes: @await Stats.GetHeroCountByType("intelligence")</p>
<p>Total Heroes Heroes: @await Stats.GetHeroCount()</p>
</div>
现在为了使其工作,我们需要通过将 HeroStats 模型添加到 AddTransient() 方法来配置它。因此,Configure 方法现在应该如下所示:
public void ConfigureServices(IServiceCollection services){
services.AddMvc();
services.AddTransient<MVCCoreDemo.Models.HeroStats>();
}
运行应用程序将显示以下输出:
图 10:输出
介绍视图组件
MVC Core 的另一个酷功能是“视图组件”。如果您还记得,在以前的 ASP.NET MVC 版本中,Html.Action() 助手通常用于调用子控制器。子控制器可能会显示标签云、动态链接、侧边栏或任何其他内容。ASP.NET MVC Core 引入了新的视图组件来替换使用 Html.Action() 的小部件。
视图组件还支持完全异步,允许您使视图组件异步。
现在让我们尝试创建一个非常简单的视图组件,看看它们在 MVC 中是如何使用的。首先,在应用程序的根目录中创建一个新文件夹并将其命名为“ViewComponents”。在该文件夹中创建一个新类并将其命名为“HeroListViewComponent”,然后复制以下代码:
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MVCCoreDemo.Models;
namespace MVCCoreDemo.ViewComponents
{
public class HeroListViewComponent: ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(string type){
var heroes = await GetHeroesAsync(type);
return View(heroes);
}
private Task<IEnumerable<DOTAHero>> GetHeroesAsync(string type){
return Task.FromResult(GetHeroes(type));
}
private IEnumerable<DOTAHero> GetHeroes(string type){
HeroManager HM = new HeroManager();
return HM.GetHeroesByType(type);
}
}
}
与控制器一样,视图组件也遵循类命名约定。这意味着您可以通过在类中添加后缀“ViewComponent”来创建视图组件。此外,VC 必须是公共的、非嵌套的和非抽象的类。
注释
您还可以在引用 ViewComponent 时在类中使用 [ViewComponent] 属性。
您可以使用 View() 的重载方法来指定要从 InvokeAsync 方法渲染的视图。例如,return View(“YourViewName”,model)。
InvokeAsync 公开了一个可以从视图调用的方法,并且它可以接受任意数量的参数。正如您从上面的代码中看到的,我们在方法中传递了参数“type”来过滤数据。
现在,让我们为刚刚创建的视图组件添加视图。请记住,VC 在引用视图时也遵循约定。因此,首先要做的是在 Home 文件夹中创建一个新文件夹。文件夹名称必须是“Components”。由于我们需要遵循约定,下一步是在 Components 文件夹中创建另一个新文件夹,这次文件夹名称必须与您的类名匹配,减去“ViewComponents”后缀。在这种情况下,将文件夹命名为“HeroList”。最后,在 HeroList 文件夹中添加一个新视图并将其命名为“Default”,因为我们没有在 InvokeAsync 代码中指定要渲染的视图。您的项目结构现在应该如下所示:
图 11:解决方案资源管理器
现在,在您的 Default.cshtml 文件中,为您的视图组件的视图添加以下标记:
@model IEnumerable<MVCCoreDemo.Models.DOTAHero>
<h3>@Model.First().Type Heroes</h3>
<ul>
@foreach (var p in Model)
{
<li>@p.Name</li>
}
</ul>
以下是我们从主视图 (Index.cshmtl) 调用视图组件的方式:
<div>
@await Component.InvokeAsync("HeroList", new { type = "agility" })
</div>
运行页面将产生以下输出:
图 12:最终输出
就是这么简单!希望您觉得这篇文章有用。敬请期待更多精彩内容!:)
摘要
在本文中,我们学习了如何从头开始创建一个简单的 MVC Core 应用程序。我们还探索了 MVC Core 的一些酷功能。