C# WPF开发如何发起GET请求调用Sunrise Sunset API
C# WPF 对接日出日落API实现方案
先补两个你需要的基础概念:
- GET请求:HTTP协议最常用的请求方法之一,逻辑是按约定规则把参数拼在请求地址后,向服务器发起索取数据的请求,不需要提交复杂的请求体。你要对接的这个日出日落API是无鉴权公开接口,不需要传密钥,对新手非常友好。
- 你问题里写的接口地址格式有误,正确的请求根地址是
https://api.sunrise-sunset.org/json,直接访问这个根地址会报错,必须携带要求的参数才能正常返回数据。
第一步:明确接口传参规则
参数直接拼在请求根地址后面,用?开头,参数之间用&分隔,常用参数如下:
lat:必填,目标位置的纬度,数值类型lng:必填,目标位置的经度,数值类型date:选填,要查询的日期,格式为YYYY-MM-DD,不传默认查询当天数据formatted:选填,传0返回标准UTC时间格式,方便C#直接转成时间类型;传1返回预格式化的字符串,默认值为1
你可以先拼一个测试地址,直接贴到浏览器地址栏验证是否能正常返回数据,比如查询北京当天日出日落、返回标准时间格式的地址为:https://api.sunrise-sunset.org/json?lat=39.9042&lng=116.4074&formatted=0
确认浏览器能正常返回JSON结构后,再开始写代码,能省很多排错时间。
第二步:项目准备
新建WPF项目后,不需要额外安装第三方Nuget包,用.NET自带组件即可实现全部功能:
- 用
HttpClient发起GET请求 - 用
System.Text.Json解析返回的JSON数据
注意:HttpClient建议做全局单例,不要每次请求都新建实例,否则会触发套接字耗尽问题。
第三步:核心代码实现
首先在App.xaml.cs里注册全局单例的HttpClient:
public partial class App : Application { public static HttpClient SharedHttpClient { get; } = new HttpClient(); }
定义和接口返回结构匹配的实体类,方便直接反序列化数据:
public class SunriseSunsetApiResult { public SunriseSunsetData Results { get; set; } public string Status { get; set; } } public class SunriseSunsetData { public DateTimeOffset Sunrise { get; set; } public DateTimeOffset Sunset { get; set; } // 如果需要昼长、晨昏蒙影时间等其他字段,照着接口返回的JSON结构加对应属性即可 }
封装请求方法,注意接口默认返回UTC时间,需要转成本地时间再展示:
public async Task<(DateTimeOffset? sunrise, DateTimeOffset? sunset, string errorMsg)> GetSunriseSunsetTime(double lat, double lng, DateTime? queryDate = null) { try { // 拼接合法请求地址 var dateStr = queryDate.HasValue ? queryDate.Value.ToString("yyyy-MM-dd") : DateTime.Today.ToString("yyyy-MM-dd"); var requestUrl = $"https://api.sunrise-sunset.org/json?lat={lat}&lng={lng}&date={dateStr}&formatted=0"; // 发起GET请求 var response = await App.SharedHttpClient.GetAsync(requestUrl); response.EnsureSuccessStatusCode(); // 接口返回4xx/5xx错误时直接抛出异常,统一捕获处理 // 读取并解析返回内容 var responseContent = await response.Content.ReadAsStringAsync(); var parseResult = JsonSerializer.Deserialize<SunriseSunsetApiResult>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); if (parseResult.Status != "OK") { return (null, null, $"接口返回异常:{parseResult.Status}"); } // UTC时间转本地时间 var localSunrise = parseResult.Results.Sunrise.ToLocalTime(); var localSunset = parseResult.Results.Sunset.ToLocalTime(); return (localSunrise, localSunset, null); } catch (Exception ex) { return (null, null, $"请求失败:{ex.Message}"); } }
第四步:WPF界面交互实现
先在MainWindow.xaml里写基础界面:
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Margin="20"> <TextBlock x:Name="LatInputTip" Text="纬度:39.9042(北京)" Margin="0 5"/> <TextBlock x:Name="LngInputTip" Text="经度:116.4074(北京)" Margin="0 5"/> <Button x:Name="QueryBtn" Content="查询日出日落时间" Click="QueryBtn_Click" Margin="0 10" Padding="12 6"/> <TextBlock x:Name="SunriseShow" Margin="0 5" FontSize="14"/> <TextBlock x:Name="SunsetShow" Margin="0 5" FontSize="14"/> <TextBlock x:Name="ErrorShow" Foreground="Red" Margin="0 5" TextWrapping="Wrap"/> </StackPanel>
在MainWindow.xaml.cs里加按钮点击的事件逻辑,初期可以先写死经纬度测试,跑通后再接入系统定位API获取用户真实位置:
private async void QueryBtn_Click(object sender, RoutedEventArgs e) { QueryBtn.IsEnabled = false; ErrorShow.Text = string.Empty; try { // 测试阶段先写死经纬度,后续替换为定位拿到的真实经纬度即可 double lat = 39.9042; double lng = 116.4074; var (sunrise, sunset, error) = await GetSunriseSunsetTime(lat, lng); if (!string.IsNullOrEmpty(error)) { ErrorShow.Text = error; return; } SunriseShow.Text = $"日出时间:{sunrise.Value:yyyy年MM月dd日 HH:mm:ss}"; SunsetShow.Text = $"日落时间:{sunset.Value:yyyy年MM月dd日 HH:mm:ss}"; } finally { QueryBtn.IsEnabled = true; } }
新手常见避坑提醒
- 不要每次发请求都new一个HttpClient,全局共用一个单例实例即可
- 接口默认返回UTC时区时间,东八区直接显示会比实际时间早8小时,一定要调用
ToLocalTime()转成本地时间 - 后续如果要获取用户真实位置,可以调用Windows自带的
Windows.Devices.Geolocation定位API,记得先在应用清单里开启定位权限 - 如果请求报错,先把拼接好的地址复制到浏览器访问,确认地址本身能正常返回数据再排查代码问题
内容的提问来源于stack exchange,提问作者44ay_
相关产品推荐
相关产品推荐

