Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cbd8b7559 | ||
|
|
d54b71badb | ||
|
|
ddeb2948b7 | ||
|
|
fb1ce7d931 | ||
|
|
c117d9ef1f | ||
|
|
9b38ee9b39 | ||
|
|
116dd1a808 | ||
|
|
26753657b8 | ||
|
|
62ffe47d25 | ||
|
|
bb2f4641a3 | ||
|
|
aadc4128f0 | ||
|
|
a8ce74f35d | ||
|
|
44ed8dfd3c | ||
|
|
a7261fde58 | ||
|
|
453a15b9ad | ||
|
|
5a04f831a7 | ||
|
|
fdfde570c7 | ||
|
|
874f5b6cef | ||
|
|
86ec43f676 | ||
|
|
66334d6535 |
@@ -0,0 +1,34 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on: [create]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build Project
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Setup .NET Core
|
||||||
|
uses: actions/setup-dotnet@v1
|
||||||
|
with:
|
||||||
|
dotnet-version: '3.1.101'
|
||||||
|
- name: Build
|
||||||
|
run: dotnet build
|
||||||
|
|
||||||
|
publish:
|
||||||
|
needs: build
|
||||||
|
name: Publish Project to Nuget
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Setup .NET Core
|
||||||
|
uses: actions/setup-dotnet@v1
|
||||||
|
with:
|
||||||
|
dotnet-version: '3.1.101'
|
||||||
|
- name: Publish
|
||||||
|
run: |
|
||||||
|
version=`git describe --tags`
|
||||||
|
dotnet pack --configuration release -p:PackageVersion=$version
|
||||||
|
dotnet nuget push bin/release/YY-Tech.YYApi.$version.nupkg -k ${APIKEY} -s https://www.nuget.org/api/v2/package
|
||||||
|
env:
|
||||||
|
APIKEY: ${{ secrets.APPKEY }}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
name: PublishToNuget
|
|
||||||
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: publish to nuget
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
fetch-depth: 2
|
|
||||||
- name: Publish NuGet
|
|
||||||
uses: rohith/publish-nuget@v1.0.3
|
|
||||||
with:
|
|
||||||
nuget_key: ${{ secrets.NugetKey }}
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using YYApi.Communications;
|
||||||
|
using YYApi.Exceptions;
|
||||||
|
|
||||||
|
namespace YYApi.Attributes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 检测登录中间件
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||||
|
public class YYAuthAttribute : ActionFilterAttribute
|
||||||
|
{
|
||||||
|
private string[] Types { get; }
|
||||||
|
|
||||||
|
//默认是user登录类型
|
||||||
|
public YYAuthAttribute()
|
||||||
|
{
|
||||||
|
Types = new[] { "user" };
|
||||||
|
}
|
||||||
|
|
||||||
|
//只检测一种用户类型的快捷方式
|
||||||
|
public YYAuthAttribute(string type)
|
||||||
|
{
|
||||||
|
Types = new[] { type };
|
||||||
|
}
|
||||||
|
|
||||||
|
//设定特定类型的检测
|
||||||
|
public YYAuthAttribute(string[] types)
|
||||||
|
{
|
||||||
|
Types = types;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnActionExecuting(ActionExecutingContext context)
|
||||||
|
{
|
||||||
|
var loginInfo = (YYLoginItem)context.HttpContext.Items["LoginInfo"];
|
||||||
|
//检测是否登录
|
||||||
|
if (loginInfo == null)
|
||||||
|
{
|
||||||
|
throw new YYApiException(401);
|
||||||
|
}
|
||||||
|
//检测用户类型
|
||||||
|
if (Types.Intersect(loginInfo.Type).Count() == 0)
|
||||||
|
{
|
||||||
|
throw new YYApiException(403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,22 @@
|
|||||||
using Swashbuckle.AspNetCore.Annotations;
|
using System;
|
||||||
|
using Swashbuckle.AspNetCore.Annotations;
|
||||||
|
|
||||||
namespace YYApi.Helpers
|
namespace YYApi.Attributes
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 快捷自定义接口文档类
|
/// 快捷自定义接口文档类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ApiDoc : SwaggerOperationAttribute
|
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
|
||||||
|
public class YYDocAttribute : SwaggerOperationAttribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 定义接口说明
|
/// 定义接口说明
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tag">接口分组</param>
|
/// <param name="tag">接口分组</param>
|
||||||
/// <param name="name">接口名称</param>
|
/// <param name="name">接口名称</param>
|
||||||
public ApiDoc(string tag, string name)
|
public YYDocAttribute(string tag, string name)
|
||||||
{
|
{
|
||||||
Tags = new[] {tag};
|
Tags = new[] { tag };
|
||||||
Summary = name;
|
Summary = name;
|
||||||
// Consumes = new[] {"application/json"};
|
// Consumes = new[] {"application/json"};
|
||||||
// Produces = new[] {"application/json"};
|
// Produces = new[] {"application/json"};
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
namespace YYApi.Communications
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 只有ID的请求
|
||||||
|
/// </summary>
|
||||||
|
public class YYIdOnlyRequest
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 基础分页请求
|
||||||
|
/// </summary>
|
||||||
|
public class YYBasePageRequest
|
||||||
|
{
|
||||||
|
public int Page { get; set; }
|
||||||
|
public int Count { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ namespace YYApi.Communications
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 基础相应
|
/// 基础相应
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BaseResponse
|
public class YYBaseResponse
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 错误代码
|
/// 错误代码
|
||||||
@@ -36,7 +36,7 @@ namespace YYApi.Communications
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回一个成功的空结果
|
/// 返回一个成功的空结果
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BaseResponse()
|
public YYBaseResponse()
|
||||||
{
|
{
|
||||||
SetCode(200);
|
SetCode(200);
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ namespace YYApi.Communications
|
|||||||
/// 返回指定代码的描述
|
/// 返回指定代码的描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="code">错误代码</param>
|
/// <param name="code">错误代码</param>
|
||||||
public BaseResponse(int code)
|
public YYBaseResponse(int code)
|
||||||
{
|
{
|
||||||
SetCode(code);
|
SetCode(code);
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ namespace YYApi.Communications
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="code">错误代码</param>
|
/// <param name="code">错误代码</param>
|
||||||
/// <param name="message">错误信息</param>
|
/// <param name="message">错误信息</param>
|
||||||
public BaseResponse(int code, string message)
|
public YYBaseResponse(int code, string message)
|
||||||
{
|
{
|
||||||
SetCodeMsg(code, message);
|
SetCodeMsg(code, message);
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ namespace YYApi.Communications
|
|||||||
/// 动态内容分页
|
/// 动态内容分页
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public class BasePageResponse<T> : BaseResponse
|
public class YYBasePageResponse<T> : YYBaseResponse
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 动态内容列表
|
/// 动态内容列表
|
||||||
@@ -122,7 +122,7 @@ namespace YYApi.Communications
|
|||||||
/// 动态Data返回
|
/// 动态Data返回
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public class BaseResponse<T> : BaseResponse
|
public class YYBaseResponse<T> : YYBaseResponse
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 动态内容列表
|
/// 动态内容列表
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
namespace YYApi.Communications
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 登录信息中间件
|
||||||
|
/// </summary>
|
||||||
|
public class YYLoginItem
|
||||||
|
{
|
||||||
|
//登录用户的ID
|
||||||
|
public int Id { get; set; }
|
||||||
|
//登录用户来源
|
||||||
|
public string[] Type { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using YYApi.Communications;
|
using YYApi.Communications;
|
||||||
using YYApi.Helpers;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using YYApi.Exceptions;
|
||||||
|
|
||||||
namespace YYApi.Controllers
|
namespace YYApi.Controllers
|
||||||
{
|
{
|
||||||
@@ -13,12 +13,12 @@ namespace YYApi.Controllers
|
|||||||
/// 2. 报错返回
|
/// 2. 报错返回
|
||||||
/// 3. 错误回馈页面
|
/// 3. 错误回馈页面
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BaseController : Controller
|
public class YYBaseController : Controller
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前登录用户的ID
|
/// 当前登录用户的ID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected LoginInfoItem LoginInfo => (LoginInfoItem)HttpContext.Items["LoginInfo"];
|
protected YYLoginItem LoginInfo => (YYLoginItem)HttpContext.Items["LoginInfo"];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 验证请求参数
|
/// 验证请求参数
|
||||||
@@ -46,9 +46,9 @@ namespace YYApi.Controllers
|
|||||||
/// <param name="code">错误代码</param>
|
/// <param name="code">错误代码</param>
|
||||||
/// <param name="message">错误描述(若是常规错误,代码可自动带取描述)</param>
|
/// <param name="message">错误描述(若是常规错误,代码可自动带取描述)</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected static void Error(int code, string message = null)
|
protected static void Error(int code = 500, string message = "")
|
||||||
{
|
{
|
||||||
throw new ApiException(code, message);
|
throw new YYApiException(code, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -57,7 +57,7 @@ namespace YYApi.Controllers
|
|||||||
/// <param name="condition">检测条件</param>
|
/// <param name="condition">检测条件</param>
|
||||||
/// <param name="code">错误代码</param>
|
/// <param name="code">错误代码</param>
|
||||||
/// <param name="message">错误描述</param>
|
/// <param name="message">错误描述</param>
|
||||||
protected static void ErrorWhen(bool condition, int code, string message = null)
|
protected static void ErrorWhen(bool condition, int code = 500, string message = "")
|
||||||
{
|
{
|
||||||
if (condition)
|
if (condition)
|
||||||
{
|
{
|
||||||
@@ -71,7 +71,7 @@ namespace YYApi.Controllers
|
|||||||
/// <param name="condition">检测条件</param>
|
/// <param name="condition">检测条件</param>
|
||||||
/// <param name="code">错误代码</param>
|
/// <param name="code">错误代码</param>
|
||||||
/// <param name="message">错误描述</param>
|
/// <param name="message">错误描述</param>
|
||||||
protected static void ErrorWhenNull(object condition, int code, string message = null)
|
protected static void ErrorWhenNull(object condition, int code = 404, string message = "请求的资源不存在")
|
||||||
{
|
{
|
||||||
ErrorWhen(condition == null, code, message);
|
ErrorWhen(condition == null, code, message);
|
||||||
}
|
}
|
||||||
@@ -83,16 +83,16 @@ namespace YYApi.Controllers
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("exception/{code:int}")]
|
[HttpGet("exception/{code:int}")]
|
||||||
[ApiExplorerSettings(IgnoreApi = true)]
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public BaseResponse ExceptionHandler(int code)
|
public YYBaseResponse ExceptionHandler(int code)
|
||||||
{
|
{
|
||||||
var response = new BaseResponse();
|
var response = new YYBaseResponse();
|
||||||
response.SetCode(code);
|
response.SetCode(code);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BaseResponse<string> UploadFile()
|
protected YYBaseResponse<string> UploadFile()
|
||||||
{
|
{
|
||||||
return new BaseResponse<string>();
|
return new YYBaseResponse<string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
namespace YYApi.Exceptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Api错误捕获异常
|
||||||
|
/// </summary>
|
||||||
|
public class YYApiException : Exception
|
||||||
|
{
|
||||||
|
public int Code { get; }
|
||||||
|
|
||||||
|
public YYApiException(int code, string message = "") : base(message)
|
||||||
|
{
|
||||||
|
Code = code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+64
-31
@@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Builder;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using Swashbuckle.AspNetCore.SwaggerUI;
|
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||||
|
using YYApi.Middlewares;
|
||||||
|
|
||||||
namespace YYApi
|
namespace YYApi
|
||||||
{
|
{
|
||||||
@@ -12,18 +13,10 @@ namespace YYApi
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
//**********快捷添加**************
|
||||||
/// 添加自定义授权认证中间价
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IServiceCollection AddAuth(this IServiceCollection builder)
|
|
||||||
{
|
|
||||||
return builder.AddScoped<Auth>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加整个YYAPI
|
/// 添加整个YYAPI,同时增加CORS规则
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="builder"></param>
|
/// <param name="builder"></param>
|
||||||
/// <param name="title"></param>
|
/// <param name="title"></param>
|
||||||
@@ -32,7 +25,44 @@ namespace YYApi
|
|||||||
public static IServiceCollection AddYYApi(this IServiceCollection builder, string title,
|
public static IServiceCollection AddYYApi(this IServiceCollection builder, string title,
|
||||||
string description = null)
|
string description = null)
|
||||||
{
|
{
|
||||||
return builder.AddAuth().AddApiDoc(title, description);
|
return builder.AddYYAuth().AddYYDoc(title, description).AddCors().AddYYUpload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用所有YYApi自定义中间件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder"></param>
|
||||||
|
/// <param name="title"></param>
|
||||||
|
/// <param name="staticFileroot"></param>
|
||||||
|
/// <param name="submitMethods"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IApplicationBuilder UseYYApi(this IApplicationBuilder builder, string title = "API文档", params SubmitMethod[] submitMethods)
|
||||||
|
{
|
||||||
|
return builder.UseYYException().UseYYDoc(title, submitMethods).UseMiddleware<YYAuthMiddleware>().UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()).UseYYUpload();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//*********组件快捷方式*************
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加自定义授权认证中间价
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IServiceCollection AddYYAuth(this IServiceCollection builder)
|
||||||
|
{
|
||||||
|
return builder.AddScoped<YYAuth>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加Base64上传组件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IServiceCollection AddYYUpload(this IServiceCollection builder)
|
||||||
|
{
|
||||||
|
return builder.AddSingleton<YYUpload>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -42,7 +72,7 @@ namespace YYApi
|
|||||||
/// <param name="title">文档标题</param>
|
/// <param name="title">文档标题</param>
|
||||||
/// <param name="description">文档描述</param>
|
/// <param name="description">文档描述</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IServiceCollection AddApiDoc(this IServiceCollection builder, string title,
|
public static IServiceCollection AddYYDoc(this IServiceCollection builder, string title,
|
||||||
string description = null)
|
string description = null)
|
||||||
{
|
{
|
||||||
return builder.AddSwaggerGen(x =>
|
return builder.AddSwaggerGen(x =>
|
||||||
@@ -70,9 +100,23 @@ namespace YYApi
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="builder"></param>
|
/// <param name="builder"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IApplicationBuilder UseExceptionMiddleware(this IApplicationBuilder builder)
|
public static IApplicationBuilder UseYYException(this IApplicationBuilder builder)
|
||||||
{
|
{
|
||||||
return builder.UseMiddleware<ExceptionMiddleware>();
|
return builder.UseMiddleware<YYExceptionMiddleware>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置上传组件必须
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IApplicationBuilder UseYYUpload(this IApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
return builder.UseStaticFiles(new StaticFileOptions
|
||||||
|
{
|
||||||
|
DefaultContentType = "application/x-msdownload",
|
||||||
|
ServeUnknownFileTypes = true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -82,7 +126,7 @@ namespace YYApi
|
|||||||
/// <param name="title">文档标题</param>
|
/// <param name="title">文档标题</param>
|
||||||
/// <param name="submitMethods">文档支持的提交方式(如果不指定,默认使用POST)</param>
|
/// <param name="submitMethods">文档支持的提交方式(如果不指定,默认使用POST)</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IApplicationBuilder UseApiDoc(this IApplicationBuilder builder, string title,
|
public static IApplicationBuilder UseYYDoc(this IApplicationBuilder builder, string title,
|
||||||
params SubmitMethod[] submitMethods)
|
params SubmitMethod[] submitMethods)
|
||||||
{
|
{
|
||||||
return builder.UseSwagger(x => x.RouteTemplate = "docs/{documentName}.json").UseSwaggerUI(x =>
|
return builder.UseSwagger(x => x.RouteTemplate = "docs/{documentName}.json").UseSwaggerUI(x =>
|
||||||
@@ -112,10 +156,10 @@ namespace YYApi
|
|||||||
/// <param name="title">文档标题</param>
|
/// <param name="title">文档标题</param>
|
||||||
/// <param name="submitMethods">API提交方式定义</param>
|
/// <param name="submitMethods">API提交方式定义</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IApplicationBuilder UseDocAndException(this IApplicationBuilder builder, string title = "API文档",
|
public static IApplicationBuilder UseYYDocEx(this IApplicationBuilder builder, string title = "API文档",
|
||||||
params SubmitMethod[] submitMethods)
|
params SubmitMethod[] submitMethods)
|
||||||
{
|
{
|
||||||
return builder.UseExceptionMiddleware().UseApiDoc(title, submitMethods);
|
return builder.UseYYException().UseYYDoc(title, submitMethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -123,22 +167,11 @@ namespace YYApi
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="builder"></param>
|
/// <param name="builder"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IApplicationBuilder UseAuthMiddleware(this IApplicationBuilder builder)
|
public static IApplicationBuilder UseYYAuth(this IApplicationBuilder builder)
|
||||||
{
|
{
|
||||||
return builder.UseMiddleware<AuthMiddleware>();
|
return builder.UseMiddleware<YYAuthMiddleware>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 使用所有YYApi自定义中间件
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder"></param>
|
|
||||||
/// <param name="title"></param>
|
|
||||||
/// <param name="submitMethods"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IApplicationBuilder UseYYApiMiddleware(this IApplicationBuilder builder, string title = "API文档",
|
|
||||||
params SubmitMethod[] submitMethods)
|
|
||||||
{
|
|
||||||
return builder.UseExceptionMiddleware().UseApiDoc(title, submitMethods).UseMiddleware<AuthMiddleware>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
|
||||||
using Microsoft.Extensions.Caching.Distributed;
|
|
||||||
|
|
||||||
namespace YYApi.Helpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 认证信息获取中间件
|
|
||||||
/// </summary>
|
|
||||||
public class AuthMiddleware
|
|
||||||
{
|
|
||||||
private RequestDelegate Next { get; }
|
|
||||||
|
|
||||||
public AuthMiddleware(RequestDelegate next)
|
|
||||||
{
|
|
||||||
Next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task Invoke(HttpContext httpContext, IDistributedCache cache)
|
|
||||||
{
|
|
||||||
string token = null;
|
|
||||||
if (httpContext.Request.Headers.ContainsKey("Token"))
|
|
||||||
{
|
|
||||||
token = httpContext.Request.Headers["Token"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(token))
|
|
||||||
{
|
|
||||||
var login = cache.GetString(token);
|
|
||||||
if (login != null)
|
|
||||||
{
|
|
||||||
httpContext.Items.Add("LoginInfo", JsonSerializer.Deserialize<LoginInfoItem>(login));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Next(httpContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 登录信息中间件
|
|
||||||
/// </summary>
|
|
||||||
public class LoginInfoItem
|
|
||||||
{
|
|
||||||
//登录用户的ID
|
|
||||||
public int Id { get; set; }
|
|
||||||
//登录用户来源
|
|
||||||
public string Type { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检测登录中间件
|
|
||||||
/// </summary>
|
|
||||||
public class CheckAuthAttribute : ActionFilterAttribute
|
|
||||||
{
|
|
||||||
private string[] Types { get; }
|
|
||||||
|
|
||||||
//默认是user登录类型
|
|
||||||
public CheckAuthAttribute()
|
|
||||||
{
|
|
||||||
Types = new[] { "user" };
|
|
||||||
}
|
|
||||||
|
|
||||||
//只检测一种用户类型的快捷方式
|
|
||||||
public CheckAuthAttribute(string type)
|
|
||||||
{
|
|
||||||
Types = new[] { type };
|
|
||||||
}
|
|
||||||
|
|
||||||
//设定特定类型的检测
|
|
||||||
public CheckAuthAttribute(string[] types)
|
|
||||||
{
|
|
||||||
Types = types;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnActionExecuting(ActionExecutingContext context)
|
|
||||||
{
|
|
||||||
var loginInfo = (LoginInfoItem)context.HttpContext.Items["LoginInfo"];
|
|
||||||
//检测是否登录
|
|
||||||
if (loginInfo == null)
|
|
||||||
{
|
|
||||||
throw new ApiException(401);
|
|
||||||
}
|
|
||||||
//检测用户类型
|
|
||||||
if (!Types.Contains(loginInfo.Type))
|
|
||||||
{
|
|
||||||
throw new ApiException(403);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 认证助手
|
|
||||||
/// </summary>
|
|
||||||
public class Auth
|
|
||||||
{
|
|
||||||
private IDistributedCache Cache { get; }
|
|
||||||
|
|
||||||
public Auth(IDistributedCache cache)
|
|
||||||
{
|
|
||||||
Cache = cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 产生一个Token记录并返回Token
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public string Set(int id, string type = "user")
|
|
||||||
{
|
|
||||||
var uuid = GetUUID();
|
|
||||||
var loginItem = new LoginInfoItem
|
|
||||||
{
|
|
||||||
Id = id,
|
|
||||||
Type = type
|
|
||||||
};
|
|
||||||
Cache.SetString(uuid, JsonSerializer.Serialize(loginItem));
|
|
||||||
return uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetUUID()
|
|
||||||
{
|
|
||||||
return Guid.NewGuid().ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Caching.Distributed;
|
||||||
|
using YYApi.Communications;
|
||||||
|
|
||||||
|
namespace YYApi.Helpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 认证助手
|
||||||
|
/// </summary>
|
||||||
|
public class YYAuth
|
||||||
|
{
|
||||||
|
private IDistributedCache Cache { get; }
|
||||||
|
|
||||||
|
public YYAuth(IDistributedCache cache)
|
||||||
|
{
|
||||||
|
Cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 产生一个Token记录并返回Token
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string Login(int id, string type = "user", string token = null)
|
||||||
|
{
|
||||||
|
return Login(id, new[] { type }, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 产生一个Token并记录用户ID角色[多角色]
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string Login(int id, string[] type, string uuid = null)
|
||||||
|
{
|
||||||
|
if (uuid == null)
|
||||||
|
{
|
||||||
|
uuid = Guid.NewGuid().ToString();
|
||||||
|
}
|
||||||
|
var loginItem = new YYLoginItem
|
||||||
|
{
|
||||||
|
Id = id,
|
||||||
|
Type = type
|
||||||
|
};
|
||||||
|
Cache.SetString(uuid, JsonSerializer.Serialize(loginItem));
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 退出登陆
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uuid">登陆标识</param>
|
||||||
|
public void Logout(string uuid)
|
||||||
|
{
|
||||||
|
Cache.Remove(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
|
||||||
|
namespace YYApi.Helpers
|
||||||
|
{
|
||||||
|
public class YYUpload
|
||||||
|
{
|
||||||
|
private string FilePathFolder = "/uploads/";
|
||||||
|
public string FilePath
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!value.StartsWith("/"))
|
||||||
|
{
|
||||||
|
FilePathFolder = $"/{value}";
|
||||||
|
}
|
||||||
|
if (!FilePathFolder.EndsWith("/"))
|
||||||
|
{
|
||||||
|
FilePathFolder += "/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return FilePathFolder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IWebHostEnvironment Env { get; }
|
||||||
|
|
||||||
|
public YYUpload(IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
Env = env;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class YYUploadInfo
|
||||||
|
{
|
||||||
|
public string Path { get; set; }
|
||||||
|
public int Size { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存base64文件,如果有标头按照标头自动识别
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="base64"></param>
|
||||||
|
/// <param name="ext">扩展名</param>
|
||||||
|
/// <param name="path">存放路径</param>
|
||||||
|
/// <param name="fileName">文件名</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public YYUploadInfo SaveFile(string base64, string ext = null, string path = null, string fileName = null)
|
||||||
|
{
|
||||||
|
byte[] bt;
|
||||||
|
var filePath = FilePath + path;
|
||||||
|
if (fileName == null)
|
||||||
|
{
|
||||||
|
fileName = Guid.NewGuid().ToString();
|
||||||
|
}
|
||||||
|
var baseArr = base64.Split(";");
|
||||||
|
if (baseArr.Length == 2)
|
||||||
|
{
|
||||||
|
var info = baseArr[0].Split(":")[1].Split("/");
|
||||||
|
if (path == null)
|
||||||
|
{
|
||||||
|
filePath += $"{info[0]}/";
|
||||||
|
}
|
||||||
|
if (ext == null)
|
||||||
|
{
|
||||||
|
ext = info[1];
|
||||||
|
}
|
||||||
|
var data = baseArr[1].Split(",");
|
||||||
|
bt = Convert.FromBase64String(data[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bt = Convert.FromBase64String(base64);
|
||||||
|
}
|
||||||
|
var fn = fileName + (string.IsNullOrEmpty(ext) ? string.Empty : $".{ext}");
|
||||||
|
return WriteFile(filePath, fn, bt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把数据写入文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath"></param>
|
||||||
|
/// <param name="fileName"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public YYUploadInfo WriteFile(string filePath, string fileName, byte[] data)
|
||||||
|
{
|
||||||
|
var realPath = Directory.GetCurrentDirectory() + "/wwwroot" + filePath;
|
||||||
|
if (!Directory.Exists(realPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(realPath);
|
||||||
|
}
|
||||||
|
File.WriteAllBytes(realPath + fileName, data);
|
||||||
|
return new YYUploadInfo
|
||||||
|
{
|
||||||
|
Path = filePath + fileName,
|
||||||
|
Size = data.Length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ using System.Text.RegularExpressions;
|
|||||||
|
|
||||||
namespace YYApi.Helpers
|
namespace YYApi.Helpers
|
||||||
{
|
{
|
||||||
public static class Util
|
public static class YYUtil
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 检测手机号是否正确
|
/// 检测手机号是否正确
|
||||||
@@ -20,11 +20,11 @@ namespace YYApi.JobService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// HangFire Dashboard Digest认证.
|
/// HangFire Dashboard Digest认证.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class HFDashboardAuth : IDashboardAuthorizationFilter
|
public class YYHFDashboardAuth : IDashboardAuthorizationFilter
|
||||||
{
|
{
|
||||||
private IConfiguration _config { get; }
|
private IConfiguration _config { get; }
|
||||||
private IDatabase _redis { get; }
|
private IDatabase _redis { get; }
|
||||||
public HFDashboardAuth(IConfiguration config, IDatabase redis)
|
public YYHFDashboardAuth(IConfiguration config, IDatabase redis)
|
||||||
{
|
{
|
||||||
_redis = redis;
|
_redis = redis;
|
||||||
_config = config;
|
_config = config;
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Caching.Distributed;
|
||||||
|
using YYApi.Communications;
|
||||||
|
|
||||||
|
namespace YYApi.Middlewares
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 认证信息获取中间件
|
||||||
|
/// </summary>
|
||||||
|
public class YYAuthMiddleware
|
||||||
|
{
|
||||||
|
private RequestDelegate Next { get; }
|
||||||
|
|
||||||
|
public YYAuthMiddleware(RequestDelegate next)
|
||||||
|
{
|
||||||
|
Next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Invoke(HttpContext httpContext, IDistributedCache cache)
|
||||||
|
{
|
||||||
|
string token = null;
|
||||||
|
if (httpContext.Request.Headers.ContainsKey("Token"))
|
||||||
|
{
|
||||||
|
token = httpContext.Request.Headers["Token"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(token))
|
||||||
|
{
|
||||||
|
var login = cache.GetString(token);
|
||||||
|
if (login != null)
|
||||||
|
{
|
||||||
|
httpContext.Items.Add("LoginInfo", JsonSerializer.Deserialize<YYLoginItem>(login));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Next(httpContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,20 +2,20 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using YYApi.Communications;
|
using YYApi.Communications;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using YYApi.Exceptions;
|
||||||
|
|
||||||
namespace YYApi.Helpers
|
namespace YYApi.Middlewares
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异常处理中间件
|
/// 异常处理中间件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ExceptionMiddleware
|
public class YYExceptionMiddleware
|
||||||
{
|
{
|
||||||
private RequestDelegate Next { get; }
|
private RequestDelegate Next { get; }
|
||||||
private ILogger<ExceptionMiddleware> Log { get; }
|
private ILogger<YYExceptionMiddleware> Log { get; }
|
||||||
|
|
||||||
public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> log)
|
public YYExceptionMiddleware(RequestDelegate next, ILogger<YYExceptionMiddleware> log)
|
||||||
{
|
{
|
||||||
Log = log;
|
Log = log;
|
||||||
Next = next;
|
Next = next;
|
||||||
@@ -23,12 +23,12 @@ namespace YYApi.Helpers
|
|||||||
|
|
||||||
public async Task InvokeAsync(HttpContext context)
|
public async Task InvokeAsync(HttpContext context)
|
||||||
{
|
{
|
||||||
var response = new BaseResponse();
|
var response = new YYBaseResponse();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Next(context);
|
await Next(context);
|
||||||
}
|
}
|
||||||
catch (ApiException ex)
|
catch (YYApiException ex)
|
||||||
{
|
{
|
||||||
response.SetCodeMsg(ex.Code, ex.Message);
|
response.SetCodeMsg(ex.Code, ex.Message);
|
||||||
ErrorResponse(context, response);
|
ErrorResponse(context, response);
|
||||||
@@ -47,25 +47,11 @@ namespace YYApi.Helpers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context"></param>
|
/// <param name="context"></param>
|
||||||
/// <param name="response"></param>
|
/// <param name="response"></param>
|
||||||
private void ErrorResponse(HttpContext context, BaseResponse response)
|
private void ErrorResponse(HttpContext context, YYBaseResponse response)
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = 200;
|
context.Response.StatusCode = 200;
|
||||||
context.Response.Headers.Add("Content-Type", "application/json");
|
context.Response.Headers.Add("Content-Type", "application/json");
|
||||||
context.Response.WriteAsync(response.ToString());
|
context.Response.WriteAsync(response.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Api错误捕获异常
|
|
||||||
/// </summary>
|
|
||||||
public class ApiException : Exception
|
|
||||||
{
|
|
||||||
public int Code { get; }
|
|
||||||
|
|
||||||
public ApiException(int code, string message = "") : base(message)
|
|
||||||
{
|
|
||||||
Code = code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
# YYApi 基于Asp.net Core 3的一个基础辅助包
|
# YYApi 基于Asp.net Core 3的一个基础辅助包
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
### 包含了以下组件:
|
### 包含了以下组件:
|
||||||
|
|
||||||
1. 统一的参数检测,基础认证服务
|
1. 统一的参数检测,基础认证服务
|
||||||
@@ -25,28 +27,28 @@ namespace Controllers
|
|||||||
```C#
|
```C#
|
||||||
#Startup.cs
|
#Startup.cs
|
||||||
|
|
||||||
services.AddApiDoc("文档名称", "文档描述");
|
services.AddYYDoc("文档名称", "文档描述");
|
||||||
|
|
||||||
app.UseApiDoc("名称",SubmitMethod[])
|
app.UseYYDoc("名称",SubmitMethod[])
|
||||||
|
|
||||||
#控制器中可以直接使用特性
|
#控制器中可以直接使用特性
|
||||||
|
|
||||||
[ApiDoc("分组","名称")]
|
[YYDoc("分组","名称")]
|
||||||
```
|
```
|
||||||
|
|
||||||
3. 简单的基于Redis的登录TOKEN服务
|
3. 简单的基于Redis的登录TOKEN服务
|
||||||
|
|
||||||
```C#
|
```C#
|
||||||
#Startup.cs
|
#Startup.cs
|
||||||
service.AddAuth();
|
service.AddYYAuth();
|
||||||
```
|
```
|
||||||
添加时候, 可以从DI中获取 Auth 类,调用 Auth.Set(int,string) 将用户ID/类型和生成的Token绑定,本方法返回缓存中的Key名称
|
添加时候, 可以从DI中获取 Auth 类,调用 Auth.Set(int,string) 将用户ID/类型和生成的Token绑定,本方法返回缓存中的Key名称
|
||||||
|
|
||||||
```C#
|
```C#
|
||||||
#Startup.cs
|
#Startup.cs
|
||||||
app.UseAuthMiddleware();
|
app.UseYYAuth();
|
||||||
```
|
```
|
||||||
调用本中间件,然后再需要登录认证的地方,使用 [CheckAuth] 特性,即可完成检测登录相关的操作,
|
调用本中间件,然后再需要登录认证的地方,使用 [YYAuth] 特性,即可完成检测登录相关的操作,
|
||||||
如果需要获取用户的ID, 只需要 直接使用 LoginId 属性即可获取
|
如果需要获取用户的ID, 只需要 直接使用 LoginId 属性即可获取
|
||||||
|
|
||||||
4. 统一返回
|
4. 统一返回
|
||||||
@@ -58,5 +60,9 @@ app.UseAuthMiddleware();
|
|||||||
|
|
||||||
```C#
|
```C#
|
||||||
#Startup.cs
|
#Startup.cs
|
||||||
app.UseExceptionMiddleware();
|
app.UseYYException();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### TODO:
|
||||||
|
1. 增加HANGFIRE 支持redis和sqlite 存储, 支持 基于其他系统的TOKEN认证和独立账号密码认证
|
||||||
|
|||||||
+10
-7
@@ -1,10 +1,10 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<PackOnBuild>true</PackOnBuild>
|
<PackOnBuild>true</PackOnBuild>
|
||||||
<Version>0.2.1</Version>
|
<Version>0.2.3</Version>
|
||||||
<Authors>xRain@YYTech</Authors>
|
<Authors>xRain@YYTech</Authors>
|
||||||
<Description>AspNetCore一个方便的API文档,捕获异常,统一输入输出的API类库</Description>
|
<Description>AspNetCore一个方便的API文档,捕获异常,统一输入输出的API类库</Description>
|
||||||
<PackageId>YY-Tech.YYApi</PackageId>
|
<PackageId>YY-Tech.YYApi</PackageId>
|
||||||
@@ -18,14 +18,17 @@
|
|||||||
<Folder Include="Communications\" />
|
<Folder Include="Communications\" />
|
||||||
<Folder Include="Controllers\" />
|
<Folder Include="Controllers\" />
|
||||||
<Folder Include="JobService\" />
|
<Folder Include="JobService\" />
|
||||||
|
<Folder Include="Middlewares\" />
|
||||||
|
<Folder Include="Attributes\" />
|
||||||
|
<Folder Include="Exceptions\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.0.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.5.1" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.0.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.5.1" />
|
||||||
<PackageReference Include="HangFire.Core" Version="1.7.8" />
|
<PackageReference Include="HangFire.Core" Version="1.7.11" />
|
||||||
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.8" />
|
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.11" />
|
||||||
<PackageReference Include="Hangfire.Console" Version="1.4.2" />
|
<PackageReference Include="Hangfire.Console" Version="1.4.2" />
|
||||||
<PackageReference Include="Hangfire.Redis.StackExchange" Version="1.8.1" />
|
<PackageReference Include="Hangfire.Redis.StackExchange" Version="1.8.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<MonoDevelop>
|
<MonoDevelop>
|
||||||
|
|||||||
Reference in New Issue
Block a user