65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.46/5 (15投票s)

2016 年 6 月 6 日

CPOL

10分钟阅读

viewsIcon

90794

downloadIcon

1723

本文将引导您完成使用 ASP.NET Core 中的 MVC 创建一个简单 Web 应用程序的基本步骤。

引言

本文将引导您完成使用 ASP.NET Core 中的 MVC 创建一个简单 Web 应用程序的基本步骤。

背景

如果您偶然发现这篇文章,那么我假设您已经熟悉旧版 MVC 的工作原理。我不会在这里介绍 MVC 本身的细节,因此如果您是 ASP.NET MVC 的新手,那么您可能需要查看我下面的系列文章:

您还可以下载我的电子书: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 的一些酷功能。

© . All rights reserved.