Home > Back-end >  ASP.NET MVC 5: is there anyway to get the client IP in the Global.asax file?
ASP.NET MVC 5: is there anyway to get the client IP in the Global.asax file?

Time:08-14

I'm working on an ASP.NET MVC application running on .NET 4.7.2.

We use DevExpress controls and add a lot of startup items in the Global.asax file in Application_Start().

Some of the settings are adding are for error handling on their controls for unhandled exceptions etc.

I can't seem to find the right way to get the IP address. I understand Application_Start() does not track each request, but is there a way to do this?

I've tried this:

    /// <summary>
    /// Gets the IP address.
    /// </summary>
    /// <returns>IP address</returns>
    private static string GetIpAddress()
    {
        try
        {
            string strHostName = System.Net.Dns.GetHostName();
            return System.Net.Dns.GetHostAddresses(strHostName).GetValue(0).ToString();
        }
        catch
        {
            return "IP Not Available";
        }
    }

    /// <summary>
    /// Handles the Error event of the Application control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    protected void Application_Error(object sender, EventArgs e)
    {
        var exception = HttpContext.Current.Server.GetLastError();

        using (var errorService = DependencyResolver.Current.GetService<ApplicationService>())
        {
            errorService.CreateEventLogSync(new EventLogCreateDTO()
            {
                EventCategory = "Global Error (Application_Error)",
                EventDescription = exception.ToString(),
                EventLogDate = DateTime.UtcNow,
                EventSourceDescription = $"{GetIpAddress()} | {exception.Message ?? "No message available"}",
                EventType = EventLogType.Error
            });
        }
    }

Here is what it generates when deploying the code and causing an error on our Azure instance:

10.0.3.30 | Year, Month, and Day parameters describe an un-representable DateTime

I understand this is a private IP address and not really want I to log when an error occurs.

So is there another way to try to obtain the IP address when an error occurs?

UPDATE 2:

It tried something like this by adding this code to a static class to be called from the Global.asasx file where I need to get the error:

    /// <summary>
    /// Gets the IP address.
    /// </summary>
    /// <returns>IP address</returns>
    public static string GetIpAddress()
    {
        try
        {
            string ip = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

            if (string.IsNullOrEmpty(ip))
            {
                ip = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }

            return ip;
        }
        catch
        {
            return "IP Not Available";
        }
    }

enter image description here

But .Request is null and therefore throws an error.

Update 3:

I tried it directly in the Application_Error() call within my Global.asasx file but this is the error:

enter image description here

    /// <summary>
    /// Handles the Error event of the Application control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    protected void Application_Error(object sender, EventArgs e)
    {
        var exception = HttpContext.Current.Server.GetLastError();

        string ipAddress = HttpContext.Current.Request.Headers["X-Forwarded-For"];
        if (ipAddress == null)
        {
            ipAddress = HttpContext.Current.Request.UserHostAddress;
        }

        using (var errorService = DependencyResolver.Current.GetService<ApplicationService>())
        {
            errorService.CreateEventLogSync(new EventLogCreateDTO()
            {
                EventCategory = "Global Error (Application_Error)",
                EventDescription = exception.ToString(),
                EventLogDate = DateTime.UtcNow,
                EventSourceDescription = $"{ipAddress} | {exception.Message ?? "No message available"}",
                EventType = EventLogType.Error
            });
        }
    }

CodePudding user response:

Something like this should be possible:

string ipAddress = HttpContext.Current.Request.Headers["X-Forwarded-For"];
if (ipAddress == null)
{
    ipAddress = HttpContext.Current.Request.UserHostAddress;
}

First check XFF header and if it's empty, check directly HttpRequest's client IP address.

  • Related