You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF MVVM应用系统日期与互联网日期校验及网络判断异常问题

问题:断开互联网后CheckNetConnectivity()仍返回true,无法触发无网络提示

在WPF MVVM应用中,使用InternetGetConnectedState检测网络连接时,即使断开互联网(仅保留局域网连接),该方法依然返回true,导致无法进入无网络的提示分支。同时当前代码未处理网络请求异常,存在潜在崩溃风险。


核心原因

InternetGetConnectedState仅检测系统是否存在网络连接(如局域网),无法验证是否能访问外部互联网服务器。因此需要通过实际请求目标服务器来确认网络可用性。


解决方案

方案1:替换网络检测逻辑,直接验证目标服务器可达

将原CheckNetConnectivity改为尝试连接Google服务器(与获取时间的目标一致),确保网络真正可用:

using System;
using System.Globalization;
using System.Net.Http;

public static class DateVerifications
{
    public static bool CheckNetConnectivity()
    {
        try
        {
            using var client = new HttpClient();
            client.Timeout = TimeSpan.FromSeconds(5);
            // 发送HEAD请求,仅获取响应头,比GET更轻量高效
            var response = client.SendAsync(new HttpRequestMessage(HttpMethod.Head, "http://www.google.com")).Result;
            return response.IsSuccessStatusCode;
        }
        catch
        {
            // 任何异常(超时、连接失败等)均视为网络不可用
            return false;
        }
    }

    public static DateTime GetGoogleTime()
    {
        using var client = new HttpClient();
        client.Timeout = TimeSpan.FromSeconds(5);
        var response = client.GetAsync("http://www.google.com").Result;
        
        if (!response.Headers.Date.HasValue)
            throw new InvalidOperationException("无法获取服务器时间");
            
        return response.Headers.Date.Value.UtcDateTime;
    }
}

方案2:保留原检测,在ViewModel中捕获请求异常

如果不想修改网络检测方法,可在ViewModel中捕获GetGoogleTime的异常,当请求失败时切换到无网络提示:

private string _dtm;
public string dtm
{
    get
    {
        if (DateVerifications.CheckNetConnectivity())
        {
            try
            {
                var serverDate = DateVerifications.GetGoogleTime().ToString("dd-MM-yyyy");
                var localDate = DateTime.Today.ToString("dd-MM-yyyy");
                return _dtm = localDate == serverDate ? "System date verified!" : "System date is not correct!";
            }
            catch (Exception)
            {
                // 请求失败,说明实际无互联网
                return _dtm = "System date cannot be verified! No internet!!!";
            }
        }
        else
        {
            return _dtm = "System date cannot be verified! No internet!!!";
        }
    }
}

额外优化建议

  1. 替换HttpWebRequest为HttpClient:HttpClient是.NET官方推荐的现代网络请求类,更简洁、性能更优。
  2. 避免在属性get中执行耗时操作:网络请求是异步操作,同步执行会导致UI卡顿。建议在ViewModel构造函数中异步执行验证,通过INotifyPropertyChanged更新属性:
using System;
using System.ComponentModel;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

public class YourViewModel : INotifyPropertyChanged
{
    private string _dtm;
    public string dtm
    {
        get => _dtm;
        set
        {
            _dtm = value;
            OnPropertyChanged();
        }
    }

    public YourViewModel()
    {
        // 异步执行日期验证,不阻塞UI线程
        _ = VerifyDateAsync();
    }

    private async Task VerifyDateAsync()
    {
        try
        {
            using var client = new HttpClient();
            client.Timeout = TimeSpan.FromSeconds(5);
            
            // 先验证网络连通性
            var headResponse = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, "http://www.google.com"));
            if (!headResponse.IsSuccessStatusCode)
            {
                dtm = "System date cannot be verified! No internet!!!";
                return;
            }

            // 获取服务器时间并对比
            var getResponse = await client.GetAsync("http://www.google.com");
            if (!getResponse.Headers.Date.HasValue)
            {
                dtm = "System date cannot be verified! Server error!!!";
                return;
            }

            var serverDate = getResponse.Headers.Date.Value.UtcDateTime.ToString("dd-MM-yyyy");
            var localDate = DateTime.Today.ToString("dd-MM-yyyy");
            dtm = localDate == serverDate ? "System date verified!" : "System date is not correct!";
        }
        catch
        {
            dtm = "System date cannot be verified! No internet!!!";
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

内容的提问来源于stack exchange,提问作者Tamal Banerjee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 21:10:28