CloudYxt.Api
4.1.3
dotnet add package CloudYxt.Api --version 4.1.3
NuGet\Install-Package CloudYxt.Api -Version 4.1.3
<PackageReference Include="CloudYxt.Api" Version="4.1.3" />
paket add CloudYxt.Api --version 4.1.3
#r "nuget: CloudYxt.Api, 4.1.3"
// Install CloudYxt.Api as a Cake Addin #addin nuget:?package=CloudYxt.Api&version=4.1.3 // Install CloudYxt.Api as a Cake Tool #tool nuget:?package=CloudYxt.Api&version=4.1.3
云享通.Net Core针对WEBAPI常规操作库
一个常见的Startup.cs的Swagger相关定义示例
public void ConfigureServices(IServiceCollection services)
{
//使用NewtonsoftJson加载API接口
services.AddControllers().AddNewtonsoftJson((opt) =>
{
//json字符串大小写原样输出
opt.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
});
//设置接收文件长度的最大值。
services.Configure<Microsoft.AspNetCore.Http.Features.FormOptions>(x =>
{
x.ValueLengthLimit = int.MaxValue;
x.MultipartBodyLengthLimit = int.MaxValue;
x.MultipartHeadersLengthLimit = int.MaxValue;
x.MultipartBoundaryLengthLimit = int.MaxValue;
});
//全局拦截模型错误
services.Configure<ApiBehaviorOptions>(options =>
{
options.InvalidModelStateResponseFactory = ApiHelperExtend.ApiMessageInvalidModelState;
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("CloudYxtTestApi", new OpenApiInfo()
{
Title = "CloudYxtTestApi",
Version = "v2",
Description = "Api测试",
});
//类似JWT的认证模型
c.AddSecurityDefinition("Authorization", new Microsoft.OpenApi.Models.OpenApiSecurityScheme()
{
Description = "在下框中输入请求头中需要添加授权信息,格式:“{协议版本} {token}”(注意两者之间是一个空格)",
Name = "Authorization",
In = Microsoft.OpenApi.Models.ParameterLocation.Header,
Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey
});
//加载ApiMessageAuthorization认证的过滤器(当方法含有ApiMessageAuthorization时才出现锁)
c.OperationFilter<ApiMessageAuthorizationSwaggerFilter>("Authorization");
//使用DescriptionAttribute作为Description说明
c.UseDescriptionAttributeAsTagDescription();
//属性名称使用模型的完整名称
//c.CustomSchemaIds(type => type.FullName);
//仅显示属性名称
//c.SchemaFilter<PropertyOnlySchemaFilter>();
//加载目录下的xml注释文件
var xmlfiles = new DirectoryInfo(AppContext.BaseDirectory).GetFiles("*.xml");
foreach (var file in xmlfiles)
c.IncludeXmlComments(file.FullName);
});
//**重要:新版本swagger务必使用此方法校正**
services.AddSwaggerGenNewtonsoftSupport();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(async (ctx, next) =>
{
ctx.Request.EnableBuffering();
await next();
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//全局跨域支持
app.UseMiddleware<AllowDomainCorsHeaderMiddleware>();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
//使用静态文件时
//app.UseStaticFiles();
app.UseSwagger(c =>
{
c.RouteTemplate = "/{documentName}/swagger.json";
});
app.UseSwaggerUI(c =>
{
c.DocumentTitle = "测试的应用API";
c.RoutePrefix = "CloudYxtTestApi/doc";
c.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.List);
c.SwaggerEndpoint("/CloudYxtTestApi/swagger.json", "CloudYxtTestApi名称");
c.DefaultModelExpandDepth(4);
});
}
使用DescriptionAttribute作为Description说明,类似SwaggerTag功能(无需Swashbuckle.AspNetCore.Annotations依赖)
在services.AddSwaggerGen中开启
c.UseDescriptionAttributeAsTagDescription();
支持Controller、方法、模型
[Description("用于test的描述")]
public class testController : Controller
{
[HttpGet]
[Description("用于Hello的描述")]
public string Hello()
{
return "Hello World";
}
[HttpPost]
[Description("用于PostHello的描述")]
public string PostHello([FromBody]request_Hello request)
{
return $"Hello World:{request.name}";
}
}
public class request_Hello
{
/// <summary>
/// ID
/// </summary>
public string id { get; set; }
[Description("用于name的描述")]
public string name { get; set; }
}_
跨域中间件使用
在Startup的Configure中定义
//支持所有域
app.UseMiddleware<AllowDomainCorsHeaderMiddleware>();
//支持一个域名跨域
app.UseMiddleware<AllowDomainCorsHeaderMiddleware>("https://www.domain1.com");
//支持多个域名跨域
app.UseMiddleware<AllowDomainCorsHeaderMiddleware>("https://www.domain1.com,https://www.domain2.com");
上传文件
/// <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
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"));
});
Product | Versions 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. |
-
net6.0
- CloudYxt.Base (>= 1.0.1)
- Newtonsoft.Json (>= 13.0.3)
- Swashbuckle.AspNetCore (>= 7.0.0)
- Swashbuckle.AspNetCore.Newtonsoft (>= 7.0.0)
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 |
---|---|---|
4.1.3 | 85 | 11/14/2024 |
4.1.2 | 79 | 11/13/2024 |
4.1.1 | 80 | 10/21/2024 |
4.0.3 | 123 | 5/17/2024 |
4.0.1 | 121 | 5/16/2024 |
4.0.0 | 100 | 5/15/2024 |
3.3.4 | 128 | 2/29/2024 |
3.3.1 | 180 | 7/31/2023 |
3.3.0 | 155 | 7/19/2023 |
3.2.1 | 160 | 6/29/2023 |
3.2.0 | 146 | 6/28/2023 |
3.1.1 | 143 | 5/6/2023 |
3.1.0 | 247 | 1/31/2023 |
3.0.1 | 432 | 7/25/2022 |
3.0.0 | 463 | 7/14/2022 |
2.4.8 | 610 | 1/21/2022 |
2.4.7 | 561 | 1/20/2022 |
2.4.6 | 581 | 1/20/2022 |
2.4.5 | 323 | 12/24/2021 |
2.4.4 | 363 | 12/1/2021 |
2.4.3 | 314 | 11/29/2021 |
2.4.2 | 399 | 11/12/2021 |
2.4.1 | 385 | 11/12/2021 |
2.4.0 | 387 | 11/12/2021 |
2.3.3 | 443 | 10/25/2021 |
2.3.2 | 442 | 10/20/2021 |
2.3.1 | 434 | 9/10/2021 |
2.3.0 | 464 | 9/10/2021 |
2.2.1 | 414 | 9/10/2021 |
2.2.0 | 394 | 9/9/2021 |
2.1.0 | 322 | 9/7/2021 |
2.0.0 | 331 | 9/3/2021 |
1.0.1 | 310 | 9/2/2021 |
1.0.0 | 332 | 9/2/2021 |
云享通.Net Core针对WEBAPI常规操作库。
4.1.3
日志记录细节修复
4.1.2
升级Swashbuckle.AspNetCore依赖至7.0
4.1.1
增加依赖Swashbuckle.AspNetCore.Newtonsoft适配Newtonsoft
新增PropertyOnlySchemaFilter可设置基本Gen时只显示类型名称,特别注意需要在services.AddSwaggerGen后添加services.AddSwaggerGenNewtonsoftSupport();
4.0.3
为Swashbuckle.AspNetCore增加[Description("描述")]支持
4.0.1
升级Swashbuckle.AspNetCore依赖至6.6.1
4.0.0
由于NSwag在打包WebApi为单个文件时无法加载xml文件,并且无法指定外部swagger.json,因此将Swagger引擎改为Swashbuckle.AspNetCore
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