简体   繁体   中英

Extracting data out of nested Json in c#

I want to develop a weather application for windows phone.I have created a simple UI for testing purpose.Containing a one grid with textbox and button to enter city name.Second grid have different labels to show weather data after button is tapped.

I am using api from openweathermap.org .I have made classes out of Json data:

{"coord":{"lon":-120.5,"lat":47.5},"sys":{"message":0.195,"country":"US","sunrise":1384787560,"sunset":1384820527},"weather":[{"id":800,"main":"Clear","description":"sky is clear","icon":"01d"}],"base":"gdps stations","main":{"temp":277.15,"pressure":1010,"humidity":86,"temp_min":277.15,"temp_max":277.15},"wind":{"speed":0.31,"deg":230.5},"rain":{"3h":1},"clouds":{"all":1},"dt":1384797300,"id":5815135,"name":"Washington","cod":200}

And The classes are:

    public class Coord
{
    public double lon { get; set; }
    public double lat { get; set; }
}

public class Sys
{
    public double message { get; set; }
    public string country { get; set; }
    public int sunrise { get; set; }
    public int sunset { get; set; }
}

public class Weather
{
    public int id { get; set; }
    public string main { get; set; }
    public string description { get; set; }
    public string icon { get; set; }
}

public class Main
{
    public double temp { get; set; }
    public double temp_min { get; set; }
    public double temp_max { get; set; }
    public double pressure { get; set; }
    public double sea_level { get; set; }
    public double grnd_level { get; set; }
    public int humidity { get; set; }
}

public class Wind
{
    public double speed { get; set; }
    public double deg { get; set; }
}

public class Clouds
{
    public int all { get; set; }
}

public class RootObject
{
    public Coord coord { get; set; }
    public Sys sys { get; set; }
    public List<Weather> weather { get; set; }
    public string  { get; set; }
    public Main main { get; set; }
    public Wind wind { get; set; }
    public Clouds clouds { get; set; }
    public int dt { get; set; }
    public int id { get; set; }
    public string name { get; set; }
    public int cod { get; set; }
}

I am using Json.net to extract data out of obtained json.My Json data do not have a list but a single object.I have seen examples how a list can be bound to ListItem in xaml.But I do not know how to do that on single object. XAML:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid x:Name="boxOfSearch" Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="8*"/>
                <ColumnDefinition Width="2*" />
            </Grid.ColumnDefinitions>
            <TextBox x:Name="getEnteredString" Margin="2,1"/>
            <Button Grid.Column="1" x:Name="btnGet" Tap="btnGet_Tap">Go</Button>
            <!--<Button x:Name="goButton" Content="Go" Grid.Column="1" Margin="2,1"                         Click="goButton_Click"/>-->
        </Grid>

        <Grid Grid.Row="1" x:Name="extractedData" Height="532">
    <Grid.RowDefinitions>
                <RowDefinition Height="3*"/>
                <RowDefinition Height="1*"/>
    <RowDefinition Height="1*"/>
                </Grid.RowDefinitions>
                        <TextBlock x:Name="getName" Text="{Binding name}"  Margin="2,2,2,5" Foreground="#FF176EB5" FontSize="48" TextAlignment="Center" />

What I want to have as output are:Name of city,high and low temperature.Name and Temperature are from different classes.If I can get these values separately it can be a great starting point for me.

    private void btnGet_Tap(object sender, GestureEventArgs e)
    {
        WebClient wc = new WebClient();
        wc.DownloadStringAsync(new Uri(""));
        wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
    }

    void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {

        MessageBox.Show(e.Result);                        

        var rootObj=JsonConvert.DeserializeObject<RootObject>(e.Result);  //Getting DeserializedObject in a variable
        getJsonStrTxtBox.Text = rootObj.name;       // var.name  where name (Name of the City) is a string in RootObject class
    }                                                //like var.name add var.main.temp_max

Now I am able to get any data from nested json. Json.net and @evanmcdonnal thank you very much.

城市名称加温度

I'm slightly confused by your question but it sounds like you're really just looking for something like this;

    RootObject response = JsonConvert.DeserializeObject<RootObject>(responseBody);

    string message = String.Format("City: {0} - high: {1}, low: {2}", response.name, response.main.temp_max, response.main.temp_mix);

     MessageBox.Show(message);

NOTE: I would recommend some checks for nullity which I have not included in the above example (is response null? Ok, is response.main null?). When you use json.NET's DeserializeObject method on a complex object the deserialization is "cascading" (for lack of better term) meaning all of the objects which the class you're deserializing is composed of will also be deserialized appropriately. From there you would access them like with any other object, there is just another layer of indirection.

Use http://james.newtonking.com/json

 class Program
    {
        static void Main(string[] args)
        {
            var json =
                "{\"coord\":{\"lon\":-120.5,\"lat\":47.5},\"sys\":{\"message\":0.195,\"country\":\"US\",\"sunrise\":1384787560,\"sunset\":1384820527},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"sky is clear\",\"icon\":\"01d\"}],\"base\":\"gdps stations\",\"main\":{\"temp\":277.15,\"pressure\":1010,\"humidity\":86,\"temp_min\":277.15,\"temp_max\":277.15},\"wind\":{\"speed\":0.31,\"deg\":230.5},\"rain\":{\"3h\":1},\"clouds\":{\"all\":1},\"dt\":1384797300,\"id\":5815135,\"name\":\"Washington\",\"cod\":200}";

            dynamic obj = JsonConvert.DeserializeObject(json);

            Console.WriteLine(obj.coord.lon + "  " + obj.coord.lat);

            Console.ReadLine(); 
        }
    }

Extract the data first and map it to the classes. And then handle the UI events.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM