【起手式】开始一个Asp .net core WebApi项目

在这篇文章,我们来试着搭建一个完备可用的Asp .net core WebApi项目,以便我们后续的业务开发。

创建工程

首先第一步自然就是创建一个新的工程了,直接创建一个最简单的啥都没有的的api工程即可

dotnet new webapi -o ProjectName

Service Extensions

C#有个非常有趣的扩展方法功能,利用它,我们可以把代码搞得更加整洁一点。

新建一个静态类,我们把它叫做ServiceExtensions

然后,所有配置依赖注入服务相关的东西,我们都使用扩展方法的形式写在这里,这样一来,Startup类里面就会简洁许多。


OpenID Connect

通常,我们的项目使用OIDC (OpenID Connect)Jwt Bearer 来保护Api资源,所以我们先来配置oidc相关内容。

首先我们需要引入一个Nuget包

IdentityServer4.AccessTokenValidation

这里我们直接使用IdentityServer4提供的包,当然也可以使用别的,比如Microsoft.AspNetCore.Authentication.JwtBearer等等

然后我们在ServiceExtensions中编写代码如下:

using IdentityServer4.AccessTokenValidation;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Meow.Api
{
    public static class ServiceExtensions
    {
        public static void AddAuthenticationWithOIDC(this IServiceCollection services , IConfiguration configuration)
        {
            services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = configuration["Oidc:Authority"];
                    options.ApiName = configuration["Oidc:ApiName"];
                    options.RequireHttpsMetadata = configuration.GetValue<bool>("Oidc:RequireHttps");
                });
        }
    }
}

其中”Oidc:Authority”等相关配置项需要写道”appsettings.json”中。

然后,我们通过上面的扩展方法,向Startup的ConfigureServices配置Oidc相关内容:

同样的,我们得配置一下管道


Swagger

对于WebApi项目来说,Swagger是个非常有用的大宝贝。尤其在调试Api时候,网页上直接点点就完事了,省的去开postman了,非常方便。

首先,依然是先添加个Nuget包进来:

Swashbuckle.AspNetCore
Swashbuckle.AspNetCore.SwaggerGen

然后继续编写扩展方法:

public static void AddSwagger(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
                {
                    Title = configuration["Swagger:v1:Title"],
                    Version = configuration["Swagger:v1:VersionName"],
                    Description = configuration["Swagger:v1:Desc"],
                });

                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                options.IncludeXmlComments(xmlPath);


                //Auth
                var dict_scopes = new Dictionary<string, string>();
                string[] scopes_arr = configuration.GetSection("Swagger:Oidc:Scopes").Get<string[]>();
                string[] scopes_desc_arr = configuration.GetSection("Swagger:Oidc:ScopesDesc").Get<string[]>();
                for(var i = 0; i < scopes_arr.Length; i++)
                {
                    dict_scopes.Add(scopes_arr[i], (scopes_desc_arr.Length > i) ? scopes_desc_arr[i] : scopes_arr[i]);
                }
                options.AddSecurityDefinition("oidc", new OpenApiSecurityScheme 
                {
                    Type = SecuritySchemeType.OAuth2,
                    Flows = new OpenApiOAuthFlows
                    {
                        Implicit = new OpenApiOAuthFlow
                        {
                            AuthorizationUrl = new Uri($"{configuration["Oidc:Authority"]}/connect/authorize"),
                            Scopes = dict_scopes
                        }
                    }
                });

                options.OperationFilter<AuthResponsesOperationFilter>();
            });
        }

这里就有点复杂了,一样样来,

首先,这样直接运行会报错,因为默认情况下这个工程不会生成xml文档,而我们Swagger是需要xml文档来读取注释信息的,于是就报错了,我们得改改。

打开这个项目的.csproj文件,添加如下:

<PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Swagger部分对应的appsetting.json配置如下:

然后,最后options.OperationFilter<AuthResponsesOperationFilter>(); 这一句中的AuthResponsesOperationFilter,代码如下:

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace Meow.Api
{
    public class AuthResponsesOperationFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true)
                .Union(context.MethodInfo.GetCustomAttributes(true))
                .OfType<AuthorizeAttribute>()
                .Any();

            if (hasAuthorize)
            {
                operation.Responses.Add("401", new OpenApiResponse { Description = "暂无权限访问" });
                operation.Responses.Add("403", new OpenApiResponse { Description = "禁止访问" });

                operation.Security = new List<OpenApiSecurityRequirement>();
                operation.Security.Add(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oidc" }
                        },
                        new[] { "Api1" , "openid" } //这里改成你自己的Scopes
                    }
                });
            }
        }
    }
}

最后给它添加到Startup类里

同样的,有部分内容需要添加到管线中:

之后,我们就可以访问到Swagger的页面了

点击右边的绿色按钮,我们可以直接跳转登录,然后就可以测试带有身份验证的Api了。

yomunsam

文章作者信息...

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>

推荐ヾ(•ω•`)o