<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      使用Scalar.AspNetCore來管理你的OpenApi

      一直覺得很好的一個組件,網上介紹少得可憐,沒辦法,只有自己爬官網了,又是對照git又是看doc文檔,總算是玩明白了,現在完全拋棄那個誰誰誰了。因人喜好各取所長吧

      先來官方參考地址:

      https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/openapi/include-metadata?view=aspnetcore-9.0&tabs=minimal-apis

      這是scalar的.net 集成文檔地址

      https://guides.scalar.com/scalar/scalar-api-references/integrations/net-aspnet-core/integration

      github地址

      https://github.com/scalar/scalar

      先放個圖,誘惑一下,集成了很多主題,還可以自定主題(留給前端去玩吧)

      01

       

      一、簡單使用

      1.建立一個API項目,(最小,mvc都可)

      2.引用包

       dotnet add package Scalar.AspNetCore (當前版本2.9.0)

       dotnet add package Microsoft.AspNetCore.OpenApi(當前版本10.0)

      3.添加引用

      using Scalar.AspNetCore;

      4.添加配置,在Program.cs中添加下面配置

      builder.Services.AddOpenApi();
      
      if (app.Environment.IsDevelopment())
      {
          app.MapOpenApi();
          app.MapScalarApiReference();
      }

      現在運行一下,看看,localhost:xxxx/scalar

      是不是看到列出漂亮的界面了?

      二、基本配置

      1.自定義路由

      不想使用/salar,可以換成自己的地址

      app.MapScalarApiReference("/api-docs");
      app.MapScalarApiReference("/docs");

      2.多文當或版本控制

      // Chain multiple documents
      app.MapScalarApiReference(options =>
      {
          options.AddDocument("v1", "Production API", "api/v1/openapi.json")
                 .AddDocument("v2-beta", "Beta API", "api/v2-beta/openapi.json", isDefault: true)
                 .AddDocument("internal", "Internal API", "internal/openapi.json");
      });
      isDefault: true是默認打開的頁面
      3.自定義文檔的默認調試語言
      app.MapScalarApiReference(options =>
      {
          options.WithDefaultHttpClient(ScalarTarget.CSharp, ScalarClient.HttpClient);
      });

      02

      它對應右邊窗口的語言,基本上都支持,java,php,rust,py,swift

      三、高級配置

      之前的老版本使用的硬編碼option加配置,2.9.0以后,在界面右上角菜單欄上出現了一個編輯配置功能

      03

      根據自己的喜好,調試編輯完配置文件后,可以復制到文件中單獨保存,真是太貼心了

      {
        "title": "Aquxa API Documentation",
        "slug": "aquxa-api-documentation",
        "hideClientButton": true,
        "servers": [
          {
            "url": "http://localhost:5215",
            "description": "Development server"
          }
        ],
        "showSidebar": true,
        "showToolbar": "localhost",//這里特別說明一下,編輯完后,不想出現這個菜單欄,就在這里可以關閉showToolbar: "never"
        "operationTitleSource": "summary",
        "theme": "solarized",//主題可以自己選,喜歡哪個選哪個
        "_integration": "dotnet",
        "persistAuth": false,
        "telemetry": true,
        "layout": "modern",
        "isEditable": false,
        "isLoading": false,
        "hideModels": true,
        "documentDownloadType": "both",
        "hideTestRequestButton": false,
        "hideSearch": false,
        "showOperationId": false,
        "hideDarkModeToggle": false,
        "favicon": "favicon.svg",
        "withDefaultFonts": true,
        "defaultOpenAllTags": false,
        "expandAllModelSections": true,
        "expandAllResponses": true,
        "orderSchemaPropertiesBy": "alpha",
        "orderRequiredPropertiesFirst": true,
        "url": "http://localhost:5215/openapi/v1.json"
      }
      PS:這里特別說明一下,編輯完后,不想出現這個菜單欄,就在這里可以關閉showToolbar: "never"
      得到這個文件,保存到wwwroot/js/scalar-config.js,注意,一定要保存到能訪問的靜態目錄里,并在program.cs添加靜態目錄的配置
      app.UseStaticFiles(). //這個要放在scalar配置的前面,不然訪問不到

      添加配置文件加載

      .WithJavaScriptConfiguration("/js/scalar-config.js")     

       

      04

      這里費了好大的勁,查官方,看代碼,因為官方文檔還是老文檔,只是簡單的概括了一下。最后整出來了

      四、文檔的編輯

      使用最重要的還是API文檔編輯,其實它完全用的標準的OpenApi,只要參考這個表就可以完全配置了

      05

      [ApiController]
          [Route("api/[controller]")]
          [ApiExplorerSettings(GroupName = "v1")]
          [Tags("Admin")] // 為整個控制器添加標簽
          public class AdminController : ControllerBase
          {
              [HttpPost("reload-cache")]
              public IActionResult ReloadCache()
              {
                  // 模擬重新加載緩存的操作
                  return Ok("Cache reloaded successfully");
              }
              
              [HttpGet("stats")]
              public IActionResult GetStats()
              {
                  return Ok(new { Users = 100, Requests = 1000 });
              }
          }

      下面說一下常用的特性

      1.API分組

          [ApiExplorerSettings]

      這個比較熟悉,它可以分組,分版本,當你分好版本后[ApiExplorerSettings(GroupName = "v1")]/[ApiExplorerSettings(GroupName = "v2")],會在scalar中左上角可以選擇,當然,你也可以把它做為組來用

      06

      如果有不想顯示的API也可以用[ApiExplorerSettings(IgnoreApi = true)]來排除顯示

      [HttpGet("/private")]
      [ApiExplorerSettings(IgnoreApi = true)]
      public IActionResult PrivateEndpoint() {
          return Ok("This is a private endpoint");
      }

      2.API分類

      [Tags]

      分類的API,會歸檔在一起,方便查詢,這樣看起來沒有那么亂了

      [Tags(["Admin", "OtherAPI"])]
      [HttpGet("attributes")]
      public IResult Attributes()
      {
          return Results.Ok("Hello world!");
      }

      07

      3.描述

      [EndpointSummary("OtherApi")]
      [EndpointDescription("這是一個公開接口,無需認證")]
      [HttpGet("attributes")]
      public IResult Attributes()
      {
          return Results.Ok("Hello world!");
      }

      08

      4.過濾

      不想顯示的接口可以用

      上面說的

      [ApiExplorerSettings(IgnoreApi = true)]來關閉
      還有一個就是根目錄,如果在配置文件中有MapGet,
      可以使用.ExcludeFromDescription();排除顯示
       
          // 默認打開首頁
          app.MapGet("/", () => "Hangfire 服務運行中。訪問 /hangfire 查看儀表盤,訪問 /docs 查看API文檔").ExcludeFromDescription();
      //可以使用.ExcludeFromDescription();排除顯示
      

        



      更多編輯文檔就看這里吧

      https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/openapi/include-metadata?view=aspnetcore-9.0&tabs=controllers

      五、認證授權

      這里就使用自己的授權就可以,這里就偷懶找AI完成了。參考部分都有備注

      using Scalar.AspNetCore;
      using Microsoft.AspNetCore.Authentication;
      using Microsoft.Extensions.Options;
      using System.Security.Claims;
      using System.Text.Encodings.Web;
      using Microsoft.AspNetCore.Mvc;
      using MyWebApi; // 添加對WeatherForecast的引用
      
      var builder = WebApplication.CreateBuilder(args);
      
      // Add services to the container.
      // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
      builder.Services.AddOpenApi("v1");
      builder.Services.AddOpenApi("v2");
      // 添加控制器服務
      builder.Services.AddControllers();
      
      // 添加身份驗證服務
      builder.Services.AddAuthentication("BasicAuthentication")
          .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", null);
      
      // 添加授權服務
      builder.Services.AddAuthorization(options =>
      {
          options.AddPolicy("ScalarAccess", policy => policy.RequireAuthenticatedUser());
      });
      
      // 配置服務器URL,避免端口沖突
      builder.WebHost.UseUrls("http://localhost:5215");
      var app = builder.Build();
      
      // Configure static file middleware to serve the JavaScript config file
      app.UseStaticFiles();
      
      // 添加身份驗證和授權中間件
      app.UseAuthentication();
      app.UseAuthorization();
      
      // Configure the HTTP request pipeline.
      if (app.Environment.IsDevelopment())
      {
          app.MapOpenApi();
          // Add Scalar for API management with JavaScript configuration and authorization
          app.MapScalarApiReference("/scalar", options =>
          {
              options.WithTitle("MyWebApi")
                     .WithJavaScriptConfiguration("/js/scalar-config.js")               
                     .AddDocument("v1", "Aquxa API Documentation",isDefault: true)
                     .AddDocument("v2", "Beta API");
          })
          .RequireAuthorization("ScalarAccess"); // 應用授權策略
      }
      
      // 添加控制器路由
      app.MapControllers();
      
      app.Run();
      
      // Basic Authentication Handler
      public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
      {
          public BasicAuthenticationHandler(
              IOptionsMonitor<AuthenticationSchemeOptions> options,
              ILoggerFactory logger,
              UrlEncoder encoder)
              : base(options, logger, encoder)
          {
          }
      
          protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
          {
              // 檢查是否有Authorization頭
              if (!Request.Headers.ContainsKey("Authorization"))
                  return AuthenticateResult.NoResult();
      
              try
              {
                  // 解析Basic認證頭
                  var authHeader = Request.Headers["Authorization"].ToString();
                  if (!authHeader.StartsWith("Basic "))
                      return AuthenticateResult.NoResult();
      
                  var encodedCredentials = authHeader.Substring("Basic ".Length).Trim();
                  var decodedCredentials = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(encodedCredentials));
                  var credentials = decodedCredentials.Split(':', 2);
                  
                  var username = credentials[0];
                  var password = credentials[1];
      
                  // 驗證用戶名和密碼(這里使用硬編碼,實際應用中應從配置或數據庫獲?。?/span>
                  if (username == "admin" && password == "password123")
                  {
                      var claims = new[] { new Claim(ClaimTypes.Name, username) };
                      var identity = new ClaimsIdentity(claims, Scheme.Name);
                      var principal = new ClaimsPrincipal(identity);
                      var ticket = new AuthenticationTicket(principal, Scheme.Name);
                      
                      return AuthenticateResult.Success(ticket);
                  }
                  
                  return AuthenticateResult.Fail("Invalid username or password");
              }
              catch
              {
                  return AuthenticateResult.Fail("Invalid Authorization Header");
              }
          }
          
          protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
          {
              // 發送WWW-Authenticate頭以觸發瀏覽器的認證對話框
              Response.Headers["WWW-Authenticate"] = "Basic realm=\"Scalar API Documentation\"";
              await base.HandleChallengeAsync(properties);
          }
      }

       09

       

      
      
      posted @ 2025-10-17 17:28  wangbin5542  閱讀(585)  評論(6)    收藏  舉報
      主站蜘蛛池模板: 大屁股国产白浆一二区| 亚洲精品国产av一区二区| 国产乱码精品一区二区麻豆 | 国产三级国产精品国产专| 成人一区二区不卡国产| 人妻系列无码专区无码中出| 久热这里只精品视频99| 国产无套精品一区二区| 亚洲中文无码手机永久| 国产丰满乱子伦无码专区| 老熟妇欲乱一区二区三区| 亚洲色在线v中文字幕| 中文字幕在线永久免费视频 | 他掀开裙子把舌头伸进去添视频 | 国产精品无码a∨麻豆| 永久无码天堂网小说区| 亚洲精品久久久中文字幕痴女| 久久精品无码专区免费东京热| 国产欧美一区二区精品性色| 和艳妇在厨房好爽在线观看| 婷婷色综合成人成人网小说 | 中文字幕日韩人妻一区| 国产日韩精品一区二区三区在线| 亚洲永久一区二区三区在线| 国产精品亚洲二区在线播放| 91久久国产成人免费观看| 国产中文字幕日韩精品| 久久亚洲色www成人欧美| 国产精品爽爽va在线观看网站| 高清无码爆乳潮喷在线观看| 免费无码黄动漫在线观看| 91精品久久一区二区三区| 成在人线AV无码免观看| 国产精品一区在线蜜臀| 亚洲欧洲色图片网站| 加勒比在线中文字幕一区二区| 国产美女被遭强高潮免费一视频| 色道久久综合亚洲精品蜜桃| 毛片av在线尤物一区二区| 极品美女自拍偷精品视频| 精品国产美女福到在线不卡 |