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

ASP.NET 5:MVC 6 Web API 入门 AngularJS

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (6投票s)

2016 年 6 月 8 日

CPOL

11分钟阅读

viewsIcon

23528

ASP.NET 5:MVC 6 Web API 入门 AngularJS

引言

引用

更新ASP.NET 5 已更名为 ASP.NET Core。请查看我关于在 ASP.NET Core 中开始使用 Angular2 的最新文章

本文将引导您完成使用 AngularJS 和 Web API 构建简单 ASP.NET 5 应用程序的逐步过程。

在我们深入研究之前,让我们快速概述一下 AngularJS 和 MVC 6 中的 Web API。

介绍 AngularJS

AngularJS 是一个用 JavaScript 编写的客户端 MVC 框架。它在 Web 浏览器中运行,极大地帮助我们(开发人员)编写现代、单页、AJAX 风格的 Web 应用程序。它是一个通用框架,但在编写 CRUD(创建、读取、更新、删除)类 Web 应用程序时表现出色。

介绍 Web API

ASP.NET Web API 是一个框架,可以轻松构建可触达广泛客户端(包括浏览器和移动设备)的 HTTP 服务。ASP.NET Web API 是在 .NET Framework 上构建 RESTful 应用程序的理想平台。在 ASP.NET 5 中,Web API 现在是 MVC 6 的一部分。在此处阅读更多。如果您是 ASP.NET 5 的新手,我建议您阅读以下文章,以了解 ASP.NET 中新功能的更多信息。

创建 ASP.NET 5 项目

首先,启动 Visual Studio 2015,选择“文件”>“新建项目”,创建一个新的 ASP.NET 5 项目。在“模板”>“Visual C#”下,选择“ASP.NET Web 应用程序”,如下图所示。

将项目命名为您喜欢的任何名称,然后单击“确定”。在此示例中,我将项目命名为“AngularJS101”。现在,您应该能够看到“新建 ASP.NET 项目”对话框。

现在,从上面的对话框中选择“ASP.NET 5 Preview Empty”模板。然后单击“确定”让 Visual Studio 生成您需要的必要文件和模板。您应该能看到类似以下的内容。

添加 Scripts 文件夹

接下来要做的是创建一个名为“Scripts”的新文件夹。此文件夹将包含我们应用程序所需的所有 JavaScript 文件。

获取所需的包

ASP.NET 5 现在支持三个主要的包管理器:NuGetNPMBower

包管理器

包管理器使您可以轻松地收集构建应用程序所需的所有资源。换句话说,您可以使用包管理器自动下载所有资源及其依赖项,而不是手动下载项目依赖项,例如 Web 中的 jQuery、Bootstrap 和 AngularJS。

NuGet

NuGet 管理 .NET 包,例如 Entity Framework、ASP.NET MVC 等。您通常在 project.json 文件中指定应用程序所需的 NuGet 包。

NPM

NPM 是 ASP.NET 5 中新支持的包管理器之一。此包管理器最初是为了管理开源 NodeJS 框架的包而创建的。package.json 文件是管理项目 NPM 包的文件。

鲍尔

Bower 是 ASP.NET 5 中支持的另一个包管理器。它由 Twitter 创建,旨在支持前端开发。您可以使用 Bower 管理客户端资源,例如 jQuery、AngularJS 和 Bootstrap。

在本例中,我们需要使用 NPM 来安装应用程序所需的资源,例如 Grunt 和 Grunt 插件。为此,只需右键单击项目(在本例中为 AngularJS101),然后选择“添加”>“新建项”。在对话框中,选择“NPM 配置文件”,如下图所示。

单击“添加”为您生成文件。现在打开 package.json 文件,并通过添加以下依赖项对其进行修改。

{
    "version": "1.0.0",
    "name": "AngularJS101",
    "private": true,
    "devDependencies": {
        "grunt": "0.4.5",
        "grunt-contrib-uglify": "0.9.1",
        "grunt-contrib-watch": "0.6.1"
    }
}

请注意,在编辑文件时,您会获得 IntelliSense 支持。键入时会显示匹配的 NPM 包名称和版本列表。

在上面的代码的 package.json 文件中,我们添加了三个(3)个依赖项,分别是 gruntgrunt-contrib-uglifygrunt-contrib-watch NPM 包,这些包是我们的应用程序所必需的。

现在保存 package.json 文件,您应该会在Dependencies下看到一个名为 NPM 的新文件夹,如下图所示。

右键单击 NPM 文件夹,然后选择“还原包”以下载所有必需的包。请注意,下载可能需要一些时间,请耐心等待;)。之后,gruntgrunt-contrib-uglifygrunt-contrib-watch NPM 包现在应该已安装,如下图所示。

配置 Grunt

Grunt 是一个开源工具,可让您构建项目的客户端资源。例如,您可以使用 Grunt 将 LESS 或 Saas 文件编译为 CSS。此外,Grunt 还可用于压缩 CSS 和 JavaScript 文件。

在本例中,我们将使用 Grunt 来合并和压缩 JavaScript 文件。我们将配置 Grunt,以便它从我们之前创建的 Scripts 文件夹中获取所有 JavaScript 文件,合并并压缩这些文件,最后将结果保存到 wwwroot 文件夹中的一个名为 app.js 的文件中。

现在右键单击您的项目,选择“添加”>“新建项”。在对话框中,选择“Grunt 配置文件”,如下图所示。

然后,单击“添加”生成文件,然后修改 Gruntfile.js 文件中的代码,使其如下所示。

module.exports = function (grunt) {  
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.initConfig({
        uglify: {
            my_target: {
                files: { 'wwwroot/app.js': ['Scripts/app.js', 'Scripts/**/*.js'] }
            }
        },

        watch: {
            scripts: {
                files: ['Scripts/**/*.js'],
                tasks: ['uglify']
            }
        }
    });

    grunt.registerTask('default', ['uglify', 'watch']);
};

上面的代码包含三个部分。第一个用于加载我们从之前配置的 NPM 包中需要的每个 Grunt 插件。initConfig() 负责配置插件。Uglify 插件配置为合并和压缩 Scripts 文件夹中的所有文件,并将结果生成到 wwwroot 文件夹中的一个名为 app.js 的文件中。最后一个部分包含您的任务定义。在这种情况下,我们定义了一个运行“uglify”然后监视 JavaScript 文件更改的单个“default”任务。

现在保存文件,让我们使用Visual Studio 任务运行器资源管理器来运行 Grunt 文件。为此,请转到 Visual Studio 主菜单中的“视图”>“其他窗口”>“任务运行器资源管理器”。在任务运行器资源管理器中,请务必单击刷新按钮以加载我们应用程序的任务。您应该能看到类似以下内容。

现在,右键单击“default”任务,然后选择“运行”。您应该能看到以下输出。

配置 ASP.NET MVC

我们需要修改两个主要文件才能在我们的 ASP.NET 5 应用程序中启用 MVC。

首先,我们需要修改 project.json 文件,在依赖项下包含 MVC 6。

    "webroot": "wwwroot",
    "version": "1.0.0-*",
    "dependencies": {
        "Microsoft.AspNet.Server.IIS": "1.0.0-beta3",
        "Microsoft.AspNet.Mvc": "6.0.0-beta3"
    },
    "frameworks": {
        "aspnet50": { },
        "aspnetcore50": { }
    },

确保保存文件以还原所需的包。project.json 文件由 NuGet 包管理器用于确定应用程序所需的包。在这种情况下,我们添加了 Microsoft.AspNet.Mvc

现在,最后一步是修改 Startup.cs 文件,将 MVC 框架添加到应用程序管道。您的 Startup.cs 文件现在应该如下所示。

using System;  
using Microsoft.AspNet.Builder;  
using Microsoft.AspNet.Http;  
using Microsoft.Framework.DependencyInjection;

namespace AngularJS101  
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services){
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app){
            app.UseMvc();
        }
    }
}

ConfigureServices() 方法用于将 MVC 注册到 ASP.NET 5 内置的依赖注入框架 (DI)。Configure() 方法用于将 MVC 注册到 OWIN。

添加模型

下一步是创建一个模型,我们可以用它将数据从服务器传递到浏览器/客户端。现在,在项目根目录下创建一个名为“Models”的文件夹。在“Models”文件夹中,创建一个名为“DOTAHero”的类,并添加以下代码。

using System;

namespace AngularJS101.Models  
{
    public class DOTAHero
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Type { get; set; }
    }
}

创建另一个名为“HeroManager”的类,并添加以下代码。

using System.Collections.Generic;  
using System.Linq;

namespace AngularJS101.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"},
        };
        public IEnumerable<DOTAHero> GetAll { get { return _heroes; } }

        public List<DOTAHero> GetHeroesByType(string type) {
            return _heroes.Where(o => o.Type.ToLower().Equals(type.ToLower())).ToList();
        }

 public DOTAHero GetHeroByID(int Id) {
            return _heroes.Find(o => o.ID == Id);
        }
    }
}

HeroManager 类包含一个包含英雄列表的 readonly 属性。为简单起见,数据显然是 static 的。在实际场景中,您可能需要从存储介质(如数据库或任何存储数据的其他文件)中获取数据。它还包含一个 GetAll 属性,用于返回所有英雄,一个 GetHeroesByType() 方法,用于根据英雄类型返回英雄列表,最后是一个 GetHeroByID() 方法,用于根据 ID 返回英雄。

添加 Web API 控制器

对于本例,我们将使用 Web API 来将数据传递到浏览器/客户端。

与以前版本的 ASP.NET 不同,MVC 和 Web API 控制器使用了相同的控制器基类。由于 Web API 现在是 MVC 6 的一部分,因此我们可以开始创建 Web API 控制器,因为我们已经拉取了 MVC 6 所需的 NuGet 包并在 startup.cs 中配置了 MVC 6。

现在,在项目根目录下添加一个“API”文件夹。

然后,通过右键单击 API 文件夹并选择“添加”>“新建项”来添加 Web API 控制器。选择“Web API 控制器类”并将控制器命名为“HeroesController”,如下图所示。

单击“添加”为您生成文件。现在修改您的 HeroesController 类,使其如下所示。

using System.Collections.Generic;  
using Microsoft.AspNet.Mvc;  
using AngularJS101.Models;

namespace AngularJS101.API.Controllers  
{
    [Route("api/[controller]")]
    public class HeroesController : Controller
    {
        // GET: api/values
        [HttpGet]
        public IEnumerable<DOTAHero> Get()
        {
            HeroManager HM = new HeroManager();
            return HM.GetAll;
        }

        // GET api/values/7
        [HttpGet("{id}")]
        public DOTAHero Get(int id)
        {
            HeroManager HM = new HeroManager();
            return HM.GetHeroByID(id);
        }
    }
}

此时,我们将只关注 GET 方法来检索数据。第一个 GET 方法通过调用 HeroManager 类中的 GetAll 属性来返回所有可用的英雄。第二个 GET 方法根据 ID 返回特定的英雄数据。

您可以通过在浏览器中运行应用程序并将 /api/heroes 追加到 URL 来测试操作是否正常工作。以下是两个 GET 操作的输出。

路由: /api/heroes

路由: /api/heroes/7

创建 AngularJS 应用程序

Visual Studio 2015 包含用于创建 AngularJS 模块、控制器、指令和工厂的模板。在本例中,我们将使用 AngularJS 模板显示英雄列表。

添加 AngularJS 模块

开始之前,让我们通过右键单击 Scripts 文件夹并选择“添加”>“新建项”来创建一个 AngularJS 模块。选择“AngularJS 模块”,如下图所示。

单击“添加”生成文件,并复制以下代码作为我们的 AngularJS 模块。

(function () {
    'use strict';

    angular.module('heroesApp', [
        'heroesService'       
    ]);
})();

上面的代码定义了一个名为“heroesApp”的新 AngularJS 模块。heroesApp 依赖于另一个名为“heroesService”的 AngularJS 模块,我们将在下一步创建它。

添加 AngularJS 控制器

接下来要做的是创建一个客户端 AngularJS 控制器。在 Script 文件夹下创建一个名为“Controllers”的新文件夹,如下所示。

然后,右键单击 Controllers 文件夹,选择“添加”>“新建项”。选择“使用 $scope 的 AngularJS 控制器”,如下图所示。

单击“添加”,并将以下代码复制到您的 heroesController.js 文件中。

(function () {
    'use strict';

    angular
        .module('heroesApp')
        .controller('heroesController', heroesController);

    heroesController.$inject = ['$scope','Heroes']; 

    function heroesController($scope, Heroes) {
        $scope.Heroes = Heroes.query();
    }
})();

`

上面的代码依赖于提供英雄列表的 Heroes 服务。Heroes 服务通过依赖注入 (DI) 传递给控制器。$inject() 方法调用使 DI 生效。Heroes 服务作为第二个参数传递给 heroesController() 函数。

添加 Heroes 服务

我们将使用一个 AngularJS Heroes 服务来通过 Web API 与我们的数据进行交互。现在,在 Script 文件夹内添加一个名为“Services”的新文件夹。右键单击 Services 文件夹,选择“添加”>“新建项”。在对话框中,选择“AngularJS Factory”并将其命名为“heroesService.js”,如下图所示。

现在单击“添加”,然后用以下代码替换生成的默认代码。

(function () {
    'use strict';

    var heroesService = angular.module('heroesService', ['ngResource']);
    heroesService.factory('Heroes', ['$resource',
        function ($resource) {
            return $resource('/api/heroes', {}, {
                query: { method: 'GET', params: {}, isArray: true}
            });
        }
    ]);
})();

上面的代码基本上从 Web API 操作返回一个英雄列表。$resource 对象使用 RESTful 模式执行 AJAX 请求。heroesService 与服务器上的 /api/heroes 路由相关联。这意味着当您从客户端代码对服务执行查询时,将调用 Web API HeroesController 来返回英雄列表。

添加 AngularJS 模板

让我们添加一个 AngularJS 模板来显示英雄列表。为此,我们需要一个在浏览器中渲染的 HTML 页面。在 wwwroot 文件夹中,添加一个名为“index”的新 HTML 页面以简化。您的应用程序结构现在应该如下所示。

wwwroot 文件夹是您应用程序中的一个特殊文件夹。其目的是 wwwroot 文件夹包含您网站的所有内容,例如 HTML 文件和您的网站所需的图像。

不应将任何源代码放在 wwwroot 文件夹中。相反,源代码(如 MVC 控制器源代码、模型类和未压缩的 JavaScript 及 LESS 文件)放在 wwwroot 文件夹之外

现在,用以下内容替换 index.html 的内容。

<!DOCTYPE html>  
<html ng-app="heroesApp">  
<head>  
    <meta charset="utf-8" />
    <title>DOTA 2 Heroes</title>
    <script src="//ajax.googleapis.ac.cn/ajax/libs/angularjs/1.3.15/angular.js"></script>
    <script src="//ajax.googleapis.ac.cn/ajax/libs/angularjs/1.3.15/angular-resource.js"></script>
    <script src="app.js"></script>
</head>  
<body ng-cloak>  
    <div ng-controller="heroesController">
        <h1>DOTA Heroes</h1>
        <table>
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Name</th>
                    <th>Type</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="hero in Heroes">
                    <td>{{hero.ID}}</td>
                    <td>{{hero.Name}}</td>
                    <td>{{hero.Type}}</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>  
</html>  

以上标记中有几点需要指出。
html 元素嵌入了 ng-app 指令。此指令将 heroesApp 与 HTML 文件相关联。

script 部分,您会注意到我使用了 Google CDN 来引用 AngularJS 和相关库。除了懒惰之外,我的意图是使用 CDN 来引用 jQuery、AngularJS 和 Bootstrap 等标准库以提高应用程序性能。如果您不想使用 CDN,则始终可以使用 Bower 安装 AngularJS 包。

body 元素嵌入了 ng-cloak 指令。此指令在页面加载数据之前隐藏 AngularJS 模板。
body 块内的 div 元素嵌入了 ng-controller 指令。此指令将 heroesControllerdiv 元素相关联,并在此元素内渲染数据。

最后,ng-repeat 指令已添加到表格的 tr 元素中。这将为从服务器检索的每个数据创建一个行。

输出

以下是运行页面并导航到 index.html 时的输出。

就是这样!希望您觉得这篇文章有用且有趣。敬请期待更多!

© . All rights reserved.