主頁 > .NET開發 > 手把手教你用Abp vnext構建API介面服務

手把手教你用Abp vnext構建API介面服務

2020-09-16 07:05:44 .NET開發

ABP是一個開源應用程式框架,該專案是ASP.NET Boilerplate Web應用程式框架的下一代,專注于基于ASP.NET Core的Web應用程式開發,也支持開發控制臺應用程式,

官方網站:https://abp.io/
官方檔案:https://docs.abp.io/

一、使用ABP框架可以快速的搭建一個應用程式,僅需要幾步即可完成:

1. 安裝ABP CLI

ABP CLI是使用ABP框架啟動新解決方案的最快方法,如果沒有安裝ABP CLI,使用命令列視窗安裝ABP CLI:

dotnet tool install -g Volo.Abp.Cli

2. 在一個空檔案夾中使用abp new命令創建您的專案:

abp new Acme.BookStore

您可以使用不同級別的名稱空間,例如BookStore,Acme.BookStore或Acme.Retail.BookStore,

這樣,就已經完成了一個應用程式的搭建,

然后我們只需要修改一下其他的配置即可運行應用程式,開發人員在這個架構的基礎上就可以愉快的擼代碼了,

然而,ABP的學習才剛剛開始,ABP放棄了原有MVC的架構,使用了模塊化架構,支持微服務,根據DDD模式和原則設計和開發,為應用程式提供分層模型,對于沒有微服務開發經驗的程式員來說,學習ABP難度比較大,下面我們開始從一個空的web解決方案,一步步搭建API介面服務,

二、用APB基礎架構搭建一個用戶中心API介面服務

開發環境:Mac Visual Studio Code
SDK:dotnet core 3.1

1. 首先我們創建一個檔案夾Lemon.UserCenter,并在終端中打開該檔案夾,

使用命令創建一個空的web方案:

dotnet new web -o Lemon.UserCenter.HttpApi.Hosting

2. 再使用命令創建其他類別庫方案:

創建api層
dotnet new classlib -o Lemon.UserCenter.HttpApi
創建應用層
dotnet new classlib -o Lemon.UserCenter.Application
創建領域層
dotnet new classlib -o Lemon.UserCenter.Domain
創建基于EntityFrameworkCore的資料層
dotnet new classlib -o Lemon.UserCenter.EntityFrameworkCore

3. 把所有類別庫加入解決方案,然后類別庫間互相參考:

創建解決方案
dotnet new sln
所有類別庫加入解決方案
dotnet sln Lemon.UserCenter.sln add Lemon.UserCenter.HttpApi.Hosting/Lemon.UserCenter.HttpApi.Hosting.csproj
dotnet sln Lemon.UserCenter.sln add Lemon.UserCenter.HttpApi/Lemon.UserCenter.HttpApi.csproj
dotnet sln Lemon.UserCenter.sln add Lemon.UserCenter.Application/Lemon.UserCenter.Application.csproj
dotnet sln Lemon.UserCenter.sln add Lemon.UserCenter.Domain/Lemon.UserCenter.Domain.csproj
dotnet sln Lemon.UserCenter.sln add Lemon.UserCenter.EntityFrameworkCore/Lemon.UserCenter.EntityFrameworkCore.csproj
添加專案參考
dotnet add Lemon.UserCenter.HttpApi.Hosting/Lemon.UserCenter.HttpApi.Hosting.csproj reference Lemon.UserCenter.HttpApi/Lemon.UserCenter.HttpApi.csproj
dotnet add Lemon.UserCenter.HttpApi.Hosting/Lemon.UserCenter.HttpApi.Hosting.csproj reference Lemon.UserCenter.EntityFrameworkCore/Lemon.UserCenter.EntityFrameworkCore.csproj
dotnet add Lemon.UserCenter.HttpApi/Lemon.UserCenter.HttpApi.csproj reference Lemon.UserCenter.Application/Lemon.UserCenter.Application.csproj
dotnet add Lemon.UserCenter.Application/Lemon.UserCenter.Application.csproj reference Lemon.UserCenter.Domain/Lemon.UserCenter.Domain.csproj
dotnet add Lemon.UserCenter.EntityFrameworkCore/Lemon.UserCenter.EntityFrameworkCore.csproj reference Lemon.UserCenter.Domain/Lemon.UserCenter.Domain.csproj

4. 在領域層新增物體,

領域層添加Volo.Abp.Identity.Domain包參考:

dotnet add Lemon.UserCenter.Domain/Lemon.UserCenter.Domain.csproj package Volo.Abp.Identity.Domain

創建領域層模塊類:

using Volo.Abp.Identity;
using Volo.Abp.Modularity;

namespace Lemon.UserCenter.Domain
{
    [DependsOn(typeof(AbpIdentityDomainModule))]
    public class UserCenterDomainModule : AbpModule
    {
        
    }
}

創建物體類:

using System;
using Volo.Abp.Domain.Entities;

namespace Lemon.UserCenter.Domain
{
    public class UserData : Entity<Guid>
    {
        /// <summary>
        /// 賬號
        /// </summary>
        /// <value>The account.</value>
        public string Account { get; set; }

        /// <summary>
        /// 昵稱
        /// </summary>
        /// <value>The name of the nike.</value>
        public string NickName { get; set; } = "";

        /// <summary>
        /// 頭像
        /// </summary>
        /// <value>The head icon.</value>
        public string HeadIcon { get; set; } = "";

        /// <summary>
        /// 手機號碼
        /// </summary>
        /// <value>The mobile.</value>
        public string Mobile { get; set; } = "";

        /// <summary>
        /// 電子郵箱
        /// </summary>
        /// <value>The email.</value>
        public string Email { get; set; } = "";

        /// <summary>
        /// 洗掉注記
        /// </summary>
        /// <value><c>true</c> if deleted; otherwise, <c>false</c>.</value>
        public bool Deleted { get; set; }
    }
}

5. 創建資料層

資料層添加參考:

dotnet add Lemon.UserCenter.EntityFrameworkCore/Lemon.UserCenter.EntityFrameworkCore.csproj package Volo.Abp.EntityFrameworkCore
dotnet add Lemon.UserCenter.EntityFrameworkCore/Lemon.UserCenter.EntityFrameworkCore.csproj package Volo.Abp.EntityFrameworkCore.PostgreSQL
dotnet add Lemon.UserCenter.EntityFrameworkCore/Lemon.UserCenter.EntityFrameworkCore.csproj package Microsoft.EntityFrameworkCore.Design
dotnet add Lemon.UserCenter.EntityFrameworkCore/Lemon.UserCenter.EntityFrameworkCore.csproj package Microsoft.EntityFrameworkCore
dotnet add Lemon.UserCenter.EntityFrameworkCore/Lemon.UserCenter.EntityFrameworkCore.csproj package Microsoft.EntityFrameworkCore.Relational

在這里我們使用的是PostgreSQL資料庫,所以參考了Volo.Abp.EntityFrameworkCore.PostgreSQL,如果使用的是MySQL,就要參考Volo.Abp.EntityFrameworkCore.MySQL,如果使用的是sqlserver,就要參考Volo.Abp.EntityFrameworkCore.SQLServer,

加入UserCenterDbContext類:

using Lemon.UserCenter.Domain;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;

namespace Lemon.UserCenter.EntityFrameworkCore
{
    [ConnectionStringName("Default")]
    public class UserCenterDbContext : AbpDbContext<UserCenterDbContext>
    {
        public DbSet<UserData> UserData { get; set; }
        
        public UserCenterDbContext(DbContextOptions<UserCenterDbContext> options)
            : base(options)
        {

        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
        }

    }
}

加入UserCenterDbContextFactory類:

using System.IO;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;

namespace Lemon.UserCenter.EntityFrameworkCore
{
    public class UserCenterDbContextFactory: IDesignTimeDbContextFactory<UserCenterDbContext>
    {
        public UserCenterDbContext CreateDbContext(string[] args)
        {
            var configuration = BuildConfiguration();

            var builder = new DbContextOptionsBuilder<UserCenterDbContext>()
                .UseNpgsql(configuration.GetConnectionString("Default"));

            return new UserCenterDbContext(builder.Options);
        }

        private static IConfigurationRoot BuildConfiguration()
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false);

            return builder.Build();
        }
    }
}

加入appsettings.json配置,用于生成資料遷移代碼:

{
    "ConnectionStrings": {
      "Default": "server=127.0.0.1;port=5432;Database=abp-samples-user-center;uid=postgres;pwd=123456"
    }
}

創建資料層模塊類:

using Lemon.UserCenter.Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.PostgreSql;
using Volo.Abp.Modularity;

namespace Lemon.UserCenter.EntityFrameworkCore
{
    [DependsOn(typeof(UserCenterDomainModule),
        typeof(AbpEntityFrameworkCoreModule),
        typeof(AbpEntityFrameworkCorePostgreSqlModule))]
    public class UserCenterentityFrameworkCoreModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddAbpDbContext<UserCenterDbContext>(options => {
                options.AddDefaultRepositories(includeAllEntities: true);
            });

            Configure<AbpDbContextOptions>(options =>
            {
                options.Configure(ctx =>
                {
                    if (ctx.ExistingConnection != null)
                    {
                        ctx.DbContextOptions.UseNpgsql(ctx.ExistingConnection);
                    }
                    else
                    {
                        ctx.DbContextOptions.UseNpgsql(ctx.ConnectionString);
                    }
                });
            });

            #region 自動遷移資料庫

            context.Services.BuildServiceProvider().GetService<UserCenterDbContext>().Database.Migrate();

            #endregion 自動遷移資料庫
        }
    }
}

生成資料遷移代碼:

dotnet ef migrations add InitialCreate --project Lemon.UserCenter.EntityFrameworkCore/Lemon.UserCenter.EntityFrameworkCore.csproj

在資料層下生成一個Migrations檔案夾,里面的代碼就是資料遷移代碼,執行以下命令即可在資料庫中自動生成資料庫表:

dotnet ef database update --project Lemon.UserCenter.EntityFrameworkCore/Lemon.UserCenter.EntityFrameworkCore.csproj

6. 在應用層實作具體業務邏輯

應用層添加Volo.Abp.Identity.Application應用:

dotnet add Lemon.UserCenter.Application/Lemon.UserCenter.Application.csproj package Volo.Abp.Identity.Application

創建應用層模塊類:

using Volo.Abp.Modularity;
using Volo.Abp.Identity;

namespace Lemon.UserCenter.Application
{
    [DependsOn(typeof(AbpIdentityApplicationModule))]
    public class UserCenterApplicationModule : AbpModule
    {
        
    }
}

創建用戶介面:

using System.Threading.Tasks;
using Lemon.UserCenter.Domain;

namespace Lemon.UserCenter.Application
{
    public interface IUserService
    {
         Task<UserData> Create(UserData data);
    }
}

實作用戶服務:

using System;
using System.Threading.Tasks;
using Lemon.UserCenter.Domain;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace Lemon.UserCenter.Application
{
    public class UserService : ApplicationService, IUserService
    {
        private readonly IRepository<UserData, Guid> _repository;
        public UserService(IRepository<UserData, Guid> repository)
        {
            this._repository = repository;
        }

        public async Task<UserData> Create(UserData data)
        {
            return await _repository.InsertAsync(data);
        }
    }
}

7. 在api層實作webapi控制器

api層添加Volo.Abp.Identity.HttpApi參考:

dotnet add Lemon.UserCenter.HttpApi/Lemon.UserCenter.HttpApi.csproj package Volo.Abp.Identity.HttpApi

創建模塊類:

using Lemon.UserCenter.Application;
using Volo.Abp.Identity;
using Volo.Abp.Modularity;

namespace Lemon.UserCenter.HttpApi
{
    [DependsOn(typeof(AbpIdentityHttpApiModule),
    typeof(UserCenterApplicationModule))]
    public class UserCenterHttpApiModule : AbpModule
    {
        
    }
}

創建controller:

using System.Threading.Tasks;
using Lemon.UserCenter.Application;
using Lemon.UserCenter.Domain;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;

namespace Lemon.UserCenter.HttpApi.Controllers
{
    [Route("api/user")]
    public class UserController : AbpController
    {
        private readonly IUserService _userService;
        public UserController(IUserService userService)
        {
            this._userService = userService;
        }

        [HttpPost("create")]
        public async Task<IActionResult> Create(UserData data)
        {
            var result = await _userService.Create(data);
            return Json(result);
        }
    }
}

7. 在api hosting實作專案啟動項

添加Volo.Abp.Autofac參考:

dotnet add Lemon.UserCenter.HttpApi.Hosting/Lemon.UserCenter.HttpApi.Hosting.csproj package Volo.Abp.Autofac

創建模塊類

using Lemon.UserCenter.Domain;
using Lemon.UserCenter.EntityFrameworkCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;

namespace Lemon.UserCenter.HttpApi.Hosting
{
    [DependsOn(typeof(UserCenterHttpApiModule),
                typeof(UserCenterDomainModule),
                typeof(UserCenterentityFrameworkCoreModule),
                typeof(AbpAspNetCoreMvcModule),
                typeof(AbpAutofacModule))]
    public class UserCenterHttpApiHostingModule: AbpModule
    {
        public override void OnApplicationInitialization(
            ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            app.UseStaticFiles();
            app.UseRouting();
            app.UseMvcWithDefaultRouteAndArea();
        }
    }
}

修改Program類,新增UseAutofac:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Lemon.UserCenter.HttpApi.Hosting
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                }).UseAutofac();
    }
}

修改Startup類:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace Lemon.UserCenter.HttpApi.Hosting
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplication<UserCenterHttpApiHostingModule>();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.InitializeApplication();
        }
    }
}

8. 運行服務

cd Lemon.UserCenter.HttpApi.Hosting
dotnet watch run

9. 最后我們用postman來測驗api介面服務是否可以正常使用,

操作如下圖:

資料庫結果如下:

總結

以上就是介面服務的構建程序,主要參考了ABP CLI生成的專案結構,但是又有所不同,整個分層架構還可以繼續優化,這個就見仁見智吧,后續還會繼續分享ABP的相關知識,例如identity server 4、快取、微服務等,

GitHub: https://github.com/huangbenq/abp-samples

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/54777.html

標籤:.NET Core

上一篇:搭建私有 Nuget 服務器教程(1)

下一篇:AspNetCore3.1_Secutiry原始碼決議_1_目錄

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more