使用 dotnet core 和 Azure PaaS服务进行devOps开发(Web API 实例)
作者:陈希章 发表于 2017年12月19日
引子
这一篇文章将用一个完整的实例,给大家介绍如何基于dotnet core(微软.NET的最新版本,支持跨平台,跨设备的应用开发,详情请参考 https://www.microsoft.com/net 开发一个Web API Service,并且利用Azure的PaaS服务来实现部署,以及持续的开发运营(devops)。
这篇文章的难度不高,但会作为一个操作指南,后续很多文章,如果涉及到这块基础工作,都会引用这篇文章。本文所演示的范例代码,可以通过 https://github.com/chenxizhang/dotnetcoreapisample 下载。
1、安装dotnet core SDK
目前的最新版本是2.1.3,你可以根据需要下载到不同的版本,请注意安装SDK,而不是Runtime。
- https://www.microsoft.com/net/download/windows
- https://www.microsoft.com/net/download/linux
- https://www.microsoft.com/net/download/macos
2、安装开发工具 visual studio code
这个工具同样是支持跨平台的,请通过下面的地址下载安装:https://code.visualstudio.com/Download
3、创建Web API 项目
在命令行工具中运行 dotnet new webapi –o dotnetcoreapisample

4、运行Web API 项目
即便不做任何修改,在命令行工具中运行dotnet run即可运行这个项目。
在浏览器中访问 http://localhost:5000/api/values 如果你也看到下面的效果,恭喜你,你的项目已经运行成功了。
在命令行中输入 code . 会自动打开Visual Studio Code。如果你打开Controllers目录下面的ValuesController.cs 文件,你可以看到如下代码,跟上面的网页返回结果对照一下,你会觉得现在编写一个Web API 真的非常简单啊。

5、增加数据实体
虽然上面的代码能运行,但我们真正要做的一个Web API服务,是希望能给用户提供创建订单,修改订单,查询订单,甚至删除订单的服务。所以,请先删除掉上面这个ValuesController.cs 文件。我会演示怎么样一步一步地将一个订单服务实现出来。
所有的服务都离不开数据,我们将使用Entity Framework来实现数据层服务。所以我们要先定义订单这个数据接口的实体。
请增加一个目录,Models,然后增加第一个代码文件 Order.cs
namespace dotnetcoreapisample.Models
{
using System;
public class Order{
public int Id { get; set; }
public DateTime OrderDate { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public string Product { get; set; }
}
}
6、创建数据服务
光有数据实体是不够的,我们还需要定义一个数据服务,或者也可以成为数据上下文服务。请在Models目录中,再创建下面这样一个类:SampleDbContext.cs
namespace dotnetcoreapisample.Models{
using System;
using Microsoft.EntityFrameworkCore;
using System.Linq;
public class SampleDbContext:DbContext{
public SampleDbContext(DbContextOptions<SampleDbContext> options):base(options){
}
public DbSet<Order> Orders { get; set; }
}
}
7、注入数据服务
dotnet core提供了一种非常好的编程模型,我们可以在程序启动的时候,将必要的数据服务对象注入进去,然后在后续的业务服务中就可以直接使用它。
定位到Startup.cs这个文件,在顶部先添加两个命名空间的引用 using Microsoft.EntityFrameworkCore; 和 using dotnetcoreapisample.Models;
然后在 ConfigureServices 这个方法里面,第一行添加如下代码 services.AddDbContext<SampleDbContext>(_=>_.UseInMemoryDatabase("Sample"));
这句代码的意思是,使用一个在内存中的数据库。作为快速开发和测试目的,这是最方面的。当然,如果你真的想要有一个实际的数据库文件,Entity Framework支持几乎所有的数据源,尤其是对sqlite和SQL Server的支持非常好,请参考 https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/intro
8、创建Web API 服务
这是最后一步了,请在Controllers目录中增加一个OrderController.cs的文件,代码如下
using Microsoft.AspNetCore.Mvc;
using dotnetcoreapisample.Models;
using System.Collections.Generic;
using System.Linq;
namespace dotnetcoreapisample.Controllers
{
[Route("api/[controller]")]
public class OrdersController:Controller{
private SampleDbContext context;
public OrdersController(SampleDbContext ctx){
context = ctx;
}
[HttpGet]
public IEnumerable<Order> Get(){
return context.Orders;
}
[HttpGet("{id}")]
public Order Get(int id){
return context.Orders.FirstOrDefault(x=>x.Id == id);
}
[HttpPost]
public void Post([FromBody]Order value){
context.Orders.Add(value);
context.SaveChanges();
}
[HttpPut("{id}")]
public void Put(int id,[FromBody]Order value){
var found = context.Orders.FirstOrDefault(x=>x.Id == id);
if(found!=null){
found.OrderDate = value.OrderDate;
found.Product =value.Product;
found.Quantity =value.Quantity;
found.UnitPrice =value.UnitPrice;
context.SaveChanges();
}
}
[HttpDelete("{id}")]
public void Delete(int id){
var found = context.Orders.FirstOrDefault(x=>x.Id == id);
context.Orders.Remove(found);
context.SaveChanges();
}
}
}
9、运行和测试Web API服务
完成上面的工作后,你就可以通过按下F5键(或者执行dotnet run命令)运行这个项目了。我用Fiddler来模拟用户请求,下面展示了四个不同的脚本。
创建订单
我们使用POST方法发起请求,地址是http://localhost:5000/api/orders,然后在请求的正文里面用JSON格式表示一个订单信息
查询订单
我们使用GET方法发起请求,地址也是http://localhost:5000/api/orders,在请求的头部里面设置Content-Type为application/json
此时我们可以看到,系统已经创建了一个订单,编号为1(这是自动编号的)。
修改订单
我们使用PUT方法发起请求,地址是http://localhost:5000/api/orders/1,在请求的正文里面,我将要修改的订单信息用JSON表示,请注意,我将单价从200修改为400
如果再次查询订单,你可以看到数据已经修改了
删除订单
最后,我们可以通过DELETE方法发起请求,给定地址是 http://localhost:5000/api/orders/1 来完成删除一个订单的操作
一切看起来还不错,接下来给大家介绍一下如何采用Azure云平台进行部署,以及通过Azure的PaaS服务实现开发运营一体会(devops)的实践。
10、创建Azure的应用程序服务(App Service)
传统的情况,开发人员(和测试人员)做到上面这一步,工作就算结束了。他们会将代码签入到代码库,然后愉快地打卡下班。接下来的工作是什么呢?运维人员会准备虚拟机,安装必要的软件,然后将代码下载下来,编译之后将得到的文件复制到服务器的某个文件夹,沐浴更衣烧香拜佛之后,很有可能Web服务器能正常地启动起来,如果不能,他们就要顶着巨大的压力,跟开发人员打电话,委婉地要求对方帮忙检查一下问题,但是很可能得到的答复是:你是怎么弄的呢,这个明明在我的机器是跑的好好的?上帝保佑,如果这次部署是成功的,但下次如果要更新一个版本,可能是再一次的痛苦的过程。如果说,在以前的时候我们的软件更新并不频繁,这种痛苦还是可以接受的话,现在随着互联网应用开发模式的兴起,业务需求可能三天两头的变化,如此的开发运营割裂的状况,是远远达不到要求的。这也是业界呼唤有更好的工作方式的一个根本原因,devops也就是这么样兴起的。
理论其实并不高深,关键看怎么能有效地实现开发和运维的一体化,很大程度上,这个当然取决于平台和工具,其根本在于要实现智能和自动化。另外,devops会逼迫我们重新对应用架构进行一些思考,模组化和微服务化会成为一个自然而然的选择。这个我在后面会有专门的文章给大家解读。本文先用实例来让大家感受一下。
我这里推荐的平台是微软的Azure云平台,它不仅仅是一个强大的IaaS平台,提供了全球质量保证和安全合规的基础架构服务(计算,网络,存储等),同时更重要的是,它是一个PaaS平台,对于广大的业务应用开发人员来说,使用Azure提供的工具,可以事半功倍地实现devops,将更多精力集中在应用逻辑而不是服务器配置、监测、部署更新等工作上面。
闲话少说,如果你还没有Azure账号,可以申请试用。接下来可以参考我的步骤来看看如何将我们刚才创建的这个Web API项目部署到Azure,并且实现基于代码更新的应用自动发布。
登录到Azure的管理门户后,选择“应用程序服务”,然后添加一个“Web应用”
在接下来的窗口中完成资源配置,请注意,作为测试场景的话,你甚至可以选择免费的一种应用服务计划。这里还可以打开Application Insight(这个目前也是免费的服务)。
配置这个应用服务的部署选择,此时逐渐解开了Azure 作为 devops 平台的面纱了。在下图中可以选择“本地Git存储库”作为部署源
虽然你可以看到很多其他的选项,但本篇文章是入门的,所以不做一一展开。下面我们设置一下部署的凭据。
完成上面这些配置后,我们回到Web应用的概述页面,你会发现现在多出来一个可以用来远程部署的Git存储库地址,请将这个地址复制下来。

11、配置和远程部署
回到之前的Visual Studio Code的界面,打开命令行窗口,通过git init 命令初始化本地的git存储库,然后执行git add *和git commit -m 'init' 这两条命令完成初始化提交到本地。最后,通过下面的命令添加远程存储库。
接下来,运行 git push azure master这条命令,此时会弹出一个对话框,请输入上一步创建的用户名和密码,这个提交过程可能会比较长,尤其是第一次。这是因为它不仅仅会将代码上传到代码库,而且后台会启动一系列的操作,来进行编译和部署。下面是在我这边的输出结果。
PS C:\temp\dotnetcoreapisample> git push azure master
Counting objects: 9, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (9/9), 7.90 KiB | 899.00 KiB/s, done.
Total 9 (delta 5), reused 0 (delta 0)
remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id '3adc61d27e'.
remote: Generating deployment script.
remote: Running deployment command...
remote: Handling ASP.NET Core Web Application deployment.
remote: ............................................................
remote: Restoring packages for D:\home\site\repository\dotnetcoreapisample.csproj...
remote: Restore completed in 755.48 ms for D:\home\site\repository\dotnetcoreapisample.csproj.
remote: .....
remote: Generating MSBuild file D:\home\site\repository\obj\dotnetcoreapisample.csproj.nuget.g.props.
remote: Generating MSBuild file D:\home\site\repository\obj\dotnetcoreapisample.csproj.nuget.g.targets.
remote: Restore completed in 10.36 sec for D:\home\site\repository\dotnetcoreapisample.csproj.
remote: .............................................................
remote: Microsoft (R) Build Engine version 15.4.8.50001 for .NET Core
remote: Copyright (C) Microsoft Corporation. All rights reserved.
remote:
remote: ................................................
remote: dotnetcoreapisample -> D:\home\site\repository\bin\Release\netcoreapp2.0\dotnetcoreapisample.dll
remote: ...........
remote: dotnetcoreapisample -> D:\local\Temp\8d546e10a232b37\
remote: KuduSync.NET from: 'D:\local\Temp\8d546e10a232b37' to: 'D:\home\site\wwwroot'
remote: Copying file: 'dotnetcoreapisample.deps.json'
remote: Copying file: 'dotnetcoreapisample.dll'
remote: Copying file: 'dotnetcoreapisample.pdb'
remote: Copying file: 'dotnetcoreapisample.PrecompiledViews.dll'
remote: Copying file: 'dotnetcoreapisample.PrecompiledViews.pdb'
remote: Copying file: 'dotnetcoreapisample.runtimeconfig.json'
remote: Finished successfully.
remote: Running post deployment command(s)...
remote: Deployment successful.
To https://dotnetcoreapisample.scm.azurewebsites.net:443/dotnetcoreapisample.git
37b30a5..3adc61d master -> master
我们可以很清楚地看到代码上传后,触发了一个部署的事件,该部署脚本先会拉取所有依赖的包,然后执行构建,最后将文件复制到指定的一个目录。这种自动化的过程就是devops的基石。当然,现在的dotnet core的平台无关性也给部署带来了极大的便利。
12、查看Web API的运行结果
在完成部署后,我们回到Azure的门户,在应用服务的“部署选项”可以看到已经部署的记录,最新的一次部署被标记为 “活动”状态。
点击某一次部署,还可以看到详细信息
如果我们对于当前这次部署不满意,还可以随时选择其他部署,并且选择“重新部署”操作,这样就可以快速进行应用的回滚。
好了,我们最后可以在浏览中输入 https://dotnetcoreapisample.azurewebsites.net/api/orders ,如果返回一个空白的数组“[]” ,说明这个服务是正常工作的。因为我们使用的是内存数据库,所以每次部署后,都会将数据清空,这就是为什么第一次返回空白数组的原因。
结语
使用Azure的PaaS服务来部署Web 应用,通过简单配置后,开发人员只需要关注代码本身,在本地调试后,将代码推送到Azure,后台将自动进行构建和部署,由于有版本控制,所以随时可以根据需要进行前滚和回滚。基于Azure平台进行应用开发,无缝地融入了devops,可以极大地改善开发和运维流程,提高研发效率和质量。本文只是一个开始,我在后续还会介绍各种不同的场景。
使用 dotnet core 和 Azure PaaS服务进行devOps开发(Web API 实例)的更多相关文章
- devOps开发(Web API 实例)dotnet core 和 Azure PaaS服务
使用 dotnet core 和 Azure PaaS服务进行devOps开发(Web API 实例) 作者:陈希章 发表于 2017年12月19日 引子 这一篇文章将用一个完整的实例,给大家介绍如何 ...
- Azure PaaS服务密钥的安全性
Azure PaaS服务,比如存储,Redis缓存,服务总线,IoT中心等等,一般通过密钥来认证客户端,也就是说只有提供正确密钥的客户端才能访问和使用对应的Azure PaaS服务,所以这个密钥是很重 ...
- .Net Core 3.1浏览器后端服务(一) Web API项目搭建
一.前言 基于CefSharp开发的浏览器项目已有一段时间,考虑到后期数据维护需要Server端来管理,故开启新篇章搭建浏览器后端服务.该项目前期以梳理服务端知识为主,后期将配合CefSharp浏览器 ...
- ASP.NET Core 1.0开发Web API程序
.NET Core版本:1.0.0-rc2Visual Studio版本:Microsoft Visual Studio Community 2015 Update 2开发及运行平台:Windows ...
- .NET Core HttpClient调用腾讯云对象存储Web API的"ERROR_CGI_PARAM_NO_SUCH_OP"问题
开门见山地说一下问题的原因:调用 web api 时请求头中多了双引号,请求体中少了双引号. 腾讯云提供的对象存储(COS)C# SDK 是基于 .NET Framework 用 WebRequest ...
- Azure AI 服务之语音识别
笔者在前文<Azure AI 服务之文本翻译>中简单介绍了 Azure 认知服务中的文本翻译 API,通过这些简单的 REST API 调用就可以轻松地进行机器翻译.如果能在程序中简单的集 ...
- dotnet core在Task中使用依赖注入的Service/EFContext
C#:在Task中使用依赖注入的Service/EFContext dotnet core时代,依赖注入基本已经成为标配了,这就不多说了. 前几天在做某个功能的时候遇到在Task中使用EF DbCon ...
- asp.net core 2.0 web api基于JWT自定义策略授权
JWT(json web token)是一种基于json的身份验证机制,流程如下: 通过登录,来获取Token,再在之后每次请求的Header中追加Authorization为Token的凭据,服务端 ...
- Asp.Net Core Web Api图片上传(一)集成MongoDB存储实例教程
Asp.Net Core Web Api图片上传及MongoDB存储实例教程(一) 图片或者文件上传相信大家在开发中应该都会用到吧,有的时候还要对图片生成缩略图.那么如何在Asp.Net Core W ...
随机推荐
- Problem W
Problem Description Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了.要申请国外的任何大学,你都要交纳一定的申请费用 ...
- John
John Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Submissi ...
- 磁盘管理之 raid 文件系统 分区
第1章 RAID 磁盘阵列 1.1 使用raid的目的 1)获得更大的容量 2)让数据更安全 3)读写速度更快 1.2 raid0.raid1.raid5.raid10对比 磁头 0磁道 1扇区 前4 ...
- kettle介绍
Kettle也叫PDI,在2006年Kettle加入了开源的BI组织Pentaho,正式命名为PDI,英文全称为Pentaho Data Integeration.Kettle是"Kettl ...
- 利用PowerShell 得到 进程总共占用的内存
$task = tasklist /nh /fo csv $total = 0 for($i=0; $i -lt $task.count; $i++) { $one = $task[ $i ].Spl ...
- scrolling 优化 避免卡顿
让我们来瞧瞧在滚动时到底发生了什么.在理解这个问题之前,我们先简要的介绍下浏览器是如何向屏幕绘制内容的.这一切都是从 DOM 树(本质上就是页面中的所有元素)开始的.浏览器先检查拥有了样式的 DOM, ...
- JAVAscript学习笔记 js条件语句 第三节 (原创) 参考js使用表 (2017-09-14 15:55)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 利用Python循环(包括while&for)各种打印九九乘法表
一.for循环打印九九乘法表 #注意:由于缩进在浏览器不好控制,请大家见谅,后续会有图片传入. 1.1 左下角 for i in range(1,10): for j in range(1,i+1): ...
- 使用qt制作一个简单的计算器
前言:今天使用qt制作了一个很简单的计算器,觉得挺有意思的,所以在这里跟大家分享一下. 这里先跟大家说说使用到的函数: 一.槽连接函数 connect(信号发送者,发送的信号,信号接收者,信号接收者的 ...
- Python学习中的一些小例子
这篇文章包括用Python编写的斐波那契数列,三位数的水仙花数和百钱买百鸡的基础代码 斐波那契数列: ''' def hanshu(n): n_1 = 1 n_2 = 1 m = n sumn = 0 ...