Skip to content

Instantly share code, notes, and snippets.

@amitapl
Created August 27, 2012 01:02
Show Gist options
  • Save amitapl/3484790 to your computer and use it in GitHub Desktop.
Save amitapl/3484790 to your computer and use it in GitHub Desktop.
using Microsoft.WindowsAzure.MobileServices;
using System;
using Windows.Foundation;
namespace MobileServices
{
public class AdminServiceFilter : IServiceFilter
{
private bool disableScripts;
private string masterKey;
public AdminServiceFilter(bool disableScripts, string masterKey)
{
this.disableScripts = disableScripts;
this.masterKey = masterKey;
}
public IAsyncOperation<IServiceFilterResponse> Handle(IServiceFilterRequest request, IServiceFilterContinuation continuation)
{
// Add master key to the request's header to have admin level control
request.Headers["X-ZUMO-MASTER"] = this.masterKey;
if (this.disableScripts)
{
// Get the request's query and append noScript=true as the first query parameter
var uriBuilder = new UriBuilder(request.Uri);
var oldQuery = (uriBuilder.Query ?? string.Empty).Trim('?');
uriBuilder.Query = ("noScript=true&" + oldQuery).Trim('&');
request.Uri = uriBuilder.Uri;
}
return continuation.Handle(request);
}
}
}
public async Task<IJsonValue> GetTableItems(string tableName, string masterKey, bool disableServerSideScripts)
{
// Get mobile service client with the admin filter.
MobileServiceClient adminMobileService = App.MobileService.WithFilter(new AdminServiceFilter(disableServerSideScripts, masterKey));
// Get the selected mobile service table.
IMobileServiceTable mobileServiceTable = this.adminMobileService.GetTable(tableName);
// Read the first 10 items in this table,
// With disableServerSideScripts=true it's the actual first 10 rows otherwise it depends on the server side script.
return await mobileServiceTable.ReadAsync("$top=10");
}
<Page
x:Class="MobileServices.MainPage"
IsTabStop="false"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MobileServices"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="White">
<Grid Margin="50,50,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.ColumnSpan="2" Margin="0,0,0,20">
<StackPanel>
<ProgressBar Name="BusyProgressBar" Visibility="Collapsed" IsIndeterminate="True" />
<TextBlock Foreground="#0094ff" FontFamily="Segoe UI Light" Margin="0,0,0,6">WINDOWS AZURE MOBILE SERVICES</TextBlock>
<TextBlock Foreground="Gray" FontFamily="Segoe UI Light" FontSize="45" >Tables Viewer</TextBlock>
<ComboBox Name="TableSelector" ItemsSource="{Binding Newa}" SelectionChanged="TableSelector_SelectionChanged"/>
</StackPanel>
</Grid>
<ScrollViewer Grid.Row="1">
<Grid>
<GridView Name="ListItems" Margin="62,10,0,0" Grid.Row="1" ItemsSource="{Binding}" SelectionMode="Single">
<GridView.Header>
<GridView Name="ItemsHeader">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" FontWeight="Bold"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</GridView.Header>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<GridView Name="InnerGridView" ItemsSource="{Binding Values}" SelectionMode="None">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Value, Mode=TwoWay}" Background="{Binding ValidationError}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" IsReadOnly="False"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
</ScrollViewer>
</Grid>
</Grid>
<Page.BottomAppBar>
<AppBar x:Name="BottomAppBar" Padding="10,0,10,0">
<StackPanel Orientation="Horizontal">
<Button x:Name="BottomAppBarDelete" Tag="Delete" Style="{StaticResource DeleteAppBarButtonStyle}" HorizontalAlignment="Left" Click="DeleteClick" />
<Button x:Name="BottomAppBarUpdate" Tag="Update" Style="{StaticResource SaveAppBarButtonStyle}" HorizontalAlignment="Left" Click="UpdateClick" />
<Button x:Name="BottomAppBarRefresh" Tag="Refresh" Style="{StaticResource RefreshAppBarButtonStyle}" HorizontalAlignment="Left" Click="RefreshClick" />
</StackPanel>
</AppBar>
</Page.BottomAppBar>
</Page>
using Microsoft.WindowsAzure.MobileServices;
using System.Linq;
using System.Threading.Tasks;
using Windows.Data.Json;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace MobileServices
{
public sealed partial class MainPage : Page
{
private MobileServiceClient adminMobileService;
public MainPage()
{
this.InitializeComponent();
this.TableSelector.ItemsSource = Constants.TableNames;
}
private async Task RefreshTableView()
{
var mobileServiceTable = GetSelectedTable();
if (mobileServiceTable != null)
{
BusyProgressBar.Visibility = Windows.UI.Xaml.Visibility.Visible;
// Get all items as json array
var tableItems = await mobileServiceTable.ReadAsync("$top=10");
var gridViewItems = tableItems.GetArray().Select(jsonValue => new MobileServiceTableItem(jsonValue.GetObject()));
var gridViewItemsHeaders = tableItems.GetArray().First().GetObject().Select(o => o.Key);
ListItems.ItemsSource = gridViewItems;
ItemsHeader.ItemsSource = gridViewItemsHeaders;
BusyProgressBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
}
private IMobileServiceTable GetSelectedTable()
{
var selectedTableName = TableSelector.SelectedValue as string;
if (selectedTableName != null)
{
return this.adminMobileService.GetTable(selectedTableName);
}
else
{
return null;
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string masterKey = e.Parameter as string;
adminMobileService = App.MobileService.WithFilter(new AdminServiceFilter(true, masterKey));
this.TableSelector.SelectedIndex = 0;
}
private async Task ButtonRefresh_Click(object sender, RoutedEventArgs e)
{
await this.RefreshTableView();
}
private async void TableSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
await this.RefreshTableView();
}
private async void RefreshClick(object sender, RoutedEventArgs e)
{
await this.RefreshTableView();
}
private async void DeleteClick(object sender, RoutedEventArgs e)
{
var selectedTable = GetSelectedTable();
if (selectedTable != null)
{
var selectedTableItem = ListItems.SelectedItem as MobileServiceTableItem;
if (selectedTableItem != null)
{
BusyProgressBar.Visibility = Windows.UI.Xaml.Visibility.Visible;
await selectedTable.DeleteAsync(selectedTableItem.JsonObject);
await this.RefreshTableView();
BusyProgressBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
}
}
private async void UpdateClick(object sender, RoutedEventArgs e)
{
var selectedTable = GetSelectedTable();
if (selectedTable != null)
{
var selectedTableItem = ListItems.SelectedItem as MobileServiceTableItem;
if (selectedTableItem != null)
{
BusyProgressBar.Visibility = Windows.UI.Xaml.Visibility.Visible;
await selectedTable.UpdateAsync(selectedTableItem.JsonObject);
await this.RefreshTableView();
BusyProgressBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
}
}
}
}
<Page
x:Class="MobileServices.MasterKeyInputPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MobileServices"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="White">
<Grid Margin="50,50,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.ColumnSpan="2" Margin="0,0,0,20">
<StackPanel>
<ProgressBar Name="BusyProgressBar" Visibility="Collapsed" IsIndeterminate="True" />
<TextBlock Foreground="#0094ff" FontFamily="Segoe UI Light" Margin="0,0,0,6">WINDOWS AZURE MOBILE SERVICES</TextBlock>
<TextBlock Foreground="Gray" FontFamily="Segoe UI Light" FontSize="45" >Tables Viewer</TextBlock>
</StackPanel>
</Grid>
<StackPanel Grid.Row="1" Background="{StaticResource ApplicationPageBackgroundThemeBrush}" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="Enter your master key" FontSize="28" HorizontalAlignment="Center" />
<TextBox Name="MasterKeyTextBox" FontSize="24" Margin="0,30,0,30" Width="500" HorizontalAlignment="Center" />
<Button Click="ButtonClick" HorizontalAlignment="Center" FontSize="28">Start</Button>
</StackPanel>
</Grid>
</Grid>
</Page>
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace MobileServices
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MasterKeyInputPage : Page
{
public MasterKeyInputPage()
{
this.InitializeComponent();
}
private void ButtonClick(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(MainPage), MasterKeyTextBox.Text);
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Windows.Data.Json;
using Windows.UI;
using Windows.UI.Xaml.Media;
namespace MobileServices
{
public class MobileServiceTableItem
{
public MobileServiceTableItem(JsonObject jsonObject)
{
this.JsonObject = jsonObject;
}
public JsonObject JsonObject { get; private set; }
public IEnumerable<Item> Values
{
get
{
if (this.JsonObject != null)
{
return this.JsonObject.Select(kv => new Item(kv.Key, JsonObject));
}
return null;
}
}
}
public class Item : INotifyPropertyChanged
{
public Item(string key, JsonObject jsonObject)
{
Key = key;
JsonObject = jsonObject;
ValidationError = new SolidColorBrush();
}
public event PropertyChangedEventHandler PropertyChanged;
public JsonObject JsonObject { get; private set; }
public string Key { get; private set; }
private Brush validationError;
public Brush ValidationError
{
get
{
return validationError;
}
set
{
validationError = value;
OnPropertyChanged("ValidationError");
}
}
public string Value
{
get
{
if (JsonObject[Key].ValueType == JsonValueType.String)
{
return JsonObject[Key].GetString();
}
return JsonObject[Key].Stringify();
}
set
{
try
{
switch (JsonObject[Key].ValueType)
{
case JsonValueType.Boolean:
JsonObject[Key] = JsonValue.CreateBooleanValue(bool.Parse(value));
break;
case JsonValueType.Number:
JsonObject[Key] = JsonValue.CreateNumberValue(double.Parse(value));
break;
case JsonValueType.String:
JsonObject[Key] = JsonValue.CreateStringValue(value);
break;
case JsonValueType.Null:
case JsonValueType.Object:
case JsonValueType.Array:
default:
throw new NotSupportedException("The value type is not supported: " + JsonObject[Key].ValueType);
}
ValidationError = new SolidColorBrush();
}
catch (FormatException)
{
ValidationError = new SolidColorBrush(Colors.Red);
}
OnPropertyChanged("Value");
}
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment