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";
}
}
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:
/// <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.