发生异常时如何检索发布到web api端点的对象?

时间:2017-08-31 04:44:29

标签: c# asp.net-web-api serialization exception-handling httprequest

我有一个Web Api End point和Exception处理程序。当出现问题时,我想知道发布到端点的内容。我如何实现这一目标?

//In my controller
[Route("send/postmodel")]
[HttpPost]
public IHttpActionResult PostModel(MyModel model)
{
    //Exception occured
}

//My Exception Handler
public class ApiExceptionHandler : ExceptionHandler
{
    public override void Handle(ExceptionHandlerContext context)
    {
        //How do i retrive the object here
    }
}

我试过在ExceptionHandlerContext中查看HttpRequestMessage和HttpRequestContext,但没有运气。

1 个答案:

答案 0 :(得分:1)

您可以使用DelegatingHandler记录您发送和接收的每个请求和响应,这将有助于您记录您的例外情况。

代码段

 public class ApiLogHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var apiLogEntry = CreateApiLogEntryWithRequestData(request);

        if (request.Content != null)
        {
            request.Content.ReadAsStringAsync()
               .ContinueWith(task =>
               {
                   apiLogEntry.RequestContentBody = task.Result;
               }, cancellationToken);
        }

        return base.SendAsync(request, cancellationToken)
            .ContinueWith(task =>
            {
                var response = task.Result;

                // Update the API log entry with response info
                apiLogEntry.ResponseStatusCode = (int)response.StatusCode;
                apiLogEntry.ResponseTimestamp = DateTime.Now;

                if (response.Content != null)
                {
                    apiLogEntry.ResponseContentBody = response.Content.ReadAsStringAsync().Result;
                    apiLogEntry.ResponseContentType = response.Content.Headers.ContentType.MediaType;
                    apiLogEntry.ResponseHeaders = SerializeHeaders(response.Content.Headers);
                }

                // TODO: Save the API log entry to the database
                InsertAPILog(apiLogEntry);


                return response;
            }, cancellationToken);
    }

    private ApiLogEntry CreateApiLogEntryWithRequestData(HttpRequestMessage request)
    {
        var context = ((HttpContextBase)request.Properties["MS_HttpContext"]);
        var routeData = request.GetRouteData();

        return new ApiLogEntry
        {
            Application = "[Logging]",
            User = context.User.Identity.Name,
            Machine = Environment.MachineName,
            RequestContentType = context.Request.ContentType,
            RequestRouteTemplate = routeData.Route.RouteTemplate,
            RequestRouteData = SerializeRouteData(routeData),
            RequestIpAddress = context.Request.UserHostAddress,
            RequestMethod = request.Method.Method,
            RequestHeaders = SerializeHeaders(request.Headers),
            RequestTimestamp = DateTime.Now,
            RequestUri = request.RequestUri.ToString()
        };
    }

    private string SerializeRouteData(IHttpRouteData routeData)
    {
        return JsonConvert.SerializeObject(routeData, Formatting.Indented);
    }

    private string SerializeHeaders(HttpHeaders headers)
    {
        var dict = new Dictionary<string, string>();

        foreach (var item in headers.ToList())
        {
            if (item.Value != null)
            {
                var header = String.Empty;
                foreach (var value in item.Value)
                {
                    header += value + " ";
                }

                // Trim the trailing space and add item to the dictionary
                header = header.TrimEnd(" ".ToCharArray());
                dict.Add(item.Key, header);
            }
        }

        return JsonConvert.SerializeObject(dict, Formatting.Indented);
    }

    private void InsertAPILog(ApiLogEntry apiLogEntry)
    {
        try
        {
            using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["API_Logging"].ToString()))
            {
                con.Open();
                SqlCommand cmd = new SqlCommand("API_LoggingRequest", con);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@Application", apiLogEntry.Application);
                cmd.Parameters.AddWithValue("@User", apiLogEntry.User);
                cmd.Parameters.AddWithValue("@Machine", apiLogEntry.Machine);
                cmd.Parameters.AddWithValue("@RequestIpAddress", apiLogEntry.RequestIpAddress);
                cmd.Parameters.AddWithValue("@RequestContentType", apiLogEntry.RequestContentType);
                cmd.Parameters.AddWithValue("@RequestContentBody", apiLogEntry.RequestContentBody);
                cmd.Parameters.AddWithValue("@RequestUri", apiLogEntry.RequestUri);
                cmd.Parameters.AddWithValue("@RequestMethod", apiLogEntry.RequestMethod);
                cmd.Parameters.AddWithValue("@RequestRouteTemplate", apiLogEntry.RequestRouteTemplate);
                cmd.Parameters.AddWithValue("@RequestRouteData", apiLogEntry.RequestRouteData);
                cmd.Parameters.AddWithValue("@RequestHeaders", apiLogEntry.RequestHeaders);
                cmd.Parameters.AddWithValue("@RequestTimestamp", apiLogEntry.RequestTimestamp);
                cmd.Parameters.AddWithValue("@ResponseContentType", apiLogEntry.ResponseContentBody);
                cmd.Parameters.AddWithValue("@ResponseContentBody", apiLogEntry.ResponseContentBody);
                cmd.Parameters.AddWithValue("@ResponseStatusCode", apiLogEntry.ResponseStatusCode);
                cmd.Parameters.AddWithValue("@ResponseHeaders", apiLogEntry.ResponseHeaders);
                cmd.Parameters.AddWithValue("@ResponseTimestamp", apiLogEntry.ResponseTimestamp);
                cmd.ExecuteNonQuery();
            }
        }
        catch (Exception)
        {
            throw;
        }
    }

}