簡體   English   中英

ASP .NET Web API:跟蹤偵聽器:HTTP / 1.1 500內部服務器錯誤:怎么了?

[英]ASP .NET Web API: Trace Listeners: HTTP/1.1 500 Internal Server Error: What's wrong?

我已經使用.NET了一段時間,但這是我的第一個Web API 2項目。 這是一場艱苦的斗爭,所以請放輕松。 關於Web API的某些事情可能認為那里的文章已經是已知的,顯而易見的或顯而易見的,但是直到您嘗試找出例如“ {id}”參數為“ magic”后才真正知道。 ”,並應盡可能使用。

牢記這一點,為了幫助進一步排除應用程序故障,我嘗試使用Trace Listeners和NLog啟用日志記錄,並使用了幾篇出色的文章作為指南,其中包括以下兩篇文章:

我正在嘗試使用跟蹤偵聽器和NLog來運行ASP .NET Web API服務,以幫助我們記錄性能較慢的應用程序中的關鍵點並為其添加時間戳。

但是,當我從Fiddler測試控制器時,出現如下異常:

 HTTP/1.1 500 Internal Server Error Cache-Control: no-cache Pragma: no-cache Content-Type: application/json; charset=utf-8 Expires: -1 Server: Microsoft-IIS/10.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Fri, 04 Aug 2017 18:45:11 GMT Content-Length: 3617 {"Message":"An error has occurred.", "ExceptionMessage":"Value cannot be null.\\r\\nParameter name: traceWriter","ExceptionType":"System.ArgumentNullException","StackTrace":" at System.Web.Http.Tracing.ITraceWriterExtensions.Trace(ITraceWriter traceWriter, HttpRequestMessage request, String category, TraceLevel level, String messageFormat, Object[] messageArguments)\\r\\n at PURL_WebMarketing_API.Controllers.VisitorFormController.<GetFormInfo>d__3.MoveNext()\\r\\n--- End of stack trace from previous location where exception was thrown ---" } 

我正在使用Visual Studio 2015,.NET Framework 4.5和用於NLog,ASP.NET Web API和ASP.NET Web API跟蹤的最新NuGet軟件包。

現在查看代碼...

從App_Start / WebApiConfig.cs:

// Enable tracing
config.EnableSystemDiagnosticsTracing();

// Replace the default trace writer with my own custom handler
config.Services.Replace(typeof(System.Web.Http.Tracing.ITraceWriter), new Utilities.TraceHandler());

在VisitorFormController.cs中:

public class VisitorFormController : ApiController
{
    private IDataAccessRepository _repository;
    private readonly ITraceWriter _tracer;


    public VisitorFormController(IDataAccessRepository repository): base()
    {
        _repository = repository;

        if (Request != null)
        {
            _tracer = Request.GetConfiguration().Services.GetTraceWriter();
        }
    }

[HttpGet]
        [Route("api/VisitorForm/{code}/{pageType}")]
        [EnableCors(origins: "*", headers: "*", methods: "options,get")]
        public async Task<IHttpActionResult> GetFormInfo(string code, string pageType)
        {
            DateTime startTime = DateTime.Now;

            if (string.IsNullOrEmpty(code))
                return BadRequest("Invitation code is required.");

            if (!IsValidPageType(pageType))
                return BadRequest("Valid page types may be 'post', 'info', 'No Code' or blank.");

            if (Request != null)
            {
                string startLogMessage = CustomLogMessageBuilder.GetLogMessage(CustomLogMessageBuilder.StandardStartEventNames.EVENT_TYPE_VISITOR_FORM_REQ_START);
                _tracer.Info(Request, this.ControllerContext.ControllerDescriptor.ControllerType.FullName, startLogMessage);
            }

            // *** Work happens here
            RecipientModel visitorFormInformation =  _repository.GetVisitorFormInformation(code, pageType);
            // ***

            if (visitorFormInformation == null)
                return NotFound();

            if (Request != null)
            {
                string endLogMessage = CustomLogMessageBuilder.GetLogMessage(CustomLogMessageBuilder.StandardEndEventNames.EVENT_TYPE_VISITOR_FORM_REQ_END, startTime);
                _tracer.Info(Request, this.ControllerContext.ControllerDescriptor.ControllerType.FullName, endLogMessage);
            }

            try
            {
                DateTime startLogActivityTime = DateTime.Now;

                if (Request != null)
                {
                    string startLogMessage = CustomLogMessageBuilder.GetLogMessage(CustomLogMessageBuilder.StandardStartEventNames.EVENT_TYPE_UPDATE_VISIT_LOG_FORM_VIEWED_START);
                    _tracer.Info(Request, this.ControllerContext.ControllerDescriptor.ControllerType.FullName, startLogMessage);
                }

                // Log visitor activity, asynchronously
                await _repository.LogActivity(visitorFormInformation.RecipientId, visitorFormInformation.IsCompleted);

                if (Request != null)
                {
                    string endLogMessage = CustomLogMessageBuilder.GetLogMessage(CustomLogMessageBuilder.StandardEndEventNames.EVENT_TYPE_UPDATE_VISIT_LOG_FORM_VIEWED_END, startLogActivityTime);
                    _tracer.Info(Request, this.ControllerContext.ControllerDescriptor.ControllerType.FullName, endLogMessage);
                }
            }
            catch
            {
                return BadRequest("Recipient ID#" + visitorFormInformation.RecipientId.ToString() + " not found.");
            }

            return Ok(visitorFormInformation);
        }

要查看我的自定義跟蹤處理程序,請參閱上面發布的Filip Wojcieszyn的博客文章。 我的版本幾乎相同,因此為簡潔起見,我將其省略。

如果我正在做有關跟蹤偵聽器使用的所有工作,這可能是我要傳遞的東西嗎? 在當前狀態下,只要禁用了跟蹤偵聽器,該服務就可以工作。

在有人問之前,我已經在各種瀏覽器中進行了嘗試。 但我能提供幫助,對於任何有用的評論和建議,我將不勝感激。 謝謝!

問題是HttpContext的是尚未控制器,這就是為什么的構造函數可用的Request屬性為空,這將導致_tracer為空,這將導致任何函數調用_tracer拋出ArgumentNullException

我建議您閱讀更多有關WebApi管道的信息,例如在這里 它告訴您控制器的構造方式以及入站請求在什么時候發生。

簡而言之:解決方案是不將_tracer存儲在控制器級別,而是存儲在正在執行的動作中,並在每個動作調用中獲取一個“ new”跟蹤器。

public class VisitorFormController : ApiController
{
    private IDataAccessRepository _repository;

    public VisitorFormController(IDataAccessRepository repository): base()
    {
        _repository = repository;
    }

    [HttpGet]
    [Route("api/VisitorForm/{code}/{pageType}")]
    [EnableCors(origins: "*", headers: "*", methods: "options,get")]
    public async Task<IHttpActionResult> GetFormInfo(string code, string pageType)
    {
       var tracer = Request.GetConfiguration().Services.GetTraceWriter();

       // Use tracer from here on...
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM