xianhc / apevolo-api

.Net 8 、SqlSugar ORM、Vue 2.X、RBAC、前后端分离的开箱则用的企业级中后台权限管理系统
https://www.apevolo.com
Apache License 2.0
809 stars 74 forks source link

\Controllers\Base\BaseController.cs中 HttpContext 不是线程安全型 #14

Closed huster-songtao closed 2 years ago

huster-songtao commented 2 years ago

Path = HttpContextCore.CurrentHttpContext.Request.Path.Value?.ToLower()

修改为:

Path = HttpContext.Request.Path.Value?.ToLower()

\Filter\AuditingFilter.cs 同样的问题,不需要通过AutofacHelper.GetService()去拿HttpContext

if (HttpContextCore.CurrentHttpContext.IsNotNull() && result != null)
                {
                    var reqUrlPath = HttpContextCore.CurrentHttpContext.Request.Path.Value?.ToLower();

修改为

if (context.HttpContext.IsNotNull() && result != null)
                {
                    var reqUrlPath = context.HttpContext.Request.Path.Value?.ToLower();
var auditLog = new AuditLog
        {
            Id = IdHelper.GetLongId(),
            CreateBy = _currentUser.Name ?? "",
            CreateTime = DateTime.Now,
            Area = routeValues["area"],
            Controller = routeValues["controller"],
            Action = routeValues["action"],
            Method = context.HttpContext.Request.Method,
            Description = desc == null ? "" : ((DescriptionAttribute)desc).Description,
            RequestUrl = HttpContextCore.CurrentHttpContext.Request.GetDisplayUrl() ?? "",
            RequestParameters = decs.ToJson(),
            BrowserName = browserName,
            BrowserVersion = browserVersion,
            BrowserOS = browserOS,
            BrowserDeviceType = browserDeviceType,
            RequestIp = remoteIpAddress,
            IpAddress = IpHelper.GetIpAddress(remoteIpAddress)
        };

        var reqUrl = HttpContextCore.CurrentHttpContext.Request.Path.Value?.ToLower();

修改为:

        var auditLog = new AuditLog
        {
            Id = IdHelper.GetLongId(),
            CreateBy = _currentUser.Name ?? "",
            CreateTime = DateTime.Now,
            Area = routeValues["area"],
            Controller = routeValues["controller"],
            Action = routeValues["action"],
            Method = context.HttpContext.Request.Method,
            Description = desc == null ? "" : ((DescriptionAttribute)desc).Description,
            RequestUrl = context.HttpContext.Request.GetDisplayUrl() ?? "",
            RequestParameters = decs.ToJson(),
            BrowserName = browserName,
            BrowserVersion = browserVersion,
            BrowserOS = browserOS,
            BrowserDeviceType = browserDeviceType,
            RequestIp = remoteIpAddress,
            IpAddress = IpHelper.GetIpAddress(remoteIpAddress)
        };

        var reqUrl = context.HttpContext.Request.Path.Value?.ToLower();

\Filter\GlobalExceptionFilter.cs context.Result = new ContentResult

        {
            Content = new ActionResultVm
            {
                Status = statusCode,
                Error = GetExceptionError(statusCode),
                Message = throwMsg,
                Path = HttpContextCore.CurrentHttpContext.Request.Path.Value?.ToLower()
            }.ToJson(),
            ContentType = "application/json; charset=utf-8",
            StatusCode = statusCode
        };

修改为:

context.Result = new ContentResult
        {
            Content = new ActionResultVm
            {
                Status = statusCode,
                Error = GetExceptionError(statusCode),
                Message = throwMsg,
                Path = context.HttpContext.Request.Path.Value?.ToLower()
            }.ToJson(),
            ContentType = "application/json; charset=utf-8",
            StatusCode = statusCode
        };

WriteLog(ExceptionContext context) 这个方法

 HttpContextCore.CurrentHttpContext.Request.GetDisplayUrl() ?? "", context.HttpContext.Request.Method,
            HttpContextCore.CurrentHttpContext.Request.Body.ReadToString() ?? "", _currentUser.Name ?? "",

修改为:

        ```

context.HttpContext.Request.GetDisplayUrl() ?? "", context.HttpContext.Request.Method, context.HttpContext.Request.Body.ReadToString() ?? "", _currentUser.Name ?? "",



`RequestUrl = HttpContextCore.CurrentHttpContext.Request.GetDisplayUrl() ?? "",`
修改为:
`RequestUrl = context.HttpContext.Request.GetDisplayUrl() ?? "",`

关于HttpContext: 

**HttpContext 不是线程安全型**。 

请勿在并行任务中引用 HttpContext 数据。 在开始并行任务之前,从上下文中提取所需的数据。

在处理请求之外读取或写入 HttpContext 的属性可能会导致 [NullReferenceException]
(https://docs.microsoft.com/zh-cn/dotnet/api/system.nullreferenceexception)。

HttpContextCore.CurrentHttpContext 是静态调用,这个在后台处理的部分代码会抛NullReferenceException,HttpContext 是不太推荐被静态使用,主要是这里的问题。

共享使用单一实例HttpContext我记得是有问题的,不太推荐这种静态调用的写法
xianhc commented 2 years ago

感谢你的提议,代码已优化