权限code过滤器
This commit is contained in:
@@ -33,7 +33,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id"></param>
|
/// <param name="id"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:get")]
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public virtual async Task<Result> GetById(long id)
|
public virtual async Task<Result> GetById(long id)
|
||||||
{
|
{
|
||||||
@@ -44,7 +43,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// 列表查询
|
/// 列表查询
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:get")]
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public virtual async Task<Result> GetList(QueryCondition queryCondition)
|
public virtual async Task<Result> GetList(QueryCondition queryCondition)
|
||||||
{
|
{
|
||||||
@@ -56,7 +54,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="queryCondition"></param>
|
/// <param name="queryCondition"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:get")]
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public virtual async Task<Result> PageList(QueryPageCondition queryCondition)
|
public virtual async Task<Result> PageList(QueryPageCondition queryCondition)
|
||||||
{
|
{
|
||||||
@@ -68,7 +65,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity"></param>
|
/// <param name="entity"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:add")]
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public virtual async Task<Result> Add(T entity)
|
public virtual async Task<Result> Add(T entity)
|
||||||
{
|
{
|
||||||
@@ -80,7 +76,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity"></param>
|
/// <param name="entity"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:update")]
|
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
public virtual async Task<Result> Update(T entity)
|
public virtual async Task<Result> Update(T entity)
|
||||||
{
|
{
|
||||||
@@ -92,7 +87,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ids"></param>
|
/// <param name="ids"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:del")]
|
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
public virtual async Task<Result> DeleteList(List<long> ids)
|
public virtual async Task<Result> DeleteList(List<long> ids)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// 全部列表查询
|
/// 全部列表查询
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:get")]
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public virtual async Task<Result> GetList()
|
public virtual async Task<Result> GetList()
|
||||||
{
|
{
|
||||||
@@ -57,7 +56,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity"></param>
|
/// <param name="entity"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:add")]
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public virtual async Task<Result> Add(T entity)
|
public virtual async Task<Result> Add(T entity)
|
||||||
{
|
{
|
||||||
@@ -70,7 +68,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity"></param>
|
/// <param name="entity"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:update")]
|
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
public virtual async Task<Result> Update(T entity)
|
public virtual async Task<Result> Update(T entity)
|
||||||
{
|
{
|
||||||
@@ -82,7 +79,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ids"></param>
|
/// <param name="ids"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:del")]
|
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
public virtual async Task<Result> DelList(List<long> ids)
|
public virtual async Task<Result> DelList(List<long> ids)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id"></param>
|
/// <param name="id"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:get")]
|
|
||||||
[Route("{id}")]
|
[Route("{id}")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public virtual async Task<Result> GetById([FromRoute]long id)
|
public virtual async Task<Result> GetById([FromRoute]long id)
|
||||||
@@ -45,7 +44,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// 全部列表查询
|
/// 全部列表查询
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:get")]
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public virtual async Task<Result> GetList()
|
public virtual async Task<Result> GetList()
|
||||||
{
|
{
|
||||||
@@ -57,7 +55,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ids"></param>
|
/// <param name="ids"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Permission($"{nameof(T)}:del")]
|
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
public virtual async Task<Result> DelList(List<long> ids)
|
public virtual async Task<Result> DelList(List<long> ids)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// 用户管理
|
/// 用户管理
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ApiController]
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
[Route("api/[controller]/[action]")]
|
[Route("api/[controller]/[action]")]
|
||||||
public class UserController : BaseSimpleRdController<UserEntity>
|
public class UserController : BaseSimpleRdController<UserEntity>
|
||||||
{
|
{
|
||||||
@@ -37,6 +38,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// <param name="deptId"></param>
|
/// <param name="deptId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
[Permission("system:user:query")]
|
||||||
public async Task<Result> PageList([FromQuery] UserEntity user, [FromQuery] PageParModel page,[FromQuery] long? deptId)
|
public async Task<Result> PageList([FromQuery] UserEntity user, [FromQuery] PageParModel page,[FromQuery] long? deptId)
|
||||||
{
|
{
|
||||||
return Result.Success().SetData(await _iUserService.SelctPageList(user, page, deptId));
|
return Result.Success().SetData(await _iUserService.SelctPageList(user, page, deptId));
|
||||||
@@ -49,6 +51,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// <param name="isDel"></param>
|
/// <param name="isDel"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
|
[Permission("system:user:edit")]
|
||||||
public async Task<Result> UpdateStatus(long userId, bool isDel)
|
public async Task<Result> UpdateStatus(long userId, bool isDel)
|
||||||
{
|
{
|
||||||
return Result.Success().SetData(await _iUserService._repository.UpdateIgnoreNullAsync(new UserEntity() { Id = userId, IsDeleted = isDel }));
|
return Result.Success().SetData(await _iUserService._repository.UpdateIgnoreNullAsync(new UserEntity() { Id = userId, IsDeleted = isDel }));
|
||||||
@@ -61,6 +64,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// <param name="giveUserSetRoleDto"></param>
|
/// <param name="giveUserSetRoleDto"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
|
[Permission("system:user:edit")]
|
||||||
public async Task<Result> GiveUserSetRole(GiveUserSetRoleDto giveUserSetRoleDto)
|
public async Task<Result> GiveUserSetRole(GiveUserSetRoleDto giveUserSetRoleDto)
|
||||||
{
|
{
|
||||||
return Result.Success().SetStatus(await _iUserService.GiveUserSetRole(giveUserSetRoleDto.UserIds, giveUserSetRoleDto.RoleIds));
|
return Result.Success().SetStatus(await _iUserService.GiveUserSetRole(giveUserSetRoleDto.UserIds, giveUserSetRoleDto.RoleIds));
|
||||||
@@ -74,6 +78,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{id}")]
|
[Route("{id}")]
|
||||||
|
[Permission("system:user:query")]
|
||||||
public override async Task<Result> GetById([FromRoute] long id)
|
public override async Task<Result> GetById([FromRoute] long id)
|
||||||
{
|
{
|
||||||
return Result.Success().SetData(await _iUserService.GetInfoById(id));
|
return Result.Success().SetData(await _iUserService.GetInfoById(id));
|
||||||
@@ -85,6 +90,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// <param name="userDto"></param>
|
/// <param name="userDto"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
|
[Permission("system:user:edit")]
|
||||||
public async Task<Result> Update(UserInfoDto userDto)
|
public async Task<Result> Update(UserInfoDto userDto)
|
||||||
{
|
{
|
||||||
if (await _iUserService._repository.IsAnyAsync(u => userDto.User.UserName.Equals(u.UserName)&&!userDto.User.Id.Equals(u.Id)))
|
if (await _iUserService._repository.IsAnyAsync(u => userDto.User.UserName.Equals(u.UserName)&&!userDto.User.Id.Equals(u.Id)))
|
||||||
@@ -101,6 +107,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// <param name="userDto"></param>
|
/// <param name="userDto"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
|
[Permission("system:user:edit")]
|
||||||
public async Task<Result> UpdateProfile(UserInfoDto userDto)
|
public async Task<Result> UpdateProfile(UserInfoDto userDto)
|
||||||
{
|
{
|
||||||
return Result.Success().SetStatus(await _iUserService.UpdateProfile(userDto));
|
return Result.Success().SetStatus(await _iUserService.UpdateProfile(userDto));
|
||||||
@@ -112,6 +119,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// <param name="userDto"></param>
|
/// <param name="userDto"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
[Permission("system:user:add2")]
|
||||||
public async Task<Result> Add(UserInfoDto userDto)
|
public async Task<Result> Add(UserInfoDto userDto)
|
||||||
{
|
{
|
||||||
if (await _iUserService._repository.IsAnyAsync(u => userDto.User.UserName.Equals(u.UserName)))
|
if (await _iUserService._repository.IsAnyAsync(u => userDto.User.UserName.Equals(u.UserName)))
|
||||||
@@ -128,9 +136,20 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
|||||||
/// <param name="user"></param>
|
/// <param name="user"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
|
[Permission("system:user:edit")]
|
||||||
public async Task<Result> RestPassword(UserEntity user)
|
public async Task<Result> RestPassword(UserEntity user)
|
||||||
{
|
{
|
||||||
return Result.Success().SetStatus(await _iUserService.RestPassword(user.Id, user.Password));
|
return Result.Success().SetStatus(await _iUserService.RestPassword(user.Id, user.Password));
|
||||||
}
|
}
|
||||||
|
[Permission("system:user:query")]
|
||||||
|
public override Task<Result> GetList()
|
||||||
|
{
|
||||||
|
return base.GetList();
|
||||||
|
}
|
||||||
|
[Permission("system:user:remove")]
|
||||||
|
public override Task<Result> DelList(List<long> ids)
|
||||||
|
{
|
||||||
|
return base.DelList(ids);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ ServiceLocator.Instance = app.Services;
|
|||||||
#region
|
#region
|
||||||
//<2F><><EFBFBD><EFBFBD>ץȡ<D7A5><C8A1><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>
|
//<2F><><EFBFBD><EFBFBD>ץȡ<D7A5><C8A1><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>
|
||||||
#endregion
|
#endregion
|
||||||
//app.UseErrorHandlingService();
|
app.UseErrorHandlingService();
|
||||||
|
|
||||||
#region
|
#region
|
||||||
//<2F><>̬<EFBFBD>ļ<EFBFBD>ע<EFBFBD><D7A2>
|
//<2F><>̬<EFBFBD>ļ<EFBFBD>ע<EFBFBD><D7A2>
|
||||||
|
|||||||
@@ -11,5 +11,6 @@ namespace Yi.Framework.Common.Const
|
|||||||
public const string Admin = "cc";
|
public const string Admin = "cc";
|
||||||
public const string AdminRolesCode = "admin";
|
public const string AdminRolesCode = "admin";
|
||||||
public const string AdminPermissionCode = "*:*:*";
|
public const string AdminPermissionCode = "*:*:*";
|
||||||
|
public const string PermissionClaim = "permission";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using System.Linq;
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Yi.Framework.Common.Const;
|
||||||
using Yi.Framework.Common.IOCOptions;
|
using Yi.Framework.Common.IOCOptions;
|
||||||
using Yi.Framework.Model.Models;
|
using Yi.Framework.Model.Models;
|
||||||
using JwtRegisteredClaimNames = Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames;
|
using JwtRegisteredClaimNames = Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames;
|
||||||
@@ -45,9 +46,14 @@ namespace Yi.Framework.Core
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(m.PermissionCode))
|
if (!string.IsNullOrEmpty(m.PermissionCode))
|
||||||
{
|
{
|
||||||
claims.Add(new Claim("permission", m.PermissionCode.ToString()));
|
claims.Add(new Claim(SystemConst.PermissionClaim, m.PermissionCode.ToString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (SystemConst.Admin.Equals(user.UserName))
|
||||||
|
{
|
||||||
|
claims.Add(new Claim(SystemConst.PermissionClaim, SystemConst.AdminPermissionCode));
|
||||||
|
}
|
||||||
|
|
||||||
var creds = new SigningCredentials(new RsaSecurityKey(Common.Helper.RSAFileHelper.GetKey()), SecurityAlgorithms.RsaSha256);
|
var creds = new SigningCredentials(new RsaSecurityKey(Common.Helper.RSAFileHelper.GetKey()), SecurityAlgorithms.RsaSha256);
|
||||||
var token = new JwtSecurityToken(
|
var token = new JwtSecurityToken(
|
||||||
issuer: _JWTTokenOptions.Issuer,
|
issuer: _JWTTokenOptions.Issuer,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Yi.Framework.Common.Const;
|
||||||
|
|
||||||
namespace Yi.Framework.WebCore.AttributeExtend
|
namespace Yi.Framework.WebCore.AttributeExtend
|
||||||
{
|
{
|
||||||
@@ -25,12 +26,13 @@ namespace Yi.Framework.WebCore.AttributeExtend
|
|||||||
/// <exception cref="Exception"></exception>
|
/// <exception cref="Exception"></exception>
|
||||||
public override void OnActionExecuting(ActionExecutingContext context)
|
public override void OnActionExecuting(ActionExecutingContext context)
|
||||||
{
|
{
|
||||||
base.OnActionExecuting(context);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(permission))
|
if (string.IsNullOrEmpty(permission))
|
||||||
{
|
{
|
||||||
throw new Exception("权限不能为空!");
|
throw new Exception("权限不能为空!");
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = false;
|
var result = false;
|
||||||
|
|
||||||
|
|
||||||
@@ -38,16 +40,20 @@ namespace Yi.Framework.WebCore.AttributeExtend
|
|||||||
var sid = context.HttpContext.User.Claims.FirstOrDefault(u => u.Type == JwtRegisteredClaimNames.Sid);
|
var sid = context.HttpContext.User.Claims.FirstOrDefault(u => u.Type == JwtRegisteredClaimNames.Sid);
|
||||||
|
|
||||||
//jwt存在的权限列表
|
//jwt存在的权限列表
|
||||||
var perList = context.HttpContext.User.Claims.Where(u => u.Type == "permission").Select(u=> u.Value.ToString().ToLower()). ToList();
|
var perList = context.HttpContext.User.Claims.Where(u => u.Type == SystemConst.PermissionClaim).Select(u => u.Value.ToString().ToLower()).ToList();
|
||||||
//判断权限是否存在Redis中,或者jwt中
|
//判断权限是否存在Redis中,或者jwt中
|
||||||
|
|
||||||
//进行正则表达式的匹配,以code开头
|
//进行正则表达式的匹配,以code开头
|
||||||
Regex regex = new Regex($"^{permission.ToLower()}");
|
Regex regex = new Regex($"^{permission.ToLower()}");
|
||||||
foreach (var p in perList)
|
foreach (var p in perList)
|
||||||
{
|
{
|
||||||
//过滤多余的标签
|
//如果存在超级管理员权限,直接放行
|
||||||
p.Replace("Entity","");
|
if (SystemConst.AdminPermissionCode.Equals(p))
|
||||||
p.Replace("entity","");
|
{
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (regex.IsMatch(p))
|
if (regex.IsMatch(p))
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
@@ -56,11 +62,6 @@ namespace Yi.Framework.WebCore.AttributeExtend
|
|||||||
}
|
}
|
||||||
//用户的增删改查直接可以user:*即可
|
//用户的增删改查直接可以user:*即可
|
||||||
|
|
||||||
|
|
||||||
//这里暂时全部放行即可
|
|
||||||
result = true;
|
|
||||||
|
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
throw new Exception("拦截未授权请求!");
|
throw new Exception("拦截未授权请求!");
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -15,10 +16,11 @@ namespace Yi.Framework.WebCore.MiddlewareExtend
|
|||||||
public class ErrorHandExtension
|
public class ErrorHandExtension
|
||||||
{
|
{
|
||||||
private readonly RequestDelegate next;
|
private readonly RequestDelegate next;
|
||||||
|
private ILogger<ErrorHandExtension> _logger;
|
||||||
public ErrorHandExtension(RequestDelegate next)
|
public ErrorHandExtension(RequestDelegate next,ILogger<ErrorHandExtension> logger)
|
||||||
{
|
{
|
||||||
this.next = next;
|
this.next = next;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Invoke(HttpContext context)
|
public async Task Invoke(HttpContext context)
|
||||||
@@ -34,6 +36,7 @@ namespace Yi.Framework.WebCore.MiddlewareExtend
|
|||||||
{
|
{
|
||||||
statusCode = 200;
|
statusCode = 200;
|
||||||
}
|
}
|
||||||
|
_logger.LogError($"中间件抓取错误\r\n错误信息:{ex.Message}\r\n堆栈信息“{ex.StackTrace}");
|
||||||
await HandleExceptionAsync(context, statusCode, ex.Message);
|
await HandleExceptionAsync(context, statusCode, ex.Message);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|||||||
Reference in New Issue
Block a user