c# – 获取ASP.NET Core中发生异常的行号

前端之家收集整理的这篇文章主要介绍了c# – 获取ASP.NET Core中发生异常的行号前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经基于此博客 https://blog.kloud.com.au/2016/03/23/aspnet-core-tips-and-tricks-global-exception-handling/实现了自定义异常过滤器.

我现在注意到我无法从StackFrame获取发生异常的文件名或行号;方法GetFileLineNumber的值始终为0.

我试过的一个简单示例:

StackTrace trace = new StackTrace(exception,true);
StackFrame[] stackFrames = trace.GetFrames();
if (stackFrames != null) {
 foreach (StackFrame traceFrame in stackFrames) {
   sourceFile = traceFrame.GetFileName();
   sourceLineNumber = traceFrame.GetFileLineNumber();
  }
}

要提一下:GetFileName也返回null,但我可以从不同的位置获取命名空间和类名,所以这不是问题.

在某个地方注意到我应该在文件夹上有PDB文件才能工作,我检查过我已经拥有它.即使它起作用,它也应该在生产环境中起作用.

尝试也使用来电者信息(https://msdn.microsoft.com/en-us/library/mt653988.aspx),但有一个不同的问题.异常过滤器必须实现IExceptionFilter接口并使用它的方法.因此,即使它们是可选的,我也无法添加属性.

这是Startup.cs的代码部分:

public void ConfigureServices(IServiceCollection services) {
 ...
 services.AddMvc(config => {
  config.Filters.Add(new ApplicationExceptionFilter());
 });
}

这是自定义过滤器

public class ApplicationExceptionFilter : IExceptionFilter {
 public void OnException(ExceptionContext context) {
  ApplicationExceptionHandler.handleException(context.HttpContext,context.Exception);
 }
}

我尝试获取来电者信息的原因是:

public void OnException(ExceptionContext context,[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0) {

但这不起作用,因为它不再实现接口.

如何在仍然在一个地方处理异常的同时获取行号?

假设我的问题是我没有从堆栈跟踪获取行号并重现问题:

public ActionResult ServerError() {
 Int32 x = 0;
 try {
  return Content((1 / x).ToString());
 } catch (Exception ex) {
  StackTrace trace = new StackTrace(ex,true);
  StackFrame[] stackFrames = trace.GetFrames();
  if (stackFrames != null) {
   foreach (StackFrame traceFrame in stackFrames) {
    String sourceFile = traceFrame.GetFileName();
    int sourceLineNumber = traceFrame.GetFileLineNumber();
   }
  }
 }
 return Content("");
}

仍然没有获得sourceFile(它为null)或sourceLineNumber(它为0)的值.

解决方法

看一下DeveloperErrorPageMiddleware implementation
private IEnumerable<ErrorDetails> GetErrorDetails(Exception ex)
    {
        for (var scan = ex; scan != null; scan = scan.InnerException)
        {
            var stackTrace = ex.StackTrace;
            yield return new ErrorDetails
            {
                Error = scan,StackFrames = StackTraceHelper.GetFrames(ex)
                    .Select(frame => GetStackFrame(frame.MethodDisplayInfo.ToString(),frame.FilePath,frame.LineNumber))
            };
        };
    }

    // make it internal to enable unit testing
    internal StackFrame GetStackFrame(string method,string filePath,int lineNumber)
    {
        var stackFrame = new StackFrame
        {
            Function = method,File = filePath,Line = lineNumber
        };

        if (string.IsNullOrEmpty(stackFrame.File))
        {
            return stackFrame;
        }

        IEnumerable<string> lines = null;
        if (File.Exists(stackFrame.File))
        {
            lines = File.ReadLines(stackFrame.File);
        }
        else
        {
            // Handle relative paths and embedded files
            var fileInfo = _fileProvider.GetFileInfo(stackFrame.File);
            if (fileInfo.Exists)
            {
                // ReadLines doesn't accept a stream. Use ReadLines as its more efficient
                // relative to reading lines via stream reader
                if (!string.IsNullOrEmpty(fileInfo.PhysicalPath))
                {
                    lines = File.ReadLines(fileInfo.PhysicalPath);
                }
                else
                {
                    lines = ReadLines(fileInfo);
                }
            }
        }

        if (lines != null)
        {
            ReadFrameContent(stackFrame,lines,stackFrame.Line,stackFrame.Line);
        }

        return stackFrame;
    }

猜你在找的.NET Core相关文章