0

I want to verify whether the system date of a computer is correct by checking date from the internet when my WPF app is launched.

I've created a class for this:

public static class DateVerifications
    {
        [System.Runtime.InteropServices.DllImport("wininet.dll")]
        private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);

        public static bool CheckNetConnectivity()
        {
            int desc;
            return InternetGetConnectedState(out desc, 0);
        }
        
        public static DateTime GetGoogleTime()
        {
            var myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.google.com");
            var response = myHttpWebRequest.GetResponse();
            string todaysDates = response.Headers["date"];
            return DateTime.ParseExact(todaysDates,
                                       "ddd, dd MMM yyyy HH:mm:ss 'GMT'",
                                       CultureInfo.InvariantCulture.DateTimeFormat,
                                       DateTimeStyles.AssumeUniversal);
        }

    }

Then in my viewmodel I've created a property and bound it to a label's text/content like below:

private string _dtm;
public string dtm
{
    
    get
    {
        if (DateVerifications.CheckNetConnectivity())
        {
            if (DateTime.Today.ToString("dd-MM-yyyy") == DateVerifications.GetGoogleTime().ToString("dd-MM-yyyy"))
            {
                return _dtm="System date verified!";
            }
            
            else
                return _dtm="System date is not correct!";
        }
        
        else
            return _dtm="System date cannot be verified! No internet!!!";
    }
    
}

xaml :

    <Label
        Content="{Binding dtm}"

But the problem is even when the internet connection is off the final else statement portion of the getter doesn't get hit because CheckNetConnectivity() is returning true even when the internet is disabled.

How to get around this ?

Tamal Banerjee
  • 503
  • 3
  • 20
  • InternetGetConnectedState returns true when there is an active modern or lan adapter. It does not test if the machine has internet connection. The API you use is also not recommended by Microsoft due to its lack of reliability. Better query the DNS or ping the destination. – BionicCode Dec 21 '22 at 09:53
  • @BionicCode But the ping protocol is disabled in a lot of schools/offices, so what other ways to check for an active internet connection ? – Tamal Banerjee Dec 21 '22 at 09:55
  • You can query the DNS to resolve your destination url as suggested: https://learn.microsoft.com/en-us/dotnet/api/system.net.dns?redirectedfrom=MSDN&view=net-7.0 – BionicCode Dec 21 '22 at 09:59
  • @BionicCode Will something like `if (Dns.GetHostAddresses("google.com").Any())` instead of `if (DateVerifications.CheckNetConnectivity())` in my question code do the job ? – Tamal Banerjee Dec 21 '22 at 10:36
  • You can check here about checking internet access: https://stackoverflow.com/questions/2031824/what-is-the-best-way-to-check-for-internet-connectivity-using-net – Ohad Cohen Dec 21 '22 at 12:31
  • Yes, exactly. Note that there is an asynchronous version (`GetHostAddressesAsync`) you may consider to use. It's also important to understand that the result only guarantees access to the particular web resource. The general problem is that when testing for connectivity, you can 1) test if the network interface is up (which doesn't implies that the internet is reachable) and 2) if a particular URL is available. If an address is not available it could always mean, that the issue is related with the particular URL (or service) or the network adapter. – BionicCode Dec 21 '22 at 12:44
  • You always *need* to send something out of your local network in order to test the connectivity and the result is only valid for the particular receiver of the request. In your case, it is sufficient to test the exact resource/service you depend on. It's just important to understand that you can't test if the complete internet is available and that testing the hardware level network interface is insufficient. – BionicCode Dec 21 '22 at 12:44
  • Querying the DNS is probably the fastest way to check if a URL is reachable from a client. – BionicCode Dec 21 '22 at 12:46

1 Answers1

0

I just updated my CheckNetConnectivity method like below and it seems to work (maybe not the best way to do it but anyways):

    public static bool CheckNetConnectivity()
    {
    
        try
        {
            if (Dns.GetHostAddresses("google.com").Any())
            {
                return true;
            }
            else
                return false;
            
        }
        catch (System.Net.Sockets.SocketException x)
        {
            return false;
        }
    }
Tamal Banerjee
  • 503
  • 3
  • 20