CloudYxt.Api 3.3.4

dotnet add package CloudYxt.Api --version 3.3.4
NuGet\Install-Package CloudYxt.Api -Version 3.3.4
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CloudYxt.Api" Version="3.3.4" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CloudYxt.Api --version 3.3.4
#r "nuget: CloudYxt.Api, 3.3.4"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install CloudYxt.Api as a Cake Addin
#addin nuget:?package=CloudYxt.Api&version=3.3.4

// Install CloudYxt.Api as a Cake Tool
#tool nuget:?package=CloudYxt.Api&version=3.3.4

云享通.Net Core针对WEBAPI常规操作库

跨域中间件使用

在Startup的Configure中定义

//支持所有域
app.UseMiddleware<AllowDomainCorsHeaderMiddleware>();

//支持一个域名跨域
app.UseMiddleware<AllowDomainCorsHeaderMiddleware>("https://www.domain1.com");

//支持多个域名跨域
app.UseMiddleware<AllowDomainCorsHeaderMiddleware>("https://www.domain1.com,https://www.domain2.com");

NSwag常见定义

services.AddOpenApiDocument(c =>
{
    c.Title = "WebApi";
    c.Version = "v1";
    c.Description = "WebApi说明";

    c.RequireParametersWithoutDefault = true;
    c.DocumentName = c.Title;
    c.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings() { ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver() };

    c.AddSecurity("Authorization", new NSwag.OpenApiSecurityScheme()
    {
        Description = "在下框中输入请求头中需要添加授权信息,格式:“{协议版本} {token}”(注意两者之间是一个空格)",
        Name = "Authorization",
        In = NSwag.OpenApiSecurityApiKeyLocation.Header,
        Type = NSwag.OpenApiSecuritySchemeType.ApiKey
    });

    //将控制器Summary显示为描述
    c.UseControllerSummaryAsTagDescription = true;

    //标记ApiMessageAuthorization为需授权接口
    c.OperationProcessors.Add(new ApiMessageAuthorizationNSwagProcessor("Authorization"));
});

NSwag上传文件

/// <summary>
/// 上传演示
/// </summary>
/// <param name="id">使用query参数的id</param>
/// <param name="type">使用form参数的type</param>
/// <param name="fileToUpload">文件的表单名fileToUpload,特别注意此处切勿加“[FromForm]”</param>
/// <returns></returns>
[HttpPost]
public messageData<long> PostUpload([Required][FromQuery] string id, [Required][FromForm] string type, [Required] IFormFile fileToUpload)
{
    return new messageData<long>() { data = fileToUpload.Length };
}

过滤器常见用法

在Startup中定义全局错误拦截

services.Configure<ApiBehaviorOptions>(options =>
{
    options.InvalidModelStateResponseFactory = ApiHelperExtend.ApiMessageInvalidModelState;
});

使用ApiMessageLog时,部分信息记录不到时,可在Startup的Configure中增加buffer回写

app.Use(async (ctx, next) =>
{
    ctx.Request.EnableBuffering();
    await next();
});

定义全局的Controller

[Route("Api/[controller]/[action]")]	//API路由
[ApiController]                         //声明为API控制器
[ApiMessageLog(ApiName = "Api名称")]	//API日志名称
[ApiMessagePackage]                     //使用code、message包装输出结果
public class extController : ControllerBase
{
}

演示的demo控制器,继承自extController

/// <summary>
/// 演示
/// </summary>
[OpenApiTag("demo", Description = "演示")]
public class demoController : extController
{
    /// <summary>
    /// 获取数据,并按code、message包装输出结果
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<messageData<response_class>> GetSomething()
    {
        var data = await......;

        if (something wrong) 
        {
            //抛出code、message错误信息
            throw new ApiMessageException(1, "错误提示");
        }

        return new messageData() { data = data };
    }

    /// <summary>
    /// 使用自定义包装、自定义状态码的输出
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    [ApiMessageTException]      //自定义错误message
    [ApiMessagePackageIgnore]   //不使用code、message包装
    public async Task<response_result> PostSomething([Required][FromBody] request_something request)
    {
        var data = await......;

        if (something wrong) 
        {
            //抛出402状态码的错误信息
            throw new ApiMessageTException<response_result>(类实例变量, 402);    //402状态码
        }

        return new response_result();
    }

    /// <summary>
    /// 获取当前服务器时间相对1970-1-1的毫秒数
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    [ApiMessageLogIgnore]       //忽略API日志
    [ApiMessagePackageIgnore]   //忽略使用结果包装
    public string GetMillTimer()
    {
        return $"{DateTime.Now.toMillTimer():F0}";
    }

}

ApiMessageAuthorization权限检测Filter

注意权限检测需加在方法上

权限认证成功后自动编写context.HttpContext.Items["userId"]

默认认证回调检查方法为用户自定义实现protected object mApiAuthorization(string Policy, string Roles, string AuthenticationSchemes, ActionExecutingContext context, string Scheme, string Parameter)

在WEBAPI中可通过User.Identities.FirstOrDefault(m => m.AuthenticationType == "Scheme")?.BootstrapContext获取权限检查成功的用户信息

例:

//权限验证
protected object mApiAuthorization(string Policy, string Roles, string AuthenticationSchemes, ActionExecutingContext context, string Scheme, string Parameter)
{
    //AuthenticationSchemes
    if (!string.IsNullOrEmpty(AuthenticationSchemes) && !AuthenticationSchemes.Split(',').Contains(Scheme))
        throw new ApiMessageException(4020, "不允许的权限协议", $"{Scheme} not in ({AuthenticationSchemes})");

    if (Scheme == "PRC1")
    {
        //验证用户
        var userTag = ......;
        
        return userTag;
    }
    else if (Scheme == "PRC2")
    {
        //验证用户
        var userTag = ......;
        
        return userTag;
    }

    //验证未通过则返回空
    return null;
}

//在API中获取用户信息
private ClaimsIdentity _claims;

/// <summary>
/// 获取当前用户验证的Scheme
/// </summary>
/// <returns></returns>
protected string currentUserScheme()
{
    if (_claims == null)
        _claims = User.Identities.FirstOrDefault(m => m.AuthenticationType == "Scheme");

    if (_claims == null)
        return string.Empty;

    return _claims.NameClaimType;
}

/// <summary>
/// 获取当前用户验证的用户信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
protected T currentUserTag<T>()
{
    if (_claims == null)
        _claims = User.Identities.FirstOrDefault(m => m.AuthenticationType == "Scheme");

    if (_claims == null || _claims?.BootstrapContext == null)
        return default(T);

    return (T)_claims?.BootstrapContext;
}

//支持PRC1,PRC2的权限协议,并且Roles为0才可访问
[ApiMessageAuthorization(AuthenticationSchemes = "PRC1,PRC2", Roles = "0")]
public async Task<messageData<response_class>> GetSomething() 
{
    //获取当前用户
    var userTag = currentUserTag<用户类>();
    .....
}

基于HttpContext的扩展

var ip = HttpContext.remoteRealIp(); //来源IP
var from = HttpContext.remoteFrom(); //来源URL
var agent = HttpContext.remoteAgent(); //来源AGENT
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.3.4 92 2/29/2024
3.3.1 144 7/31/2023
3.3.0 128 7/19/2023
3.2.1 134 6/29/2023
3.2.0 110 6/28/2023
3.1.1 112 5/6/2023
3.1.0 218 1/31/2023
3.0.1 400 7/25/2022
3.0.0 429 7/14/2022
2.4.8 576 1/21/2022
2.4.7 528 1/20/2022
2.4.6 555 1/20/2022
2.4.5 283 12/24/2021
2.4.4 328 12/1/2021
2.4.3 288 11/29/2021
2.4.2 373 11/12/2021
2.4.1 348 11/12/2021
2.4.0 359 11/12/2021
2.3.3 408 10/25/2021
2.3.2 408 10/20/2021
2.3.1 409 9/10/2021
2.3.0 431 9/10/2021
2.2.1 387 9/10/2021
2.2.0 365 9/9/2021
2.1.0 289 9/7/2021
2.0.0 303 9/3/2021
1.0.1 295 9/2/2021
1.0.0 299 9/2/2021

云享通.Net Core针对WEBAPI常规操作库。

3.3.4
升级NSwag.AspNetCore依赖至14.0.3,及其他细节修正

3.3.1
修正跨域支持OPTIONS响应

3.3
增加以中间件方式支持跨域头的标签

3.2.1
调整当API属性包含ApiMessageTExceptionAttribute时,返回的StatusCode状态码将保持原有400或500状态码,不会转成200正常状态码

3.2
增加ApiMessageTException<T>错误类型,可自定义出错时的Json输出类对象
throw new ApiMessageTException<messageErrorCode>(new messageErrorCode()
   {
       errcode = 10,
       errmsg = "出错啦"
   }, 501);
修复ApiMessagePackageIgnore时也会包装出错结果的BUG
修复ApiMessageLog空body的错误回收

3.1.1
升级nuget,并将ApiMessageLog类型移至CloudYxt.Base包中,以方便处理数据转储

3.1.0
取消对CloudYxt.Models的依赖

3.0.1
增加ApiMessageInfoException错误包装输出方法

3.0.0
升级包目标为.net6,增加remoteRealIp的ipv6支持

2.4.8
增加HttpContext.outputHtml、HttpContext.outputByte的ContentType类型设置

2.4.7
修复await的可返回BUG

2.4.6
增加HttpContext.outputHtml、HttpContext.outputByte用于WebApi直接输出HTML、字节数组到客户端

2.4.5
增加ApiMessagePackage支持Task控制器输出数据流的异常抛出和数据过滤包装,升级nuget版本

2.4.4
增加ApiMessageLog_Ch的入库字段名称序列

2.4.3
增加ApiMessageLog的ClickHouse类型ApiMessageLog_Ch

2.4.2
修复ApiMessagePackageIgnore属性未生效的BUG及日志记录BUG

2.4.0
同步支持CloudYxt.Base

2.3.3
修复当控制器带有动态类参数时日志未完整记录内容的BUG

2.3.2
修复BUG

2.3.1
通过ApiMessageAuthorizationAttribute认证的userId增加返回认证的Scheme

2.3.0
增加InvalidModelStateResponseFactory的ApiMessage处理方法:
services.Configure<ApiBehaviorOptions>(options =>
           {
               options.InvalidModelStateResponseFactory = ApiHelperExtend.ApiMessageInvalidModelState;
           });

注意:若要获取未验证通过的提交内容,务必EnableBuffering:
app.Use(async (ctx, next) =>
           {
               ctx.Request.EnableBuffering();
               await next();
           });

2.2.1
为ApiMessageLogAttribute增加自定义回调方法CallBackMethodName支持

2.2.0
增加权限认证属性[ApiMessageAuthorization]
权限认证成功后自动编写context.HttpContext.Items["userId"]
默认认证回调检查方法为用户自定义实现protected object mApiAuthorization(string Policy, string Roles, string AuthenticationSchemes, ActionExecutingContext context, string Scheme, string Parameter)
在WEBAPI中可通过User.Identities.FirstOrDefault(m => m.AuthenticationType == "Scheme")?.BootstrapContext获取权限检查成功的用户信息

2.1.0
增加无需日志的属性[ApiMessageLogIgnore]
调整回调日志方法mApiLog可为静态方法
context.HttpContext.Items存储的可选扩展字段名为userId、appId、custom

2.0.0
更名ApiMessage属性为ApiMessagePackage
增加ApiMessageLog,其中通用扩展属性字段可使用context.HttpContext.Items["字段名"]传递
例:(注意属性的绑定顺序)
[ApiController]
[ApiMessageLog(ApiName = "myApi")]
[ApiMessagePackage]
public class extController : ControllerBase
   {
       public void mApiLog(ApiMessageLog log)
       {
//由用户实现log的存储
       }

1.0.1
修复一个类型判断时的BUG

1.0.0:
建立基本处理模型。

[ApiMessage] :数据结果进行messageData包装
[ApiMessageException]:拦截API内报错输出为messageData模式

ApiValidationError:模型验证错误类型
services.Configure<ApiBehaviorOptions>(options =>
{
   options.InvalidModelStateResponseFactory = (context) =>
   {
       var result = context.ModelState.ToMessageResult();
       return result;
   };
});

HttpContext扩展:
remoteRealIp:来源IP
remoteFrom:来源URL
remoteAgent:来源AGENT