Asp.Net Core自定义webapi框架

最后更新: 2022/12/24 建立: 2019/5/10

(github)https://github.com/mirrortom/MyWebApiCore

简介 建立 部署 静态文件 必要概念 差别

简介

基于NET6.0 的 ASP.NET CORE 空项目模板.主要功能是将url解析到类的方法上.是一个简单的webapi功能框架.

主要文件

  • ApiHandler.cs: 自定义的"中间件"类.含有url解析中间件和异常处理中间件.
  • ApiBase.cs: 提供一些便利方法.如取参数,返回结果等,所有webapi类要继承此类.
  • ApiAttr.cs: 用于webapi类或者方法的特性.比如[HTTPGET][HTTPPOST][AUTH].User类是请求者信息,按需修改
  • settings.json: 自定义的配置文件,配置监听端口和其它选项.
  • Config.cs: 读取settings.json文件,生成配置项供程序设置.

webapi类约定

  • 类名以Api结尾
  • 类要继承ApiBase
  • 类的方法上要贴上特性

建立项目

  • 用VS2022建一个asp.net core的空项目.选.NET 6.0
  • 加入引用Newtonsoft.Json
  • 复制文件夹core里的文件,还有settings.json,以及Program.cs
  • 运行项目,打开浏览器测试.

部署

  • 直接部署,kestrel是可以用于边缘的web服务器.不用部署到其它web服务器环境内.但官方文档不推荐.
  • 部署到IIS,Apache,nginx这些服务后面.托管asp.net core应用,也就是放在代理服务器后面.
  • 在windows平台,可以托管在windows服务下,asp.net core程序支持以windows服务方式托管运行.只需要做很少的修改,这是种成本较低的部署方式.

IIS托管代理

由IIS做监听,请求转发到kestrel. (文档)https://learn.microsoft.com/zh-cn/aspnet/core/host-and-deploy/iis/out-of-process-hosting?view=aspnetcore-6.0


    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <location path="." inheritInChildApplications="false">
        <system.webServer>
          <handlers>
            <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
          </handlers>

          // 进程名字是自己项目的
          <aspNetCore processPath=".\项目名字.exe"
                      stdoutLogEnabled="false"
                      stdoutLogFile=".\logs\stdout"

                      // 要使用进程外托管.
                      hostingModel="outofprocess"/>
        </system.webServer>
      </location>
    </configuration>

托管方式也可以在项目的.csproj里添加 <AspNetCoreHostingModel>OutOfProcess[InProcess]</AspNetCoreHostingModel> 来说明进程外(内)托管.这样项目发布后,web.config文件中的托管方式值会以设定的值生成.

以windows服务方式托管运行

部署成服务时,可以当成一个本地程序,就像控制台程序但没有黑窗口.可用本机网页做交互UI.文档:https://learn.microsoft.com/zh-cn/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-6.0&tabs=visual-studio

  • 添加包引用 Microsoft.AspNetCore.Hosting.WindowsServices
  • 打开PowerShell管理员,使用sc命令建立一个windows服务:(下面MyWebApiServer是服务名字,binPath是exe程序路径.DisplayName是服务显示名字)
  • sc.exe create MyWebApiServer binPath="D:/MyWebApiPublisher/MyWebApi.exe" DisplayName=MyWebApiOnWinServer
  • 如果建立成功了,那么打开services.msc 就能找到这个服务,然后点击启动服务.成功后可打开浏览器试调API

可以用sc命令启动/停止服务: sc start/stop [SrvName]

部署到linux

发布文件,选择 "独立" 部署模式,运行时选择 "linux-64"

文件复制到linux下,运行 MyWebApi.exe文件启动项目.

在linux下,一般需要做nginx托管代理(文档:)https://learn.microsoft.com/zh-cn/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-6.0

还要以系统服务进程开启项目.这个用systemctl这个工具.

静态文件

静态文件参考文档: https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/static-files?view=aspnetcore-6.0

静态文件的默认目录是 wwwroot ,位于目录 {content root}/wwwroot

调用无参数系统中间件 UseStaticFiles() 方法重载将启用静态文件功能, 提供wwwroot目录中的文件.

自定义其它静态文件目录

调用有参数的 UseStaticFiles(StaticFileOptions[]).参数里指定了一个物理目录和对应的虚拟目录.

这个功能可以在kestrel服务器建立虚拟目录.例如内容根下的一个目录 "/contentRoot/img" 虚拟目录 "/cdn/img"

默认文档

指定一个文件在网址打开时不带url时显示.例如 index.html

调用系统中间件 UseDefaultFiles(DefaultDocOptions) 参数方法可以添加多个默认文档.

必要概念

asp.net core基础概念文档:https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/?view=aspnetcore-7.0&tabs=windows

容器层次

从core2.1到.net 6,水平差依然是觉得复杂看不明白.现在7.0文档比较丰富,感觉有点思路了.开始有一个主机,这是所有东西的容器(Host类),是封装应用资源的对象.比如主机管理配置信息/环境变量/日志,可以添加服务(IServiceCollection)/web主机(IWebHostBuilder)等.web主机也是容器,是提供web服务的,可以选择一种监听服务器,比如Kestrel(默认)或者IIS,也可以自定义服务器.web服务器可以承载应用程序IApplicationBuilder,应用程序里面就是功能模块MiddleWare.

配置

(Asp.Net)https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/?view=aspnetcore-7.0

(.NET)https://learn.microsoft.com/zh-cn/dotnet/core/extensions/configuration

配置途径真是五花八门.最后使用json文件方式


    // 系统自带的解析配置类
    IConfiguration config = new ConfigurationBuilder()
                .AddJsonFile("settings.json")
                .Build();

    // 支持索引器取json里的值还算比较方便 支持数组和KV

    // {key:"val1",key2:{key21:21}}
    config.GetValue<string>("key") 或 config["key"]
    config.GetValue<int>("key2:key21") // 21

    // {vers:[1,2,3,4,5]}
    config.GetValue<int>("vers:0") // 1

    // {psnode:[{k:1,v:1},{k:2,v:2},...]} 取一个数组转化成字典数组
    config.GetSection("psnode").Get<Dictionary<string, string>[]>();

中间件

(文档)https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-7.0

实现功能的程序,比如解析URL,处理异常,跨域等,都是通过加载中间件实现.系统已经内置了很多中间件,直接选用就行.需要实现特定功能就做一个中间件.

若干中间件组成管道处理链条,顺序很重要.比如异常中间件需要在其它中间件之前加载,否则异常出现了,异常处理中间件还没加载.静态文件中间件要在动态处理中间件之前加载.

中间件执行完会执行下一个,传递HttpContext对象.有些不会传递,比如静态文件中间件,请求到静态文件中间件后,如果找到了页面,就会返回页面,中止请求,这个是中间件短路.加载自定义中间件的方法是Use(),如果要加载一个短路中间件,可以使用Run(),一般最后一个中间件可以用Run()加载.

C#

需要了解的C#相关知识. Delegate 泛型 async异步方法 依赖注入DI Task 异常处理 反射 序列化

差别

Asp.Net Core与经典的asp.net的差别比较大了,功能上感觉更先进,也更复杂.Asp.Net Core是一个可以承载多种功能的容器平台了,不再仅仅是web服务.

  • 自带服务器kestrel,可以独立部署.除了windows,可部署Linux,真正跨平台.
  • 中间件方式实现功能模块,可以按需加载,而不用限制在asp.net的十几个事件点上.
  • 系统自带了丰富的中间件,像跨域之类的.只需要配置一下跨域规则.Asp.Net Core上的mvc webapi框架也都有,使用习惯比经典版本类似.不过前后端分离的话,这些框架基本没用了.