2017-02-22 172 views
0

越來越routetemplate值我有一個名爲的每個請求我的API中間件。我想記錄路線模板以及來自這個中間件的請求的持續時間。如何在我的中間件代碼中獲得路由模板?路線模板類似於「/ products/{productId}」。ASP.Net核心 - 從中​​間件

回答

2

這並不容易,因爲它是由MVC中間件通常恰好是在ASP.NET核心管線要執行的最後中間件創建從自定義中間件獲得路由數據。

如果你想登錄爲下方的中間件的請求和響應,

public async Task Invoke(HttpContext context) 
    { 
     var requestBodyStream = new MemoryStream(); 
     var originalRequestBody = context.Request.Body; 

     await context.Request.Body.CopyToAsync(requestBodyStream); 
     requestBodyStream.Seek(0, SeekOrigin.Begin); 

     var url = UriHelper.GetDisplayUrl(context.Request); 
     var requestBodyText = new StreamReader(requestBodyStream).ReadToEnd(); 
     _logger.Log(LogLevel.Information, 1, $"REQUEST METHOD: {context.Request.Method}, REQUEST BODY: {requestBodyText}, REQUEST URL: {url}", null, _defaultFormatter); 

     requestBodyStream.Seek(0, SeekOrigin.Begin); 
     context.Request.Body = requestBodyStream; 

     await next(context); 
       var bodyStream = context.Response.Body; 

    var responseBodyStream = new MemoryStream(); 
    context.Response.Body = responseBodyStream; 

    await _next(context); 

    responseBodyStream.Seek(0, SeekOrigin.Begin); 
    var responseBody = new StreamReader(responseBodyStream).ReadToEnd(); 
    _logger.Log(LogLevel.Information, 1, $"RESPONSE LOG: {responseBody}", null, _defaultFormatter); 
    responseBodyStream.Seek(0, SeekOrigin.Begin); 
    await responseBodyStream.CopyToAsync(bodyStream); 
    } 

但是,如果你是在路由數據真正感興趣,有非常漂亮的SO回答來實現獲取路線miidleware here

其它可供選擇的方法是使用爲Action Filters請求/響應日誌記錄。

+0

你的代碼示例記錄了實際的請求url。我想記錄路線模板。而不是/ products/product123我想記錄/ products/{productId}。不過,我可以使用動作過濾器來獲得此功能。感謝那些信息。 – sathya

0

這是我如何得到它的工作。我在我的過濾器OnActionExecuting方法中獲取路由模板並將其添加到HttpContext。後來,我從中間件內部的HttpContext訪問它,因爲我可以在中間件內部訪問HttpContext。

public class LogActionFilter : IActionFilter 
    { 
     public LogActionFilter() 
     { 
     } 
     public void OnActionExecuted(ActionExecutedContext context) 
     { 

     } 

     public void OnActionExecuting(ActionExecutingContext context) 
     { 
      context.HttpContext.Items.Add("RouteTemplate", context.ActionDescriptor.AttributeRouteInfo.Template); 
     } 
    }