0

New to coding and new to JSON, I have this JSON string: https://feeds.citibikenyc.com/stations/stations.json

Now i'm able to get the timestamp out, but not the data like stationnames.

here is my Proxy

public class BPNewYorkCityProxy
{
    public async static Task<RootObject> GetNewYorkCity()
    {
        var http = new HttpClient();
        var response = await http.GetAsync("https://feeds.citibikenyc.com/stations/stations.json");
        var result = await response.Content.ReadAsStringAsync();
        var serializer = new DataContractJsonSerializer(typeof(RootObject));

        var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
        var data = (RootObject)serializer.ReadObject(ms);

        return data;

    }
}

[DataContract]
public class StationBeanList
{
    [DataMember]
    public int id { get; set; }
    [DataMember]
    public string stationName { get; set; }
    [DataMember]
    public int availableDocks { get; set; }
    [DataMember]
    public int totalDocks { get; set; }
    [DataMember]
    public double latitude { get; set; }
    [DataMember]
    public double longitude { get; set; }
    [DataMember]
    public string statusValue { get; set; }
    [DataMember]
    public int statusKey { get; set; }
    [DataMember]
    public int availableBikes { get; set; }
    [DataMember]
    public string stAddress1 { get; set; }
    [DataMember]
    public string stAddress2 { get; set; }
    [DataMember]
    public string city { get; set; }
    [DataMember]
    public string postalCode { get; set; }
    [DataMember]
    public string location { get; set; }
    [DataMember]
    public string altitude { get; set; }
    [DataMember]
    public bool testStation { get; set; }
    [DataMember]
    public string lastCommunicationTime { get; set; }
    [DataMember]
    public string landMark { get; set; }
}

[DataContract]
public class RootObject
{
    [DataMember]
    public string executionTime { get; set; }
    [DataMember]
    public List<StationBeanList> stationBeanList { get; set; }
}

And here is my code on my XAML, as said the timestamp get's but now i want more, like station name's and available spots.

private async void GetData_Click(object sender, RoutedEventArgs e)
    {
        RootObject nycParking = await BPNewYorkCityProxy.GetNewYorkCity();

        // how to get a stationname .. my proxy creates a list, does it?... 
        //myStationName.Text = 

        // Well this works
        myTimeStamp.Text = nycParking.executionTime.ToString();

    }

How to do this? thanks in advance

1
  • 2
    You really should consider using a different serializer. Newtonsoft Json.Net has better performance and features than DataContractJsonSerializer and doesn't require attributing every single class and property. Not to mention it has a far more intuitive API. Commented Aug 25, 2016 at 15:12

2 Answers 2

1

The RootObject wraps the list stationBeanList and I presume that's what you want.

private async void GetData_Click(object sender, RoutedEventArgs e)
{
    RootObject nycParking = await BPNewYorkCityProxy.GetNewYorkCity();

    foreach (var station in nycParking.stationBeanList)
    {
        // Access all of them here may be?
        Console.WriteLine(station.stationName);
    } 

    // Well this works
    myTimeStamp.Text = nycParking.executionTime.ToString();

}

But if you want a simpler workflow, I'd like to suggest using Json.net if it's not a problem for you

public class BPNewYorkCityProxy
{
    public static async Task<RootObject> GetNewYorkCity()
    {
        var http = new HttpClient();
        var response = await http.GetAsync("https://feeds.citibikenyc.com/stations/stations.json");
        var result = await response.Content.ReadAsStringAsync();
        var data = JsonConvert.DeserializeObject<RootObject>(result);
        return data;
    }
}  
public class StationBeanList
{
    public int id { get; set; }
    public string stationName { get; set; }
    public int totalDocks { get; set; }
    public double latitude { get; set; }
    public double longitude { get; set; }
    public string statusValue { get; set; }
    public int statusKey { get; set; }
    public int availableBikes { get; set; }
    public string stAddress1 { get; set; }
    public string stAddress2 { get; set; }
    public string city { get; set; }
    public string postalCode { get; set; }
    public string location { get; set; }
    public string altitude { get; set; }
    public bool testStation { get; set; }
    public string lastCommunicationTime { get; set; }
    public string landMark { get; set; }
}

public class RootObject
{
    public string executionTime { get; set; }
    public List<StationBeanList> stationBeanList { get; set; }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Looks clean, Thnx, i will consider using JSON.NET, will try later on today.
used JSON.net, much easier, used the binding from the other answer
Cool, lemme know how you like it.
0

You are correct that the proxy returns a list

public List<StationBeanList> stationBeanList { get; set; }

Since you have more than one list, you cannot show that in a single Text field. So you need a list

<ListBox x:Name="stations"/>

Next, you need to configure what each element in the list will look like. In XAML that is called a DataTemplate. So let's configure one for our list:

<ListBox x:Name="stations">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding stationName}" Margin="5"/>
                <TextBlock Text="{Binding availableDocks}" Margin="5"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Finally, to populate the list with the results, in your code-behind file you need to assign the ItemsSource property of the list to the data you get from the server:

private async void GetData_Click(object sender, RoutedEventArgs e)
{
    RootObject nycParking = await BPNewYorkCityProxy.GetNewYorkCity();

    // how to get a stationname .. my proxy creates a list, does it?... 
    stations.ItemsSource = nycParking.stationBeanList;
    // Well this works
    myTimeStamp.Text = nycParking.executionTime.ToString();
}

This is all, and it should work for your simple example. However, you'll probably have to work on the XAML template and make it look nicer. There are a lot of concepts that you need to work on and improve the code with:

  • Creating a view model out of your Data model
  • Use Data Binding to link the ListBox itemssource to the result set (MVVVM)
  • Use {x:Bind} instead of the old {Binding} - optional, for performance

3 Comments

Q: do i also need to create a viewmodel? with purpose of re use? Data binding i have that under my belt, and yeah the styling needs work :) , I'll try this one later on.
Q: about the x:Bind then i need to set the datatemplet to the itemsource. can I use the stationBeanList there?
can i ask another one?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.