IActionContextAccessor为Null。

6

我正在为我的.NET Core应用程序设置自定义中间件,以记录异常错误,并在Startup.cs中使用以下内容注册我的上下文:

   services.AddHttpContextAccessor();
   services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

我在我的配置文件中添加了以下内容以使用自定义中间件:

   app.UseMiddleware<CustomMiddleware>();

我的自定义中间件类如下:

 public class CustomMiddleware
 {
    private readonly RequestDelegate next;

    public CustomMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            this.BeginInvoke(context);
            await this.next.Invoke(context);
            this.EndInvoke(context);
        }
        catch(Exception ex)
        {
            //Capture the exception.
            string hostName = Environment.MachineName;
            string url = StringFunctions.getCurrentUrl(context);
            string userName = string.Empty;
            string controllerName = string.Empty;
            string actionName = string.Empty;

            //THIS IS NULL BELOW.
            IActionContextAccessor contextAccessor = context.RequestServices.GetService(typeof(IActionContextAccessor)) as IActionContextAccessor;
            RouteData routeData = contextAccessor.ActionContext.RouteData;

            if (context.User != null)
            {
                userName = context.User.Identity.Name;
            }

            if (routeData != null && routeData.Values != null)
            {
                controllerName = routeData.Values["controller"].ToString();
                actionName = routeData.Values["action"].ToString();
            }

            EventLogging.LogApplicationError(hostName, controllerName, actionName, url, userName, ex);
        }
    }

    private void BeginInvoke(HttpContext context)
    {
        //custom work here
    }

    private void EndInvoke(HttpContext context)
    {
        // Do custom work after controller execution
    }
}

我尝试从'contextAccessor'中获取ActionContext.RouteData值,但它为空。

我做错了什么?谢谢。


你确定在 Startup.cs 中已经注册了 IActionContextAccessor 吗? - Bigabdoul
我在我的Startup.cs文件的ConfigureServices函数中有以下代码:services.AddSingleton<IActionContextAccessor, ActionContextAccessor>(); - Zack Antony Bucci
1个回答

3

IActionContextAccessor.ActionContext在mvc中间件的作用域外是空的。

如果您在异常处理程序中只关心MVC操作,那么您可以创建一个操作筛选器来捕获和记录异常,而不是使用中间件。

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        //Capture the exception.
        string hostName = Environment.MachineName;
        string url = StringFunctions.getCurrentUrl(context.HttpContext);
        string userName = string.Empty;
        string controllerName = string.Empty;
        string actionName = string.Empty;

        if (context.HttpContext.User != null)
        {
            userName = context.HttpContext.User.Identity.Name;
        }

        controllerName = context.RouteData.Values["controller"].ToString();
        actionName = context.RouteData.Values["action"].ToString();

        EventLogging.LogApplicationError(hostName, controllerName, actionName, url, userName, ex);
    }
}

GetCurrentUrl方法需要HttpContext而不是ExceptionContext,所以我猜我必须为此注入IHttpAccessorContext? - Zack Antony Bucci
您可以通过 context.HttpContext 访问它。我已经更新了代码。 - Kahbazi
谢谢。我已经在我的服务中注册了它,使用services.AddMvc(config => config.Filters.Add(new CustomExceptionFilter())).SetCompatibilityVersion(CompatibilityVersion.Version_2_2); 在所有控制器中都可以正常工作。 - Zack Antony Bucci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接