Reading a text file (or JSON file) from a Windows 8 Runtime application

I just had need of reading a small JSON file into a Windows 8 application using the Windows Runtime.

Uri uri = new Uri("ms-appx:///assets/data.json");

var storageFile = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);

using (var storageStream = await storageFile.OpenReadAsync())
{
using (Stream stream = storageStream.AsStreamForRead())
{
using (StreamReader reader = new StreamReader(stream))
{
var jsonText = reader.ReadToEnd();
var results = JsonConvert.DeserializeObject<DemoData>(jsonText);
this.DataContext = results;
}
}
}

What seemed like it should have been a common example on MSDN was not …, and after a bit of searching and reading, I believe the above code represents at least a common and safe way of loading data.

I’ve got a file called data.json stored in an Assets folder:

image

And the file’s Build Action is set to Content:

image

Change the value passed to the Uri constructor and … the file will be loaded successfully. Once loaded, I used the strongly typed generic DeserializeObject method to convert the Json data to a class called DemoData.

Windows 8 IIS Express with Windows Authentication Prompts for Credentials

If you’re seeing a credentials prompt every time you launch a local IIS or IIS Express web application that requires Windows Authentication, you’ll likely grow as tired of typing in your password as I was. To add to the annoyance, the Remember my credentials checkbox doesn’t work (nothing is saved).

image

The setup:

  • Windows 8
  • Visual Studio 2012, .NET 4.5,
  • ASP.NET MVC web application
  • Non domain-joined computer (it’s on my home network)
  • Using a Microsoft account (FKA Live ID) as the local account
  • Using IIS Express/IIS
  • Windows Authentication Enabled
  • Anonymous Logon Disabled
<system.webServer>
    <security>
        <authentication>
            <windowsAuthentication enabled="true" />
            <anonymousAuthentication enabled="false" />
        </authentication>
    </security>
</system.webServer>

While there are a few proposed solutions, this is the only one that worked for me so far.

  1. Start Internet Explorer
  2. Click the settings Menu
  3. Select Internet options
  4. Click the Security tab
  5. Select Local intranet
  6. Click Sites
  7. Click Advanced
  8. Add http://localhost to the Local intranet zone
  9. Close.
  10. Verify it’s now working.

image

image

image

image

image

Done.

Alternatives welcomed. :)

How to find an element in a DataTemplate in WinRT/XAML.

Here’s one way to find a named element in a DataTemplate in XAML in Windows 8 XAML.

You might try FindName to discover it doesn’t work. That’s because it’s not recursive.

So, I created a simple extension method to do the same thing:

public static class FrameworkElementExtensions
{
    public static FrameworkElement FindDescendantByName(this FrameworkElement element, string name)
    {
        if (element == null || string.IsNullOrWhiteSpace(name)) { return null; }

        if (name.Equals(element.Name, StringComparison.OrdinalIgnoreCase))
        {
            return element;
        }
        var childCount = VisualTreeHelper.GetChildrenCount(element);
        for (int i = 0; i < childCount; i++)
        {
            var result = (VisualTreeHelper.GetChild(element, i) as FrameworkElement).FindDescendantByName(name);
            if (result != null) { return result; }
        }
        return null;
    }
}

The code above loops through the children and attempts to match by name.

A simple usage (admittedly, this is stupid and clunky as lists are often virtualized, but …)

private void Page_Loaded_1(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
    for (int i = 0; i < myPeeps.Items.Count; i++)
    {
        var element = myPeeps.ItemContainerGenerator.ContainerFromIndex(i) as FrameworkElement;
        if (element != null)
        {
            var tb = element.FindDescendantByName("tbValue") as TextBlock;
            if (tb != null)
            {
                tb.Text = i.ToString();
            }
        }
    }
}

Given this DataTemplate and Page:

<Page.Resources>
    <local:SampleDataSource x:Key="sampleData" />
    <DataTemplate x:Key="SampleDataTemplate">
        <Grid >
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <TextBlock HorizontalAlignment="Left" Text="{Binding Name}" />
            <TextBlock Grid.Row="1" Name="tbValue" />
        </Grid>
    </DataTemplate>
</Page.Resources>

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" 
      DataContext="{StaticResource sampleData}">
    <ItemsControl x:Name="myPeeps"
        ItemsSource = "{Binding Persons}"
        ItemTemplate="{StaticResource SampleDataTemplate}" FontSize="22"/>
</Grid>

And this sample data:

public class Person {
    public string Name { get; set; }        
}    

public class SampleDataSource {
    public IEnumerable<Person> Persons { get; private set; }
    
    
    public SampleDataSource () {
        var list = new List<Person>();
        
        list.Add(new Person { Name = "Alex" });
        list.Add(new Person { Name = "Betsy" });
        list.Add(new Person { Name = "Carla" });
        list.Add(new Person { Name = "Donald" });
        list.Add(new Person { Name = "Erica" });
        list.Add(new Person { Name = "Francis" });            
        
        this.Persons = list;
    }            
}

You’ll get results like this:

image