gpt4 book ai didi

在NetCore开发中如何解决Cannotaccessadisposedobject这个问题

转载 作者:我是一只小鸟 更新时间:2023-05-31 14:31:45 33 4
gpt4 key购买 nike

1、简介     Net Core跨平台项目开发多了,总会遇到各种各样的问题,我就遇到了一个这样的问题,不能访问 Cannot access a disposed object 错误,经过自己多方努力,查阅资料,终于找到了解决办法,引发这个问题的原因大多数是多次读取请求Body流造成的,需要换一种获取请求Body流方法,不能使用StreamRreader方式,使用Body.CopyTo(ms)方法。             我使用的环境:Visual Studio 2022     开发语言:C#     开发框架:Asp.Net Core Mvc     DotNet版本:Net 6.0 。

    遇到问题是好事,说明自己还有不足,那就解决它,时间长了,技术和知识也就积累了。其实解决方法不难,话不多,直接上解决方案。 2、解决方案的具体实现 。    解决方法很简单,不需要做过多解释,直接找个配置和编码就可以了,我贴完整源码,是便于以后查阅,不喜勿喷.

    总共三步:红色字体写好了操作步骤( 说明一下,红色字体是要解决方法,其他不要关注,把整个代码贴出来,是为了以后查阅 ) 。

                  
                    using
                  
                  
                     Microsoft.AspNetCore.Authentication.Cookies;

                  
                  
                    using
                  
                  
                     Microsoft.AspNetCore.Mvc.Razor;

                  
                  
                    using
                  
                  
                     Microsoft.AspNetCore.Server.Kestrel.Core;

                  
                  
                    using
                  
                  
                     OpticalTrap.Framework.DataAccessors;

                  
                  
                    using
                  
                  
                     OpticalTrap.Web.Facade.Extensions.Filters;

                  
                  
                    using
                  
                  
                     OpticalTrap.Web.Facade.Utilities;

                  
                  
                    using
                  
                  
                     OpticalTrap.Web.ServiceManager;


                  
                  
                    var
                  
                   builder =
                  
                     WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews(option 
                  
                  =>
                  
                    
{
    option.Filters.Add(
                  
                  
                    typeof
                  
                  
                    (GlobalAuthorizationFilterAttribute));
    option.Filters.Add(
                  
                  
                    typeof
                  
                  
                    (GlobalOperationLogFilterAttribute));
}).AddXmlSerializerFormatters();


                  
                  
                    #region
                  
                  
                     第一步:配置可以同步请求读取流数据 builder.Services.Configure<KestrelServerOptions>(k => k.AllowSynchronousIO = true) .Configure<IISServerOptions>(k => k.AllowSynchronousIO = true); 
                  
                  
                    #endregion
                  
                  
                    #region
                  
                   配置日志
                  
                    

builder.Logging.AddLog4Net(
                  
                  
                    "
                  
                  
                    ConfigFiles/log4net.config
                  
                  
                    "
                  
                  
                    );


                  
                  
                    #endregion
                  
                  
                    #region
                  
                   配置 Session
                  
                    

builder.Services.AddSession();


                  
                  
                    #endregion
                  
                  
                    #region
                  
                   配置数据库
                  
                    

builder.Services.AddTransientSqlSugar(builder.Configuration[
                  
                  
                    "
                  
                  
                    ConnectionStrings:DefaultConnectionString
                  
                  
                    "
                  
                  
                    ]);


                  
                  
                    #endregion
                  
                  
                    #region
                  
                   配置区域
                  
                    

builder.Services.Configure
                  
                  <RazorViewEngineOptions>(option =>
                  
                    
{
    option.AreaViewLocationFormats.Clear();
    option.AreaViewLocationFormats.Add(
                  
                  
                    "
                  
                  
                    /Areas/{2}/Views/{1}/{0}.cshtml
                  
                  
                    "
                  
                  
                    );
    option.AreaViewLocationFormats.Add(
                  
                  
                    "
                  
                  
                    /Areas/{2}/Views/Shared/{0}.cshtml
                  
                  
                    "
                  
                  
                    );
    option.AreaViewLocationFormats.Add(
                  
                  
                    "
                  
                  
                    /Views/Shared/{0}.cshtml
                  
                  
                    "
                  
                  
                    );
});


                  
                  
                    #endregion
                  
                  
                    #region
                  
                   配置服务实例
                  
                    

builder.Services.AddBusinessServices();
builder.Services.AddUtilityServices();
builder.Services.AddSingleton
                  
                  <IHttpContextAccessor, HttpContextAccessor>
                  
                    ();
builder.Services.AddSingleton
                  
                  <SessionCacheObjectProvider>
                  
                    ();
builder.Services.AddTransient
                  
                  <AuthorizedDataGridGeneratorWrapper>
                  
                    ();
builder.Services.AddSingleton
                  
                  <PageNumberGenerator>
                  
                    ();


                  
                  
                    #endregion
                  
                  
                    #region
                  
                   认证设置
                  
                    

builder.Services.AddAuthentication(option 
                  
                  =>
                  
                    
{
    option.DefaultAuthenticateScheme 
                  
                  =
                  
                     CookieAuthenticationDefaults.AuthenticationScheme;
    option.DefaultChallengeScheme 
                  
                  =
                  
                     CookieAuthenticationDefaults.AuthenticationScheme;
    option.DefaultSignInScheme 
                  
                  =
                  
                     CookieAuthenticationDefaults.AuthenticationScheme;
    option.DefaultForbidScheme 
                  
                  =
                  
                     CookieAuthenticationDefaults.AuthenticationScheme;
    option.DefaultSignOutScheme 
                  
                  =
                  
                     CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options 
                  
                  =>
                  
                    
{
    options.LoginPath 
                  
                  = 
                  
                    "
                  
                  
                    /Validation/Index
                  
                  
                    "
                  
                  
                    ;
    options.LogoutPath 
                  
                  = 
                  
                    "
                  
                  
                    /Validation/Logout
                  
                  
                    "
                  
                  
                    ;
    options.AccessDeniedPath 
                  
                  = 
                  
                    "
                  
                  
                    /Validation/Index
                  
                  
                    "
                  
                  
                    ;
    options.Cookie.HttpOnly 
                  
                  = 
                  
                    true
                  
                  
                    ;
    options.ClaimsIssuer 
                  
                  = 
                  
                    "
                  
                  
                    Cookie
                  
                  
                    "
                  
                  
                    ;
});


                  
                  
                    #endregion
                  
                  
                    var
                  
                   app =
                  
                     builder.Build();


                  
                  
                    //
                      第二步:  
                  
                  
                     启用倒带, 在发生异常时, 可以通过过滤器获取post参数 
                     app.Use((context, next) => { context.Request.EnableBuffering(); return next(context); }); 
                  
                  
                    if
                  
                  
                     (app.Environment.IsProduction())
{
    app.UseStatusCodePagesWithReExecute(
                  
                  
                    "
                  
                  
                    /ErrorHandler/HttpStatusCode
                  
                  
                    "
                  
                  , 
                  
                    "
                  
                  
                    ?statusCode={0}
                  
                  
                    "
                  
                  
                    );
    app.UseExceptionHandler(
                  
                  
                    "
                  
                  
                    /ErrorHandler/ExceptionHandler
                  
                  
                    "
                  
                  
                    );
}

                  
                  
                    else
                  
                  
                    
{
    app.UseDeveloperExceptionPage();
}

app.UseStaticFiles();

app.UseSession();
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
                  
                  
                    "
                  
                  
                    defaultAreaRoute
                  
                  
                    "
                  
                  , 
                  
                    "
                  
                  
                    {area:exists}/{controller=Home}/{action=Index}/{id?}
                  
                  
                    "
                  
                  
                    );

app.MapControllerRoute(
                  
                  
                    "
                  
                  
                    defaultRoute
                  
                  
                    "
                  
                  , 
                  
                    "
                  
                  
                    {controller=Home}/{action=Index}/{id?}
                  
                  
                    "
                  
                  
                    );

app.Run();
                  
                
 
        我写了一个过滤器(实现日志功能),实现的是IActionFilter 过滤器,在过滤器中,获取Post请求Body的Context使用下面方式获取强调( 强调,关注红色字体,其他无关,这是我写的日志功能,贴全部代码,便于以后查阅,不喜勿喷)
                  
                      1
                  
                  
                    using
                  
                  
                     Microsoft.AspNetCore.Mvc.Filters;

                  
                  
                      2
                  
                  
                    using
                  
                  
                     Newtonsoft.Json;

                  
                  
                      3
                  
                  
                    using
                  
                  
                     OpticalTrap.Framework.Loggings;

                  
                  
                      4
                  
                  
                    using
                  
                  
                     OpticalTrap.Web.ConstProvider;

                  
                  
                      5
                  
                  
                    using
                  
                  
                     OpticalTrap.Web.Contracts;

                  
                  
                      6
                  
                  
                    using
                  
                  
                     OpticalTrap.Web.Facade.Controllers;

                  
                  
                      7
                  
                  
                    using
                  
                  
                     OpticalTrap.Web.Models;

                  
                  
                      8
                  
                  
                    using
                  
                  
                     System.Reflection;

                  
                  
                      9
                  
                  
                    using
                  
                  
                     System.Security.Claims;

                  
                  
                     10
                  
                  
                    using
                  
                  
                     System.Text;

                  
                  
                     11
                  
                  
                     12
                  
                  
                    namespace
                  
                  
                     OpticalTrap.Web.Facade.Extensions.Filters

                  
                  
                     13
                  
                  
                    {

                  
                  
                     14
                  
                  
                    ///
                  
                  
                    <summary>
                  
                  
                     15
                  
                  
                    ///
                  
                  
                     该类型定义了全局处理操作日志的过滤器,该类型是密封类型。

                  
                  
                     16
                  
                  
                    ///
                  
                  
                    </summary>
                  
                  
                     17
                  
                  
                    public
                  
                  
                    sealed
                  
                  
                    class
                  
                  
                     GlobalOperationLogFilterAttribute : Attribute, IActionFilter, IAsyncActionFilter

                  
                  
                     18
                  
                  
                        {

                  
                  
                     19
                  
                  
                    #region
                  
                   实例字段

                  
                     20
                  
                  
                     21
                  
                  
                    private
                  
                  
                    readonly
                  
                   ILogger<GlobalOperationLogFilterAttribute>
                  
                     _logger;

                  
                  
                     22
                  
                  
                    private
                  
                  
                    readonly
                  
                  
                     IServiceProvider _serviceProvider;

                  
                  
                     23
                  
                  
                     24
                  
                  
                    #endregion
                  
                  
                     25
                  
                  
                     26
                  
                  
                    #region
                  
                   构造函数

                  
                     27
                  
                  
                     28
                  
                  
                    ///
                  
                  
                    <summary>
                  
                  
                     29
                  
                  
                    ///
                  
                  
                     初始化该类型的新实例。

                  
                  
                     30
                  
                  
                    ///
                  
                  
                    </summary>
                  
                  
                     31
                  
                  
                    ///
                  
                  
                    <param name="logger">
                  
                  
                    需要注入的日志服务实例。
                  
                  
                    </param>
                  
                  
                     32
                  
                  
                    ///
                  
                  
                    <param name="serviceProvider">
                  
                  
                    需要注入的服务提供器。
                  
                  
                    </param>
                  
                  
                     33
                  
                  
                    public
                  
                   GlobalOperationLogFilterAttribute(ILogger<GlobalOperationLogFilterAttribute>
                  
                     logger, IServiceProvider serviceProvider)

                  
                  
                     34
                  
                  
                            {

                  
                  
                     35
                  
                               _logger =
                  
                     logger;

                  
                  
                     36
                  
                               _serviceProvider =
                  
                     serviceProvider;

                  
                  
                     37
                  
                  
                            }

                  
                  
                     38
                  
                  
                     39
                  
                  
                    #endregion
                  
                  
                     40
                  
                  
                     41
                  
                  
                    #region
                  
                   操作日志的同步方法

                  
                     42
                  
                  
                     43
                  
                  
                    ///
                  
                  
                    <summary>
                  
                  
                     44
                  
                  
                    ///
                  
                  
                     在标注方法执行之前执行该方法。

                  
                  
                     45
                  
                  
                    ///
                  
                  
                    </summary>
                  
                  
                     46
                  
                  
                    ///
                  
                  
                    <param name="context">
                  
                  
                    方法执行前的上下文。
                  
                  
                    </param>
                  
                  
                     47
                  
                  
                    public
                  
                  
                    async
                  
                  
                    void
                  
                  
                     OnActionExecuting(ActionExecutingContext context)

                  
                  
                     48
                  
                  
                            {

                  
                  
                     49
                  
                  
                    if
                  
                   (context.Controller.GetType() != 
                  
                    typeof
                  
                  
                    (ErrorHandlerController))

                  
                  
                     50
                  
                  
                                {

                  
                  
                     51
                  
                  
                    if
                  
                   (context.ActionDescriptor.EndpointMetadata.Any(c => c.GetType() == 
                  
                    typeof
                  
                  
                    (RequiredLogAttribute)))

                  
                  
                     52
                  
                  
                                    {

                  
                  
                     53
                  
                  
                    #region
                  
                   核心处理

                  
                     54
                  
                  
                     55
                  
                  
                    var
                  
                   controllerType =
                  
                     context.Controller.GetType();

                  
                  
                     56
                  
                  
                    var
                  
                   currentMethodName = context.ActionDescriptor.RouteValues[
                  
                    "
                  
                  
                    action
                  
                  
                    "
                  
                  ]!
                  
                    ;

                  
                  
                     57
                  
                  
                     58
                  
                  
                    string
                  
                  ? loginName = 
                  
                    string
                  
                  
                    .Empty;

                  
                  
                     59
                  
                  
                    var
                  
                   claimKeysProvider = _serviceProvider.GetService<ClaimKeysConstProvider>
                  
                    ();

                  
                  
                     60
                  
                  
                    if
                  
                   (claimKeysProvider != 
                  
                    null
                  
                  
                    )

                  
                  
                     61
                  
                  
                                        {

                  
                  
                     62
                  
                                           loginName =
                  
                     context.HttpContext.User.FindFirstValue(claimKeysProvider.ClaimStoreUserNameKey);

                  
                  
                     63
                  
                  
                                        }

                  
                  
                     64
                  
                  
                     65
                  
                  
                    var
                  
                   currentDateTime =
                  
                     DateTime.Now;

                  
                  
                     66
                  
                  
                    var
                  
                   methodType =
                  
                     context.HttpContext.Request.Method;

                  
                  
                     67
                  
                  
                    string
                  
                   parameterResult = 
                  
                    string
                  
                  
                    .Empty;

                  
                  
                     68
                  
                  
                    if
                  
                   (
                  
                    string
                  
                  .Compare(methodType, 
                  
                    "
                  
                  
                    get
                  
                  
                    "
                  
                  , 
                  
                    true
                  
                  ) == 
                  
                    0
                  
                  
                    )

                  
                  
                     69
                  
                  
                                        {

                  
                  
                     70
                  
                  
                    if
                  
                   (!
                  
                    string
                  
                  .IsNullOrEmpty(context.HttpContext.Request.QueryString.Value) && !
                  
                    string
                  
                  
                    .IsNullOrWhiteSpace(context.HttpContext.Request.QueryString.Value))

                  
                  
                     71
                  
                  
                                            {

                  
                  
                     72
                  
                                               parameterResult =
                  
                     context.HttpContext.Request.QueryString.Value;

                  
                  
                     73
                  
                  
                                            }

                  
                  
                     74
                  
                  
                                        }

                  
                  
                     75
                  
                  
                    else
                  
                  
                     76
                  
                  
                                        {

                  
                  
                     77
                  
                  
                    //
                      第三步:在同步方法里的使用:  
                  
                  
                     启用倒带, 读取request.body里的的参数, 还必须在在Program.cs里也启用倒带功能 
                  
                  
                     78
                  
                  
                     context.HttpContext.Request.EnableBuffering(); 
                  
                  
                     79
                  
                  
                     context.HttpContext.Request.Body.Position = 0; 
                  
                  
                     80
                  
                  
                     using (var memoryStream = new MemoryStream()) 
                  
                  
                     81
                  
                  
                     { 
                  
                  
                     82
                  
                  
                     context.HttpContext.Request.Body.CopyTo(memoryStream); 
                  
                  
                     83
                  
                  
                     var streamBytes = memoryStream.ToArray(); 
                  
                  
                     84
                  
                  
                     parameterResult = Encoding.UTF8.GetString(streamBytes); 
                  
                  
                    //
                  
                  
                    把body赋值给bodyStr
                  
                  
                     85
                  
                  
                     } 
                  
                  
                     86
                  
                  
                    //using (var reader = new StreamReader(context.HttpContext.Request.Body, Encoding.UTF8))
                    
                        //{
                        //   var bodyRead = reader.ReadToEndAsync();
                        //   bodyStr = bodyRead.Result;  //把body赋值给bodyStr
                        //   needKey = JsonConvert.DeserializeAnonymousType
                //  (bodyRead.Result, new Dictionary<string, object>())[dependencySource].ToString();
                        //}
                  
                    if
                  
                   (controllerType != 
                  
                    typeof
                  
                  
                    (ValidationController))

                  
                  
                     87
                  
                  
                                            {

                  
                  
                     88
                  
                                               parameterResult =
                  
                     ProcessFormParameters(parameterResult);

                  
                  
                     89
                  
                  
                                            }

                  
                  
                     90
                  
                  
                    else
                  
                  
                     91
                  
                  
                                            {

                  
                  
                     92
                  
                                               parameterResult = ProcessLoginUserNameParameters(parameterResult, controllerType, nameof(ValidationController), currentMethodName, 
                  
                    out
                  
                  
                     loginName);

                  
                  
                     93
                  
                  
                                            }

                  
                  
                     94
                  
                  
                                        }

                  
                  
                     95
                  
                  
                     96
                  
                                       parameterResult = !
                  
                    string
                  
                  .IsNullOrEmpty(parameterResult) ? parameterResult : 
                  
                    "
                  
                  
                    没有传递任何参数
                  
                  
                    "
                  
                  
                    ;

                  
                  
                     97
                  
                                       loginName = !
                  
                    string
                  
                  .IsNullOrEmpty(loginName) ? loginName : 
                  
                    "
                  
                  
                    anonymous
                  
                  
                    "
                  
                  
                    ;

                  
                  
                     98
                  
                                       Guid userid =
                  
                     Guid.Empty;

                  
                  
                     99
                  
                  
                    if
                  
                   (
                  
                    string
                  
                  .IsNullOrEmpty(context.HttpContext.User.FindFirstValue(ClaimTypes.Sid)) || 
                  
                    string
                  
                  
                    .IsNullOrWhiteSpace(context.HttpContext.User.FindFirstValue(ClaimTypes.Sid)))

                  
                  
                    100
                  
                  
                                        {

                  
                  
                    101
                  
                                           userid = Guid.Parse(
                  
                    "
                  
                  
                    a05897f9-0c86-4f5a-a581-e5da936d0e4c
                  
                  
                    "
                  
                  
                    );

                  
                  
                    102
                  
                  
                                        }

                  
                  
                    103
                  
                  
                    else
                  
                  
                    104
                  
                  
                                        {

                  
                  
                    105
                  
                                           userid =
                  
                     Guid.Parse(context.HttpContext.User.FindFirstValue(ClaimTypes.Sid));

                  
                  
                    106
                  
                  
                                        }

                  
                  
                    107
                  
                  
                    108
                  
                                       OperationLog log = 
                  
                    new
                  
                  
                     OperationLog()

                  
                  
                    109
                  
                  
                                        {

                  
                  
                    110
                  
                                           Id =
                  
                     Guid.NewGuid(),

                  
                  
                    111
                  
                                           Name = $
                  
                    "
                  
                  
                    {loginName}在{currentDateTime.ToString(
                  
                  
                    "
                  
                  yyyy-MM-dd HH:mm:ss
                  
                    "
                  
                  
                    )}执行了{currentMethodName}操作。
                  
                  
                    "
                  
                  
                    ,

                  
                  
                    112
                  
                                           LoginName =
                  
                     loginName,

                  
                  
                    113
                  
                                           Parameters =
                  
                     parameterResult,

                  
                  
                    114
                  
                                           ActionName = $
                  
                    "
                  
                  
                    {controllerType.FullName}.{currentMethodName}
                  
                  
                    "
                  
                  
                    ,

                  
                  
                    115
                  
                                           ActionType =
                  
                     methodType,

                  
                  
                    116
                  
                                           Message = $
                  
                    "
                  
                  
                    【{loginName}】用户在【{currentDateTime.ToString(
                  
                  
                    "
                  
                  yyyy-MM-dd HH:mm:ss
                  
                    "
                  
                  
                    )}】执行了控制器【{controllerType.FullName}】的【{currentMethodName}】方法,执行方法的类型:{methodType},执行方法所需的参数:【{parameterResult}】,操作顺利完成。
                  
                  
                    "
                  
                  
                    ,

                  
                  
                    117
                  
                                           Remarks = 
                  
                    "
                  
                  
                    全局日志记录器记录的日志。
                  
                  
                    "
                  
                  
                    ,

                  
                  
                    118
                  
                                           CreateUserId =
                  
                     userid,

                  
                  
                    119
                  
                                           CreateDate =
                  
                     currentDateTime

                  
                  
                    120
                  
                  
                                        };

                  
                  
                    121
                  
                  
                    122
                  
                  
                    try
                  
                  
                    123
                  
                  
                                        {

                  
                  
                    124
                  
                                           MethodInfo?
                  
                     methodInfo;

                  
                  
                    125
                  
                  
                    if
                  
                   (controllerType.IsDefined(
                  
                    typeof
                  
                  (RequiredLogAttribute), 
                  
                    false
                  
                  
                    ))

                  
                  
                    126
                  
                  
                                            {

                  
                  
                    127
                  
                                               methodInfo =
                  
                     controllerType.GetMethod(currentMethodName);

                  
                  
                    128
                  
                  
                    if
                  
                   (methodInfo != 
                  
                    null
                  
                  
                    )

                  
                  
                    129
                  
                  
                                                {

                  
                  
                    130
                  
                  
                                                    _logger.LogInformation(JsonConvert.SerializeObject(log));

                  
                  
                    131
                  
                  
                                                }

                  
                  
                    132
                  
                  
                                            }

                  
                  
                    133
                  
                  
                    else
                  
                  
                    134
                  
                  
                                            {

                  
                  
                    135
                  
                                               methodInfo =
                  
                     controllerType.GetMethod(currentMethodName);

                  
                  
                    136
                  
                  
                    if
                  
                   (methodInfo != 
                  
                    null
                  
                  
                    )

                  
                  
                    137
                  
                  
                                                {

                  
                  
                    138
                  
                  
                    if
                  
                   (methodInfo.IsDefined(
                  
                    typeof
                  
                  (RequiredLogAttribute), 
                  
                    false
                  
                  
                    ))

                  
                  
                    139
                  
                  
                                                    {

                  
                  
                    140
                  
                  
                                                        _logger.LogInformation(JsonConvert.SerializeObject(log));

                  
                  
                    141
                  
                  
                                                    }

                  
                  
                    142
                  
                  
                                                }

                  
                  
                    143
                  
                  
                                            }

                  
                  
                    144
                  
                  
                                        }

                  
                  
                    145
                  
                  
                    catch
                  
                  
                     (Exception ex)

                  
                  
                    146
                  
                  
                                        {

                  
                  
                    147
                  
                                           log.Name = $
                  
                    "
                  
                  
                    异常操作日志:{loginName}在{currentDateTime.ToString(
                  
                  
                    "
                  
                  yyyy-MM-dd HH:mm:ss
                  
                    "
                  
                  
                    )}执行了{currentMethodName}操作。
                  
                  
                    "
                  
                  
                    ;

                  
                  
                    148
                  
                  
                    149
                  
                                           log.Message = $
                  
                    "
                  
                  
                    【{loginName}】用户在【{currentDateTime.ToString(
                  
                  
                    "
                  
                  yyyy-MM-dd HH:mm:ss
                  
                    "
                  
                  
                    )}】执行了控制器【{controllerType.FullName}】的【{currentMethodName}】方法,执行方法的类型:{methodType},执行方法所需的参数:【{parameterResult}】,操作没有完成,系统发生了异常。<br/>异常详情:{ex.Message},<br/>异常堆栈:{ex.StackTrace}。
                  
                  
                    "
                  
                  
                    ;

                  
                  
                    150
                  
                  
                    151
                  
                  
                                            _logger.LogInformation(JsonConvert.SerializeObject(log));

                  
                  
                    152
                  
                  
                                        }

                  
                  
                    153
                  
                  
                    154
                  
                  
                    #endregion
                  
                  
                    155
                  
                  
                                    }

                  
                  
                    156
                  
                  
                                }

                  
                  
                    157
                  
                  
                            }

                  
                  
                    158
                  
                  
                    159
                  
                  
                    ///
                  
                  
                    <summary>
                  
                  
                    160
                  
                  
                    ///
                  
                  
                     在标注方法执行之后执行该方法。

                  
                  
                    161
                  
                  
                    ///
                  
                  
                    </summary>
                  
                  
                    162
                  
                  
                    ///
                  
                  
                    <param name="context">
                  
                  
                    方法执行后的上下文。
                  
                  
                    </param>
                  
                  
                    163
                  
                  
                    public
                  
                  
                    void
                  
                  
                     OnActionExecuted(ActionExecutedContext context) { }

                  
                  
                    164
                  
                  
                    165
                  
                  
                    #endregion
                  
                  
                    166
                  
                  
                    167
                  
                  
                    #region
                  
                   操作日志的异步方法

                  
                    168
                  
                  
                    169
                  
                  
                    ///
                  
                  
                    <summary>
                  
                  
                    170
                  
                  
                    ///
                  
                  
                     全局日志记录器异步实现的操作日志的记录。

                  
                  
                    171
                  
                  
                    ///
                  
                  
                    </summary>
                  
                  
                    172
                  
                  
                    ///
                  
                  
                    <param name="context">
                  
                  
                    方法执行前的上下文。
                  
                  
                    </param>
                  
                  
                    173
                  
                  
                    ///
                  
                  
                    <param name="next">
                  
                  
                    方法执行的下一个环节代理。
                  
                  
                    </param>
                  
                  
                    174
                  
                  
                    ///
                  
                  
                    <returns></returns>
                  
                  
                    175
                  
                  
                    public
                  
                  
                    async
                  
                  
                     Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)

                  
                  
                    176
                  
                  
                            {

                  
                  
                    177
                  
                  
                    if
                  
                   (context.Controller.GetType() != 
                  
                    typeof
                  
                  
                    (ErrorHandlerController))

                  
                  
                    178
                  
                  
                                {

                  
                  
                    179
                  
                  
                    if
                  
                   (context.ActionDescriptor.EndpointMetadata.Any(c => c.GetType() == 
                  
                    typeof
                  
                  
                    (RequiredLogAttribute)))

                  
                  
                    180
                  
                  
                                    {

                  
                  
                    181
                  
                  
                    #region
                  
                   核心处理

                  
                    182
                  
                  
                    183
                  
                  
                    var
                  
                   controllerType =
                  
                     context.Controller.GetType();

                  
                  
                    184
                  
                  
                    var
                  
                   currentMethodName = context.ActionDescriptor.RouteValues[
                  
                    "
                  
                  
                    action
                  
                  
                    "
                  
                  ]!
                  
                    ;

                  
                  
                    185
                  
                  
                    186
                  
                  
                    string
                  
                  ? loginName = 
                  
                    string
                  
                  
                    .Empty;

                  
                  
                    187
                  
                  
                    var
                  
                   claimKeysProvider = _serviceProvider.GetService<ClaimKeysConstProvider>
                  
                    ();

                  
                  
                    188
                  
                  
                    if
                  
                   (claimKeysProvider != 
                  
                    null
                  
                  
                    )

                  
                  
                    189
                  
                  
                                        {

                  
                  
                    190
                  
                                           loginName =
                  
                     context.HttpContext.User.FindFirstValue(claimKeysProvider.ClaimStoreUserNameKey);

                  
                  
                    191
                  
                  
                                        }

                  
                  
                    192
                  
                  
                    193
                  
                  
                    var
                  
                   currentDateTime =
                  
                     DateTime.Now;

                  
                  
                    194
                  
                  
                    var
                  
                   methodType =
                  
                     context.HttpContext.Request.Method;

                  
                  
                    195
                  
                  
                    string
                  
                   parameterResult = 
                  
                    string
                  
                  
                    .Empty;

                  
                  
                    196
                  
                  
                    if
                  
                   (
                  
                    string
                  
                  .Compare(methodType, 
                  
                    "
                  
                  
                    get
                  
                  
                    "
                  
                  , 
                  
                    true
                  
                  ) == 
                  
                    0
                  
                  
                    )

                  
                  
                    197
                  
                  
                                        {

                  
                  
                    198
                  
                  
                    if
                  
                   (!
                  
                    string
                  
                  .IsNullOrEmpty(context.HttpContext.Request.QueryString.Value) && !
                  
                    string
                  
                  
                    .IsNullOrWhiteSpace(context.HttpContext.Request.QueryString.Value))

                  
                  
                    199
                  
                  
                                            {

                  
                  
                    200
                  
                                               parameterResult =
                  
                     context.HttpContext.Request.QueryString.Value;

                  
                  
                    201
                  
                  
                                            }

                  
                  
                    202
                  
                  
                                        }

                  
                  
                    203
                  
                  
                    else
                  
                  
                    204
                  
                  
                                        {

                  
                  
                    205
                  
                  
                    //
                  
                  
                      第三步:在异步步方法里的使用:    启用倒带, 读取request.body里的的参数, 还必须在在Program.cs里也启用倒带功能   
                  
                  
                    206
                  
                  
                     context.HttpContext.Request.EnableBuffering(); 
                  
                  
                    207
                  
                  
                     context.HttpContext.Request.Body.Position = 0; 
                  
                  
                    208
                  
                  
                     using (var memoryStream = new MemoryStream()) 
                  
                  
                    209
                  
                  
                     { 
                  
                  
                    210
                  
                  
                     context.HttpContext.Request.Body.CopyTo(memoryStream); 
                  
                  
                    211
                  
                  
                     var streamBytes = memoryStream.ToArray(); 
                  
                  
                    212
                  
                  
                     parameterResult = Encoding.UTF8.GetString(streamBytes); 
                  
                  
                    //
                  
                  
                    把body赋值给bodyStr
                  
                  
                    213
                  
                  
                      }  
                    
                //using (var reader = new StreamReader(context.HttpContext.Request.Body, Encoding.UTF8))
                        //{
                        //   var bodyRead = reader.ReadToEndAsync();
                        //   bodyStr = bodyRead.Result;  //把body赋值给bodyStr
                        //   needKey = JsonConvert.DeserializeAnonymousType
                //  (bodyRead.Result, new Dictionary<string, object>())[dependencySource].ToString();
                        //}
214 if (controllerType != typeof (ValidationController)) 215 { 216 parameterResult = ProcessFormParameters(parameterResult); 217 } 218 else 219 { 220 parameterResult = ProcessLoginUserNameParameters(parameterResult, controllerType, nameof(ValidationController), currentMethodName, out loginName); 221 } 222 } 223 224 parameterResult = ! string .IsNullOrEmpty(parameterResult) ? parameterResult : " 没有传递任何参数 " ; 225 loginName = ! string .IsNullOrEmpty(loginName) ? loginName : " anonymous " ; 226 Guid userid = Guid.Empty; 227 if ( string .IsNullOrEmpty(context.HttpContext.User.FindFirstValue(ClaimTypes.Sid)) || string .IsNullOrWhiteSpace(context.HttpContext.User.FindFirstValue(ClaimTypes.Sid))) 228 { 229 userid = Guid.Parse( " a05897f9-0c86-4f5a-a581-e5da936d0e4c " ); 230 } 231 else 232 { 233 userid = Guid.Parse(context.HttpContext.User.FindFirstValue(ClaimTypes.Sid)); 234 } 235 236 OperationLog log = new OperationLog() 237 { 238 Id = Guid.NewGuid(), 239 Name = $ " {loginName}在{currentDateTime.ToString( " yyyy-MM-dd HH:mm:ss " )}执行了{currentMethodName}操作。 " , 240 LoginName = loginName, 241 Parameters = parameterResult, 242 ActionName = $ " {controllerType.FullName}.{currentMethodName} " , 243 ActionType = methodType, 244 Message = $ " 【{loginName}】用户在【{currentDateTime.ToString( " yyyy-MM-dd HH:mm:ss " )}】执行了控制器【{controllerType.FullName}】的【{currentMethodName}】方法,执行方法的类型:{methodType},执行方法所需的参数:【{parameterResult}】,操作顺利完成。 " , 245 Remarks = " 全局日志记录器记录的日志。 " , 246 CreateUserId = userid, 247 CreateDate = currentDateTime 248 }; 249 250 try 251 { 252 MethodInfo? methodInfo; 253 if (controllerType.IsDefined( typeof (RequiredLogAttribute), false )) 254 { 255 methodInfo = controllerType.GetMethod(currentMethodName); 256 if (methodInfo != null ) 257 { 258 _logger.LogInformation(JsonConvert.SerializeObject(log)); 259 } 260 } 261 else 262 { 263 methodInfo = controllerType.GetMethod(currentMethodName); 264 if (methodInfo != null ) 265 { 266 if (methodInfo.IsDefined( typeof (RequiredLogAttribute), false )) 267 { 268 _logger.LogInformation(JsonConvert.SerializeObject(log)); 269 } 270 } 271 } 272 } 273 catch (Exception ex) 274 { 275 log.Name = $ " 异常操作日志:{loginName}在{currentDateTime.ToString( " yyyy-MM-dd HH:mm:ss " )}执行了{currentMethodName}操作。 " ; 276 log.Message = $ " 【{loginName}】用户在【{currentDateTime.ToString( " yyyy-MM-dd HH:mm:ss " )}】执行了控制器【{controllerType.FullName}】的【{currentMethodName}】方法,执行方法的类型:{methodType},执行方法所需的参数:【{parameterResult}】,操作没有完成,系统发生了异常。<br/>异常详情:{ex.Message},<br/>异常堆栈:{ex.StackTrace}。 " ; 277 278 _logger.LogInformation(JsonConvert.SerializeObject(log)); 279 } 280 281 #endregion 282 } 283 } 284 285 await next.Invoke(); 286 } 287 288 /// <summary> 289 /// 处理参数。 290 /// </summary> 291 /// <param name="parameters"> 要处理的参数字符串。 </param> 292 /// <param name="controllerType"> 控制器的类型。 </param> 293 /// <param name="controllerFullName"> 控制器的全名。 </param> 294 /// <param name="currentMethodName"> 当前调用的方法名称。 </param> 295 /// <param name="loginName"> 登录系统的用户名称。 </param> 296 /// <returns></returns> 297 private string ProcessLoginUserNameParameters( string parameters, Type controllerType, string controllerFullName, string currentMethodName, out string loginName) 298 { 299 loginName = string .Empty; 300 if (parameters.IndexOf( " &__RequestVerificationToken " ) != - 1 ) 301 { 302 parameters = parameters.Substring( 0 , parameters.LastIndexOf( " &__RequestVerificationToken " )); 303 if (( string .Compare(controllerType.FullName, controllerFullName, true ) == 0 ) && ( string .Compare(currentMethodName, " login " , true ) == 0 )) 304 { 305 if (parameters.IndexOf( " userName= " ) != - 1 ) 306 { 307 loginName = parameters.Substring( " userName= " .Length, parameters.IndexOf( " &password " ) - " &password " .Length); 308 parameters = $ " {parameters.Substring(0, parameters.LastIndexOf( " = " ) + 1)}********* " ; 309 } 310 } 311 } 312 else 313 { 314 if (( string .Compare(controllerType.FullName, controllerFullName, true ) == 0 ) && ( string .Compare(currentMethodName, " login " , true ) == 0 )) 315 { 316 if (parameters.IndexOf( " userName= " ) != - 1 ) 317 { 318 loginName = parameters.Substring( " userName= " .Length, parameters.IndexOf( " &password " ) - " &password " .Length); 319 parameters = $ " {parameters.Substring(0, parameters.LastIndexOf( " = " ) + 1)}********* " ; 320 } 321 } 322 } 323 return parameters; 324 } 325 326 /// <summary> 327 /// 返回经过处理的 Form 表单参数。 328 /// </summary> 329 /// <param name="originalFormParameters"> 未经处理的、原始的 Form 表单参数。 </param> 330 /// <returns></returns> 331 private string ProcessFormParameters( string originalFormParameters) 332 { 333 string result = " 没有 Form 表单参数。 " ; 334 if ( string .IsNullOrEmpty(originalFormParameters) || string .IsNullOrWhiteSpace(originalFormParameters)) 335 { 336 return result; 337 } 338 339 if (originalFormParameters.IndexOf( " = " ) != - 1 && (originalFormParameters.IndexOf( " = " ) != originalFormParameters.LastIndexOf( " = " ))) 340 { 341 var formParameters = originalFormParameters.Split( new string [] { " ----------------------------- " , " Content-Disposition: form-data; " }, StringSplitOptions.RemoveEmptyEntries); 342 var filterParameter = new List< string > (); 343 344 // 获取参数数据,包含=等号的就是form表单的值 345 foreach ( var parameter in formParameters) 346 { 347 if (parameter.IndexOf( " = " ) != - 1 && parameter.IndexOf( " __RequestVerificationToken " , StringComparison.CurrentCultureIgnoreCase) == - 1 ) 348 { 349 filterParameter.Add(parameter); 350 } 351 } 352 // 整理表单数据格式为:name='xxxx' value='yyyyyy'\r\nname='xxxx2' value='yyyyyy2'.... 353 if (filterParameter.Count > 0 ) 354 { 355 for ( int i = 0 ; i < filterParameter.Count; i++ ) 356 { 357 filterParameter[i] = ProcessCore(filterParameter[i]); 358 } 359 } 360 361 // 凭借结果值,并返回。 362 if (filterParameter.Count > 0 ) 363 { 364 result = string .Join( " \r\n " , filterParameter); 365 } 366 } 367 368 return result; 369 } 370 371 /// <summary> 372 /// 递归的处理参数的格式,将格式转换为 name='xxxx' value='yyyyyy'。 373 /// </summary> 374 /// <param name="parameter"> 要处理的参数。 </param> 375 /// <returns> 返回处理好的参数。 </returns> 376 private string ProcessCore( string parameter) 377 { 378 // 过滤Form表单中的图片,只获取字段名和值,具体上传文件的数据不保留。 379 if (parameter.IndexOf( " Content-Type: image/ " , StringComparison.CurrentCultureIgnoreCase) != - 1 ) 380 { 381 parameter = parameter.Substring( 0 , parameter.IndexOf( " Content-Type: image/ " )); 382 } 383 else if (parameter.IndexOf( " \" " ) != - 1 ) // 替换数据中的斜杠和双引号为单引号 384 { 385 parameter = parameter.Replace( " \" " , " ' " ); 386 } 387 else if (parameter.IndexOf( " \r\n\r\n " ) != - 1 ) 388 // 替换数据中的两个换行符为value=',格式:“name=\"Details\"\r\n\r\n<p>asdfsadfas</p><p>asdfsadf</p><p>fasdfsadfsadf</p>\r\n”== “name=\"Details\" value='<p>asdfsadfas</p><p>asdfsadf</p><p>fasdfsadfsadf</p>'” 389 { 390 parameter = parameter.Replace( " \r\n\r\n " , " value=' " ); 391 } 392 else if (parameter.EndsWith( " \r\n " )) 393 // 替换数据尾部的换行符为单引号,格式:“name=\"Details\"\r\n\r\n<p>asdfsadfas</p><p>asdfsadf</p><p>fasdfsadfsadf</p>\r\n”== “name=\"Details\"\r\n\r\n<p>asdfsadfas</p><p>asdfsadf</p><p>fasdfsadfsadf</p>'” 394 { 395 parameter = parameter.Replace( " \r\n " , " ' " ); 396 } 397 else if (parameter.IndexOf( " ; " ) != - 1 ) 398 { 399 parameter = parameter.Replace( " ; " , " " ); 400 } 401 else if (parameter.IndexOf( " '' " ) != - 1 ) 402 { 403 parameter = parameter.Replace( " '' " , " ' " ); 404 } 405 else 406 { 407 return parameter; 408 } 409 return ProcessCore(parameter); 410 } 411 412 #endregion 413 } 414

3、总结
    好了,写完了,今天又解决了一个问题,知识和技能就是在出现问题和解决问题的过程中积累的,不忘初心,继续努力,老天不会亏待努力的人。

最后此篇关于在NetCore开发中如何解决Cannotaccessadisposedobject这个问题的文章就讲到这里了,如果你想了解更多关于在NetCore开发中如何解决Cannotaccessadisposedobject这个问题的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com