C#でJsonを扱う Json.Net DeserializeObject編

2021-03-14

C#でJsonを扱う DynamicJson編
C#でJsonを扱う Json.Net JToken/JObject/JArray編
C#でJsonを扱う Json.Net DeserializeObject編
・C#でJsonを扱う System.Text.Json編

Json.Netについて

Json.NET – Newtonsoft

App.xaml

<Application x:Class="WpfApp7.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApp7"
             StartupUri="View\MainView.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

WeatherEntity.cs

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp7.DataEntity
{
    [JsonObject]
    public class WeatherEntity
    {
        [JsonProperty("forecasts")]
        public List<ForecastsEntity> Forecasts { get; set; }

        [JsonProperty("title")]
        public string Title { get; set; }

        [JsonProperty("description")]
        public DescriptionEntity Description { get; set; }
    }

    [JsonObject("forecasts")]
    public class ForecastsEntity
    {
        [JsonProperty("dateLabel")]
        public string DateLabel { get; set; }

        [JsonProperty("telop")]
        public string Telop { get; set; }

        [JsonProperty("date")]
        public string Date { get; set; }

        [JsonProperty("image")]
        public ForecastsImageEntity Image { get; set; }
    }

    [JsonObject("image")]
    public class ForecastsImageEntity
    {
        [JsonProperty("width")]
        public int Width { get; set; }

        [JsonProperty("url")]
        public string Url { get; set; }

        [JsonProperty("title")]
        public string Title { get; set; }

        [JsonProperty("height")]
        public int Height { get; set; }
    }

    [JsonObject("description")]
    public class DescriptionEntity
    {
        [JsonProperty("text")]
        public string Text { get; set; }

        [JsonProperty("publicTime")]
        public DateTime PublicTime { get; set; }
    }
}

MainView.xaml

<Window x:Class="WpfApp7.View.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
        xmlns:local="clr-namespace:WpfApp7.View"
        xmlns:vm="clr-namespace:WpfApp7.ViewModel"
        mc:Ignorable="d"
        Title="MainView" Height="450" Width="800">

    <Window.DataContext>
        <vm:MainViewModel/>
    </Window.DataContext>

    <i:Interaction.Triggers>
        <i:EventTrigger EventName ="ContentRendered">
            <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="OnContentRendered" />
        </i:EventTrigger>
    </i:Interaction.Triggers>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="{Binding Path=Weather.Title}"/>

        <ListView Grid.Row="1" Grid.Column="0" ItemsSource="{Binding Path=Weather.Forecasts}">
            <ListView.Style>
                <Style TargetType="ListView">
                    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Visible"/>
                    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/>
                </Style>
            </ListView.Style>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Label Content="{Binding Path=Date}"/>
                        <Image Source="{Binding Path=Image.Url}"/>
                        <Label Content="{Binding Path=Telop}"/>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <Label Grid.Row="2" Grid.Column="0" Content="{Binding Path=Weather.Description.Text}"/>
    </Grid>
</Window>

MainViewModel.cs

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace WpfApp7.ViewModel
{
    public class MainViewModel : Livet.ViewModel
    {
        private DataEntity.WeatherEntity _Weather = null;
        public DataEntity.WeatherEntity Weather
        {
            get
            {
                return _Weather;
            }
            set
            {
                _Weather = value;
                RaisePropertyChanged();
            }
        }

        public void OnContentRendered()
        {
            string strSource = "";

            using (System.Net.WebClient objWebClient = new System.Net.WebClient())
            {
                // JSONデータの取得
                strSource = objWebClient.DownloadString("http://weather.livedoor.com/forecast/webservice/json/v1?city=130010");
            }

            // Unicodeエスケープ文字を元に戻す
            strSource = Regex.Unescape(strSource);

            // 指定した型でデシリアライズ
            Weather = JsonConvert.DeserializeObject<DataEntity.WeatherEntity>(strSource);
        }
    }
}