Following on from my previous post (Consuming POX in Silverlight), here’s a simple example of consuming a Json data service.
Data file (exposed via Http Handler on Web Server)
[
{
name:'Shredded Wheat',
price:4.95,
description:'Two per serving with skimmed milk',
calories:650
},
{
name:'Fresh Fruit Salad',
price:5.95,
description:'Strawberries, bananas, apples and pears',
calories:400
},
{
name:'Scrambled Eggs on Toast',
price:3.95,
description:'Two eggs on two slices of wholewheat toast',
calories:300
},
{
name:'Bacon Roll',
price:2.5,
description:'Three slices of lean bacon in a granary roll',
calories:600
},
{
name:'Homestyle Breakfast',
price:12.95,
description:'Two eggs, bacon, sausage, toast and orange juice',
calories:950
}
]
Http Handler (on Web Server)
using System.IO;
using System.Web;
namespace AgileREST.Web
{
public class FoodService : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
var dataPath = HttpContext.Current.Server.MapPath("Food.json");
using (var reader = new StreamReader(dataPath))
{
var result = reader.ReadToEnd();
context.Response.ContentType = "text/json";
context.Response.Write(result);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
Mapping (on the client)
namespace AgileREST
{
public class Food
{
public string Name { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
public int Calories { get; set; }
}
}
Service Call (on the client)
using System;
using System.Collections.Generic;
using System.Json;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
namespace AgileREST
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
void webClientForJson_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error != null) return;
// first option
JsonArray foods = (JsonArray)JsonArray.Load(e.Result);
var query = from food in foods
select new Food()
{
Name = (string)food["name"],
Price = (decimal)food["price"],
Description = (string)food["description"],
Calories = (int)food["calories"]
};
listboxFoodJson.ItemsSource = query.ToList();
// second option
// for implicit serialisation requires identical case sensitive name across Json and C# food objects)
//DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(List<Food>));
//List<Food> foods = (List<Food>) jsonSerializer.ReadObject(e.Result);
//listboxFoodJson.ItemsSource = foods;
}
private void btnGetFoodJson_Click(object sender, RoutedEventArgs e)
{
WebClient webClientForXml = new WebClient();
webClientForXml.OpenReadCompleted += webClientForJson_OpenReadCompleted;
webClientForXml.OpenReadAsync(new Uri(HtmlPage.Document.DocumentUri, "FoodService.ashx"));
}
}
}
Data binding (on the client)
<UserControl x:Class="AgileREST.MainPage"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="700">
<UserControl.Resources>
<DataTemplate x:Key="itemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="tbName"
Width="170"
Text="{Binding Path=Name}" />
<TextBlock x:Name="tbPrice"
Width="50"
Text="{Binding Path=Price}" />
<TextBlock x:Name="tbDescription"
Width="300"
Text="{Binding Path=Description}" />
<TextBlock x:Name="tbCalories"
Width="50"
Text="{Binding Path=Calories}" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Width="600" Margin="10">
<TextBlock Text="Json Example" Margin="5" />
<StackPanel x:Name="ColumnDescriptions" Orientation="Horizontal" Margin="5" >
<TextBlock Text="Name" Width="170" />
<TextBlock Text="Price" Width="50" />
<TextBlock Text="Description" Width="300" />
<TextBlock Text="Calories" Width="50" />
</StackPanel>
<ListBox x:Name="listboxFoodJson"
Height="150"
Margin="5"
ItemTemplate="{StaticResource itemTemplate}" />
<Button x:Name="btnGetFoodJson"
Height="50"
Margin="5"
Click="btnGetFoodJson_Click"
Content="Get Food From Json Service" />
</StackPanel>
</Grid>
</UserControl>
You can download the source code from the following link:
No comments:
Post a Comment