Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpRequest describable to string

I'm using asp.net core v2.1 with C# and made a small website. This website has ExceptionsTracker that catching all the unhandeled exceptions.

internal class ExceptionTracker : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        // ...
        string httpRequestInformation;
        try
        {
            httpRequestInformation = context.HttpContext.Request.ToString(); // The problem here.
        }
        catch (Exception)
        {
            httpRequestInformation = string.Empty;
        }
        // ...
    }
}

The main idea behind this is to write all the exception to log and be able to reproduce it on development (run the same query that made the exception).

When I made this line with the previous .NET framework (v4.6) context.HttpContext.Request.ToString(), the return value was a string that contain all the information from the request (requested URL, headers, body, ...). When I'm doing it with .net core, the return value is

Microsoft.AspNetCore.Http.Internal.DefaultHttpRequest

Do you have better solution then to construct this string manually?

Thanks!

Update

According to @kennyzx recommendation, I made a short Method extension to solve this problem.

public static class HttpRequestExtensions
{
    public static string GetDetails(this HttpRequest request)
    {
        string baseUrl = $"{request.Scheme}://{request.Host}{request.Path}{request.QueryString.Value}";
        StringBuilder sbHeaders = new StringBuilder();
        foreach (var header in request.Headers)
            sbHeaders.Append($"{header.Key}: {header.Value}\n");

        string body = "no-body";
        if (request.Body.CanSeek)
        {
            request.Body.Seek(0, SeekOrigin.Begin);
            using (StreamReader sr = new StreamReader(request.Body))
                body = sr.ReadToEnd();
        }

        return $"{request.Protocol} {request.Method} {baseUrl}\n\n{sbHeaders}\n{body}";
    }
}

If you have better solution, let me know.

like image 962
No1Lives4Ever Avatar asked Aug 07 '18 05:08

No1Lives4Ever


1 Answers

You get

a string that contain all the information from the request (requested URL, headers, body, ...).

by calling ToString() in v4.6 because the class overrides System.Object.ToString() method, but in asp.net core v2.1 it does not, so it just prints the full qualified name of the class, which is the default return value of the System.Object.ToString().

You can do it yourself, by constructing the string from the various properties it provides. You can write an extension method like

public static class MyExtensionClass 
{
    public static string GetDetails(this Microsoft.AspNetCore.Http.Internal.DefaultHttpRequest request)
    {
        return request.PathString.Value + " " + ... ; //Construct your string here 
    }
}

And use it like

httpRequestInformation = context.HttpContext.Request.GetDetails(); 
like image 156
kennyzx Avatar answered Nov 02 '22 17:11

kennyzx