或許是你應該瞭解的一些 ASP.NET Core Web API 使用小技巧

来源:https://www.cnblogs.com/danvic712/archive/2019/07/29/11255423.html
-Advertisement-
Play Games

一、前言 在目前的軟體開發的潮流中,不管是前後端分離還是服務化改造,後端更多的是通過構建 API 介面服務從而為 web、app、desktop 等各種客戶端提供業務支持,如何構建一個符合規範、容易理解的 API 介面是我們後端開發人員需要考慮的。在本篇文章中,我將列舉一些我在使用 ASP.NET ...


 一、前言

  在目前的軟體開發的潮流中,不管是前後端分離還是服務化改造,後端更多的是通過構建 API 介面服務從而為 web、app、desktop 等各種客戶端提供業務支持,如何構建一個符合規範、容易理解的 API 介面是我們後端開發人員需要考慮的。在本篇文章中,我將列舉一些我在使用 ASP.NET Core Web API 構建介面服務時使用到的一些小技巧,因才疏學淺,可能會存在不對的地方,歡迎指出。

  代碼倉儲:https://github.com/Lanesra712/ingos-server

 二、Step by Step

  因為本篇文章中涉及到的一些知識點在之前的文章中也已經有具體的解釋了,所以這裡只會說明如何在 ASP.NET Core Web API 中如何去使用,不會做過多的詳細介紹。如果你需要詳細瞭解的話,可以跳轉到文章中給出的外鏈地址去查看。

  本篇文章中使用的代碼是基於 .NET Core 2.2 + .NET Standard 2.0 進行構建的,如果你採用的版本與我使用的不同,可能最終實現起來的代碼會有所不同,請提前知悉。同時,本篇文章中所有示例代碼都會存在於前言中所列出的 github repo 中,我會嘗試將每個功能點的開發作為一次 commit,並且也會在後續進行不定期的更新完善,最終搭建一個基於領域驅動思想的後端項目模板,如果對你有幫助的話,歡迎持續關註。

  1、使用小寫路由

   在我之前的一篇文章中(構建可讀性更高的 ASP.NET Core 路由)有提到過,因為 .NET 預設採用 Pascal 的類命名方式,如果採用預設生成的路由,最終構建出的路由地址會存在大小寫混在一起的情況,雖然在 .NET Core 中大小寫的路由地址最終都會對於到正確的資源上,但是為了更好的符合前端的規範,所以這裡我們首先按照之前的文章中所列出的方法去修改預設生成的路由地址格式。

  因為這裡我們最終想要實現的是符合 Restful 風格的 API 介面,所以這裡我們首先需要將預設生成的 URL 地址改為全小寫模式。

public void ConfigureServices(IServiceCollection services)
{
    // 採用小寫的 URL 路由模式
    services.AddRouting(options =>
    {
        options.LowercaseUrls = true;
    });
}

  如果你有看過構建可讀性更高的 ASP.NET Core 路由這篇文章,你會發現其實我們最終實現的是 hyphen(-) 格式的 Url 地址,那麼這裡我們為什麼不進行後續的修改了呢?

  如果你有查看 .NET Core 預設模板中生成的 API Controller,仔細看下,這裡其實是使用的特性路由,所以這裡我們並不能通過 Startup.UseMvc 定義的傳統路由模板,或是直接在 Startup.Configure 中的 UseMvcWithDefaultRoute 方法去修改我們的生成的路由地址格式。

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
}

  2、允許跨域請求

  不管是後端介面的服務化改造,還是只是單純的前後端分離項目開發,我們的前端項目與後端介面通常不會部署在一起,所以我們需要解決前端訪問介面時會涉及到的跨域訪問的問題。

  針對跨域請求,我們可以採用 jsonp、或者是通過給 nginx 伺服器配置響應的 header 參數頭信息、或者是使用 CORS,又或是其它的解決方案。你可以自由選擇,這裡我採用在後端介面中直接配置對於 CORS 的支持。

  在 .NET Core 中,已經在 Microsoft.AspNetCore.Cors 這個類庫中添加了對於 CORS 的支持,因為這個類庫是存在於我們已經安裝的 .NET Core SDK 中,所以這裡我們並不需要通過 Nuget 進行安裝,可以直接使用。

  在 .NET Core 中配置 CORS 規則,我們可以通過在 Startup.ConfigureServices 這個方法中添加不同的授權策略,之後再針對某個 Controller 或是 Action 通過添加 EnableCors 這個 Attribute 的方式進行配置,這裡如果指定了 policy 策略名稱,則會使用指定的策略,如果沒有指定,則適用於系統的預設配置。同樣的,我們也可以只設置一個策略,直接針對整個項目進行配置,這裡我採用對整個項目採用通用的跨域請求配置方案。

  在配置 CORS 策略時,我們可以設置只允許來源於某些 URL 地址的請求可以訪問,或者是指定介面只允許某些 HTTP 方法進行訪問,或者是在請求的 header 中必須包含某些信息才可以訪問我們的介面。

  在下麵的代碼中,我定義了針對整個項目的跨域請求策略,這裡我只是設置了對於介面請求方 URL 地址的控制,通過讀取配置文件中的數據,從而達到只允許某些 IP 可以訪問的我們介面的目的。

public class Startup
{
    // 預設的跨域請求策略名稱
    private const string _defaultCorsPolicyName = "Ingos.Api.Cors";

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc(
            // 添加 CORS 授權過濾器
            options => options.Filters.Add(new CorsAuthorizationFilterFactory(_defaultCorsPolicyName))
        ).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        // 配置 CORS 授權策略
        services.AddCors(options => options.AddPolicy(_defaultCorsPolicyName,
            builder => builder.WithOrigins(
                    Configuration["Application:CorsOrigins"]
                    .Split(",", StringSplitOptions.RemoveEmptyEntries).ToArray()
                )
            .AllowAnyHeader()
            .AllowAnyMethod()
            .AllowCredentials()));
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // 允許跨域請求訪問
        app.UseCors(_defaultCorsPolicyName);
    }
}

  例如在下麵的設置中,我只允許這一個地址可以訪問我們的介面,如果需要指定多個的話,則可以通過英文的 , 進行分隔。

"Application": {
    "CorsOrigins": "http://127.0.0.1:5050"
}

  某些情況下,如果我們不想進行限制的話,只需要將值改為 * 即可。

"Application": {
    "CorsOrigins": "*"
}

  3、添加介面版本控制

   在一些涉及到介面功能升級的場景下,當我們需要修改介面邏輯而舊版本的介面無法停用的情況時,為了減少對於原有介面的影響,我們可以採取為介面添加版本信息的形式,從而降低因採用不同版本而造成的影響。如果你想要詳細瞭解的話,可以查看這篇文章,電梯直達 =》ASP.NET Core 實戰:構建帶有版本控制的 API 介面

   在實現具有版本控制的介面前,首先我們需要通過 Nuget 添加下麵的兩個 dll,因為我是在 Ingos.Api.Core 這個類庫中進行配置的,所以我安裝到了這個類庫下,你需要根據你自己的情況選擇最終是安裝到 Api 介面項目中還是在別的類庫下。

Install-Package Microsoft.AspNetCore.Mvc.Versioning
Install-Package Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer

  在安裝完成之後,我們就可以在 Startup.ConfigureServices 方法中,為項目中的介面配置版本信息,這裡我採用的方案是將版本號添加到介面的 URL 地址中。

  因為對於所有中間件的配置都會在 Startup.ConfigureServices 方法中,為了保持該方法的純凈性,這裡我寫了一個擴展方法用於配置我們的 api 的版本,之後直接調用即可。

public static class ApiVersionExtension
{
    /// <summary>
    /// 添加 API 版本控制擴展方法
    /// </summary>
    /// <param name="services">生命周期中註入的服務集合 <see cref="IServiceCollection"/></param>
    public static void AddApiVersion(this IServiceCollection services)
    {
        // 添加 API 版本支持
        services.AddApiVersioning(o =>
        {
            // 是否在響應的 header 信息中返回 API 版本信息
            o.ReportApiVersions = true;
    
            // 預設的 API 版本
            o.DefaultApiVersion = new ApiVersion(1, 0);
    
            // 未指定 API 版本時,設置 API 版本為預設的版本
            o.AssumeDefaultVersionWhenUnspecified = true;
        });

        // 配置 API 版本信息
        services.AddVersionedApiExplorer(option =>
        {
            // api 版本分組名稱
            option.GroupNameFormat = "'v'VVVV";
    
            // 未指定 API 版本時,設置 API 版本為預設的版本
            option.AssumeDefaultVersionWhenUnspecified = true;
        });
    }
}

  擴展方法最終實現方式如上面的代碼所示,之後我們就可以直接在 ConfigureServices 方法中直接進行調用這個擴展方法就可以了。

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // Config api version
    services.AddApiVersion();
}

  現在我們刪除項目創建時預設生成的 ValuesController,在 Controllers 目錄下建立一個 v1 文件夾,代表此文件夾下都是 v1 版本的控制器。添加一個 UsersController 用來獲取系統的用戶資源,現在項目的文件結構如下圖所示。

  現在我們來改造我們的 UsersController,我們只需要在 Controller 或是 Action 上添加 ApiVersion 特性就可以指定當前 Controller/Action 的版本信息。同時,因為我需要將 API 的版本信息添加到生成的 URL 地址中,所以這裡我們需要修改特性路由的模板,將我們的版本以占位符的形式添加到生成的路由 URL 地址中,修改完成後的代碼及實現的效果如下所示。

[ApiVersion("1.0")]
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
public class UsersController : ControllerBase
{
}

  4、添加對於 Swagger 介面文檔的支持

   在前後端分離開發的情況下,我們需要提供給前端開發人員一個介面文檔,從而讓前端開發人員知道以什麼樣的 HTTP 方法或是傳遞什麼樣的參數給後端介面,從而獲取到正確的數據,而 Swagger 則提供了一種自動生成介面文檔的方式,同時也提供類似於 Postman 的功能,可以實現對於介面的實時調用測試。

  首先,我們需要通過 Nuget 添加 Swashbuckle.AspNetCore 這個 dll 文件,之後我們就可以在此基礎上實現對於 Swagger 的配置。

Install-Package Swashbuckle.AspNetCore

  與上面配置 API 介面的版本信息相似,這裡我依舊採用構建擴展方法的方式來實現對於 Swagger 中間件的配置。具體的配置過程可以查看我之前寫的文章(ASP.NET Core 實戰:構建帶有版本控制的 API 介面),這裡只列出最終配置完成的代碼。

public static void AddSwagger(this IServiceCollection services)
{
    // 配置 Swagger 文檔信息
    services.AddSwaggerGen(s =>
    {
        // 根據 API 版本信息生成 API 文檔
        //
        var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();

        foreach (var description in provider.ApiVersionDescriptions)
        {
            s.SwaggerDoc(description.GroupName, new Info
            {
                Contact = new Contact
                {
                    Name = "Danvic Wang",
                    Email = "[email protected]",
                    Url = "https://yuiter.com"
                },
                Description = "Ingos.API 介面文檔",
                Title = "Ingos.API",
                Version = description.ApiVersion.ToString()
            });
        }

        // 在 Swagger 文檔顯示的 API 地址中將版本信息參數替換為實際的版本號
        s.DocInclusionPredicate((version, apiDescription) =>
        {
            if (!version.Equals(apiDescription.GroupName))
                return false;

            var values = apiDescription.RelativePath
                .Split('/')
                .Select(v => v.Replace("v{version}", apiDescription.GroupName)); apiDescription.RelativePath = string.Join("/", values);
            return true;
        });

        // 參數使用駝峰命名方式
        s.DescribeAllParametersInCamelCase();

        // 取消 API 文檔需要輸入版本信息
        s.OperationFilter<RemoveVersionFromParameter>();

        // 獲取介面文檔描述信息
        var basePath = Path.GetDirectoryName(AppContext.BaseDirectory);
        var apiPath = Path.Combine(basePath, "Ingos.Api.xml");
        s.IncludeXmlComments(apiPath, true);
    });
}

  當我們配置完成後就可以在 Startup 類中去啟用 Swagger 文檔。

public void ConfigureServices(IServiceCollection services)
{
    // 添加對於 swagger 文檔的支持
    services.AddSwagger();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApiVersionDescriptionProvider provider)
{
    // 啟用 Swagger 文檔
    app.UseSwagger();
    app.UseSwaggerUI(s =>
    {
        // 預設載入最新版本的 API 文檔
        foreach (var description in provider.ApiVersionDescriptions.Reverse())
        {
            s.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json",
                $"Sample API {description.GroupName.ToUpperInvariant()}");
        }
    });
}

  因為我們在之前設置構建的 API 路由時包含了版本信息,所以在最終生成的 Swagger 文檔中進行測試時,我們都需要在參數列表中添加 API 版本這個參數。這無疑是有些不方便,所以這裡我們可以通過繼承 IOperationFilter 介面,控制在生成 API 文檔時移除 API 版本參數,介面的實現方法如下所示。

public class RemoveVersionFromParameter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        var versionParameter = operation.Parameters.Single(p => p.Name == "version");
        operation.Parameters.Remove(versionParameter);
    }
}

  當我們實現自定義的介面後就可以在之前針對 Swagger 的擴展方法中調用這個過濾方法,從而實現移除版本信息的目的,擴展方法中的添加位置如下所示。

public static void AddSwagger(this IServiceCollection services)
{
    // 配置 Swagger 文檔信息
    services.AddSwaggerGen(s =>
    {
        // 取消 API 文檔需要輸入版本信息
        s.OperationFilter<RemoveVersionFromParameter>();
    });
}

  最終的實現效果如下圖所示,可以看到,參數列表中已經沒有版本信息這個參數,但是我們在進行介面測試時會自動幫我們添加上版本參數信息。

  這裡需要註意,因為我們需要在最終生成的 Swagger 文檔中顯示出我們對於 Controller 或是 Action 添加的註釋信息,所以這裡我們需要在 Web Api 項目的屬性選項中勾選上輸出 XML 文檔文件。同時如果你不想 VS 一直提示你有方法沒有添加參數信息,這裡我們可以在取消顯示警告這裡添加上 1591 這個參數。

  5、構建符合 Restful 風格的介面

   在沒有採用 Restful 風格來構建介面返回值時,我們可能會習慣於在介面返回的信息中添加一個介面是否請求成功的標識,就像下麵代碼中示例的這種返回形式。

{
    sueecss: true
    msg: '',
    data: [{
        id: '20190720214402',
        name: 'zhangsan'
    }]
}

  但是,當我們想要構建符合 Restful 風格的介面時,我們就不能再這樣進行設計了,我們應該通過返回的 HTTP 響應狀態碼來標識這次訪問是否成功。一些比較常用的 HTTP 狀態碼如下表所示。

HTTP 狀態碼涵義解釋說明
200 OK 用於一般性的成功返回,不可用於請求錯誤返回
201 Created 資源被創建
202 Accepted 用於資源非同步處理的返回,僅表示請求已經收到。對於耗時比較久的處理,一般用非同步處理來完成
204 No Content 此狀態可能會出現在 PUT、POST、DELETE 的請求中,一般表示資源存在,但消息體中不會返回任何資源相關的狀態或信息
400 Bad Request 用於客戶端一般性錯誤信息返回, 在其它 4xx 錯誤以外的錯誤,也可以使用,錯誤信息一般置於 body 中
401 Unauthorized 介面需要授權訪問,為通過授權驗證
403 Forbidden 當前的資源被禁止訪問
404 Not Found 找不到對應的信息
500 Internal Server Error 伺服器內部錯誤

  我們知道 HTTP 共有四個謂詞方法,分別為 Get、Post、Put 和 Delete,在之前我們可能更多的是使用 Get 和 Post,對於 Put 和 Delete 方法可能並不會使用。同樣的,如果我們需要創建符合 Restful 風格的介面,我們則需要根據這四個 HTTP 方法謂詞一些約定俗成的功能定義去定義對應介面的 HTTP 方法。

HTTP 謂詞方法解釋說明
GET 獲取資源信息
POST 提交新的資源信息
PUT 更新已有的資源信息
DELETE 刪除資源

  例如,對於一個獲取所有資源的方法,我們可能會定義介面的預設返回 HTTP 狀態碼為 200 或是 400,當狀態碼為 200 時,代表數據獲取成功,介面可以正常返回數據,當狀態碼為 400 時,則代表介面訪問出現問題,此時則返回錯誤信息對象。

  在 ASP.NET Core Web API 中,我們可以通過在 Action 上添加 ProducesResponseType 特性來定義介面的返回狀態碼。通過 F12 按鍵我們可以進入 ProducesResponseType 這個特性,可以看到這個特性存在兩個構造方法,我們可以只定義介面返回 HTTP 狀態碼或者是在定義介面返回的狀態碼時同時返回的具體對象信息。

  上面給出的介面案例的示例代碼如下所示,從下圖中可以看到,Swagger 會自動根據我們的 ProducesResponseType 特性來列出我們介面可能返回的 HTTP 狀態碼和對象信息。這裡因為是示常式序,UserListDto 並沒有定義具體的屬性信息,所以這裡顯示的是一個不包含任何屬性的對象數組。

/// <summary>
/// 獲取全部的用戶信息
/// </summary>
/// <returns></returns>
[HttpGet]
[ProducesResponseType(typeof(IEnumerable<UserListDto>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public IActionResult Get()
{
    // 1、獲取資源數據

    // 2、判斷數據獲取是否成功
    if (true)
        return Ok(new List<UserListDto>());
    else
        return BadRequest(new
        {
            statusCode = StatusCodes.Status400BadRequest,
            description = "錯誤描述",
            msg = "錯誤信息"
        });
}

  可能這裡你可能會有疑問,當介面返回的 HTTP 狀態碼為 400 時,返回的信息是什麼鬼,與我們定義的錯誤信息對象欄位不同啊?原來,在 ASP.NET Core 2.1 之後的版本中,對於 API 介面返回 400 的 HTPP 狀態碼會預設返回 ProblemDetails 對象,因為這裡我們並沒有將介面中的返回 BadRequest 中的錯誤信息對象作為 ProducesResponseType 特性的構造函數的參數,所以這裡就採用了預設的錯誤信息對象。

  當然,當介面的 HTTP 返回狀態碼為 400 時,最終還是會返回我們自定義的錯誤信息對象,所以這裡為了不造成前後端對接上的歧義,我們最好將返回的對象信息也作為參數添加到 ProducesResponseType 特性中。

  同時,除了上面示例的介面中通過返回 OK 方法和 BadRequest 方法來表明介面的返回 HTTP 狀態碼,在 ASP.NET Core Web API 中還有下列繼承於 ObjectResult 的方法來表明介面返回的狀態碼,對應信息如下。

HTTP 狀態碼方法名稱
200 OK()
201 Created()
202 Accepted()
204 NoContent()
400 BadRequest()
401 Unauthorized()
403 Forbid()
404 NotFound()

  6、使用 Web API 分析器

  在上面的示例中,因為我們需要指定介面需要返回的 HTTP 狀態碼,所以我們需要提前添加好 ProducesResponseType 特性,在某些時候我們可能在代碼中添加了一種 HTTP 狀態碼的返回結果,可是卻忘了添加特性描述,那麼有沒有一種便捷的方式提示我們呢?

  在 ASP.NET Core 2.2 及以後更新的 ASP.NET Core 版本中,我們可以通過 Nuget 去添加 Microsoft.AspNetCore.Mvc.Api.Analyze 這個包,從而實現對我們的 API 進行分析,首先我們需要將這個包添加到我們的 API 項目中。

Install-Package Microsoft.AspNetCore.Mvc.Api.Analyzers

   例如在下麵的介面代碼中,我們根據用戶的唯一標識去尋找用戶數據,當獲取不到數據的時候,返回的 HTTP 狀態碼為 400,而我們只添加了 HTTP 狀態碼為 200 的特性說明。此時,分析器將 HTTP 404 狀態代碼的缺失特性說明做為一個警告,並提供了修複此問題的選項,我們進行修複後就可以自動添加特性。

/// <summary>
/// 獲取用戶詳細信息
/// </summary>
/// <param name="id">用戶唯一標識</param>
/// <returns></returns>
[HttpGet("{id}")]
[ProducesResponseType(typeof(UserEditDto), StatusCodes.Status200OK)]
public IActionResult Get(string id)
{
    // 1、根據 Id 獲取用戶信息
    UserEditDto user = null;

    if (user == null)
        return NotFound();
    else
        return Ok(user);
}

  但是,在自動完成文檔補全後其實還是需要我們進行一些操作的,例如,如果我們需要指定返回值的 Type 類型,還是需要我們自己手動添加到 ProducesResponseType 特性上的。

  在進行特性補齊的時候,分析器也幫我們填加了一個 ProducesDefaultResponseType 特性。通過在微軟的文檔中指向的 Swagger 文檔(Swagger Default Response)中可以瞭解到,如果我們介面不管是什麼狀態,最終返回的 response 響應結構都是相同的,我們就可以直接使用 ProducesDefaultResponseType 特性來指定 response 的響應結構,而不需要每個 HTTP 狀態都添加一個特性。

 三、總結

    在本篇文章中,主要介紹了一些我在使用 ASP.NET Core Web API 的過程中使用到的一些小技巧,以及在以前踩過坑後的一些解決方案,如果對你能有一點的幫助的話,不勝榮幸。同時,如果你有更好的解決方案,或者是針對一些你之前踩過的 Web API 坑的解決方案,也歡迎你在評論區中提出。

  我的博客即將同步至騰訊雲+社區,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=1jarnly4f8ua3


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.前言 ASP.NET Core在應用程式上引入Microsoft.Extensions.Configuration配置,可以支持多種方式配置,包括命令行配置、環境變數配置、文件配置、記憶體配置,自定義配置等等。下麵我們就其中幾個配置來聊聊。 2.命令行配置 CommandLineConfigura ...
  • 這些什麼綁定都是從Borland中學來的,MVVM只是冠上新名稱而於,不是什麼新技術。依稀記得是微軟挖了Delphi一位重量級的人員後,這些東西加進了IDE。如果從數據流來講,綁定只是減輕了前臺顯示的編寫工作而於。等到你想寫更自定式的東西時,這些東西反而變成阻礙。在寫入UI的數據流中,我們想要獲取b ...
  • 現在開源項目越來越多,Git使用越來越方便,用Git的人也越來越多。創建項目的時候,喜歡把日誌,臨時文件,項目編譯的中間文件,引用的類庫等等,這時就要設置響應的規則,來忽略這些文件。例如創建一個C#項目,項目下麵會有.vs,bin,obj等,這些都是不需要提交的需要忽略的,如何忽略呢?其實很簡單,增 ...
  • 1.智能快遞櫃(開篇) 2.智能快遞櫃(終端篇) 3.智能快遞櫃(通信篇-HTTP) 4.智能快遞櫃(通信篇-SOCKET) 5.智能快遞櫃(通信篇-Server程式) 6.智能快遞櫃(平臺篇) 7.智能快遞櫃(APP及微信公眾號) 8.智能快遞櫃SDK(聯網型鎖板) 9.智能快遞櫃SDK(串口型鎖 ...
  • .net core 基於 IHostedService 實現定時任務 ...
  • 1. 前言 關於單元測試的定義和好處可以借用Stephen Cleary的一段話來概括: 單元測試是現代開發的基礎。對項目進行單元測試的好處非常容易理解:單元測試降低了 Bug 數量,縮短了上市時間,防止過度耦合的設計。這些都是很好的優勢,但它還有更多與開發人員更直接相關的優點。在我編寫單元測試時, ...
  • 動手造輪子:基於 Redis 實現 EventBus Intro 上次我們造了一個 "簡單的基於記憶體的 " ,但是如果要跨系統的話就不合適了,所以有了這篇基於 的 探索。 本文的實現是基於 來實現的。 實現 既然要實現跨系統的 再使用基於記憶體的 EventStore 自然不行,因此這裡基於 Redi ...
  • checked checked 在進行算術運算時,可以使用checked關鍵字有效地處理溢出錯誤。如果不使用 checked 關鍵字,數值出現溢出時將不會出現任何異常信息,這時將會出現一件可怕的事情,程式中的數據已經不正確,但是還沒有發現。 Byte btOne, btTow; if (byte.T ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...