iT邦幫忙

2025 iThome 鐵人賽

DAY 5
0

例子: 天氣小幫手

本章建立一個「天氣小幫手」,自動抓取台北、台中、高雄三地天氣,並輸出為靜態 HTML 檔案,搭配簡單 HTML5/CSS 美化,無需建專案、無需設定,開箱即用。

.NET 10 單檔運行特性

  • 不需 Program.csMain() 方法、namespace、甚至 using
  • 一行指令 dotnet run 天氣.cs 即可編譯+執行

使用第三方世界天氣 API

作者使用 Open-Meteo — 取得全球座標天氣資料。

API 範例:https://api.open-meteo.com/v1/forecast?latitude=25.03&longitude=121.56&current_weather=true

生成靜態 HTML 檔案

  • 使用 System.IO.File.WriteAllText() 生成展示畫面的 HTML 檔

操作步驟

步驟 2:建立 Weather.cs 天氣腳本檔案

using System.Net.Http.Json;
using System.Text;

var cities = new[]
{
    new { Name = "台北", Lat = 25.03, Lon = 121.56 },
    new { Name = "台中", Lat = 24.15, Lon = 120.66 },
    new { Name = "高雄", Lat = 22.62, Lon = 120.31 }
};

var client = new HttpClient();
var results = new List<WeatherResult>();

foreach (var city in cities)
{
    var url = $"https://api.open-meteo.com/v1/forecast?latitude={city.Lat}&longitude={city.Lon}&current_weather=true";
    var response = await client.GetFromJsonAsync<ApiResponse>(url);
    results.Add(new WeatherResult
    {
        City = city.Name,
        Temperature = response.CurrentWeather.Temperature,
        WeatherCode = response.CurrentWeather.WeatherCode
    });
}

// 生成 HTML
var html = GenerateHtml(results);
File.WriteAllText("weather.html", html, Encoding.UTF8);

Console.WriteLine("天氣資料已生成:weather.html");

// ========== 類別定義 ==========
record ApiResponse(CurrentWeather CurrentWeather);
record CurrentWeather(double Temperature, int WeatherCode);
record WeatherResult(string City, double Temperature, int WeatherCode);

// ========== HTML 生成器 ==========
string GenerateHtml(List<WeatherResult> results)
{
    var weatherDescriptions = new Dictionary<int, string>
    {
        [0] = "晴天 ☀️",
        [1] = "多雲 ⛅",
        [2] = "局部多雲 🌤",
        [3] = "陰天 🌥",
        [45] = "有霧 🌫",
        [48] = "有霧霜 🌫❄️",
        [51] = "毛毛雨 🌧",
        [61] = "小雨 🌦",
        [63] = "中雨 🌧",
        [65] = "大雨 🌧🌧",
        [71] = "小雪 ❄️",
        [73] = "中雪 ❄️❄️",
        [75] = "大雪 ❄️❄️❄️",
        [95] = "雷陣雨 ⛈",
    };

    var cards = string.Join("\n", results.Select(r => $@"
        <article class='card'>
            <h3>{r.City}</h3>
            <div class='temp'>{r.Temperature:F1}°C</div>
            <div class='desc'>{weatherDescriptions.GetValueOrDefault(r.WeatherCode, "未知天氣")}</div>
        </article>"));

    return $@"
<!DOCTYPE html>
<html lang='zh-TW'>
<head>
    <meta charset='UTF-8'>
    <title>🌤 天氣小幫手</title>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <style>
        body {{
            font-family: 'Segoe UI', system-ui, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            margin: 0;
            padding: 2rem;
            color: white;
        }}
        .container {{
            max-width: 800px;
            margin: 0 auto;
        }}
        h1 {{
            text-align: center;
            margin-bottom: 2rem;
            font-size: 2.5rem;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
        }}
        .cards {{
            display: flex;
            gap: 1.5rem;
            justify-content: center;
            flex-wrap: wrap;
        }}
        .card {{
            background: rgba(255,255,255,0.15);
            backdrop-filter: blur(10px);
            border-radius: 16px;
            padding: 1.5rem;
            text-align: center;
            width: 200px;
            box-shadow: 0 8px 32px rgba(0,0,0,0.2);
            transition: transform 0.3s;
        }}
        .card:hover {{
            transform: translateY(-5px);
        }}
        .temp {{
            font-size: 2rem;
            font-weight: bold;
            margin: 0.5rem 0;
        }}
        .desc {{
            font-size: 1rem;
            opacity: 0.9;
        }}
    </style>
</head>
<body>
    <div class='container'>
        <h1>🌤 三都即時天氣</h1>
        <div class='cards'>
            {cards}
        </div>
    </div>
</body>
</html>";
}

效果圖


上一篇
「單 cs run 模式」底層原理跟開源程式碼由來
系列文
新 .NET & Azure & IoT & AI 開源技術實戰手冊 (含深入官方程式碼講解) 5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言