DNS Client for Windows and Windows Phone

DNS Client for Windows and Windows Phone

Don’t ask why, but I needed to be able to do a dns record lookup for a srv record from a Windows Phone application. I went looking for a library that could do this and came up with Phone Net Tools (http://phonenettools.codeplex.com/) – this seems a great library but fairly rudimentary support for DNS queries. I also came across a great post by Rob Philpott on CodeProject (http://www.codeproject.com/Articles/12072/C-NET-DNS-query-component) – it’s a bit dated and for legacy technologies (I needed to upgrade everything to even run it!). Whilst this option seemed to be more painful to update the architecture seemed to lead itself to being extended to support srv records. The net effect is there is yet another library on codeplex, this one dedicated to doing DNS lookups from a Windows 8 or Windows Phone application.

At the moment I’ve only got the Windows Phone version uploaded to the Windows and Windows Phone DNS Library. It’s relatively simple to use:

// create a DNS request
var request = new Request();

var domain = "builttoroam.com";
var type = DnsType.MX;
var dnsServer = IPAddress.Parse("203.0.178.191");

// create a question for this domain and DNS CLASS
request.AddQuestion(new Question(domain, type, DnsClass.IN));

// send it to the DNS server and get the response
//Response response =

var resp = await Resolver.Lookup(request, dnsServer);
foreach (var answer in resp.Answers)
{
    Debug.WriteLine("{0}", answer.Record);   
}

Develop for Windows Phone and Windows using Portable Class Library

Develop for Windows Phone and Windows using Portable Class Library

In the past I wasn’t a big fan of the Portable Class Library as I felt it imposed more restrictions than necessary and would constrain/frustrate developers more than it would actually solve a problem. However, in recent times a couple of things have happened that have made this whole experience a lot better.

Firstly, we no longer need to drag out VS2010 to do Windows Phone 7 development. The new Windows Phone 8 SDK plugs into VS2012 and allows for both WP7 and WP8 app development. This means that if you’re going to be targeting multiple versions of WP you can do so in the same solution.

Next, the release of Microsoft.Bcl.Async on nuget – ok, you’re probably thinking what’s that? Well a while ago Microsoft published the Async programming CTP. Whilst it had a go-live license and could be used in your Windows Phone 7 project it was a hassle to install in VS2010 (due to a weird set of dependencies which were broken with subsequent updates to VS) and didn’t support VS2012 at all. The Microsoft.Bcl.Async package is the replacement for the Async CTP, allowing you to do asynchronous programming in WP7 apps. Of course, both Win8 and WP8 support async programming out of the box.

Ok, on to using a Portable Class Library. The concept here is that you want to build a single, managed, library that can be referenced by applications targeting different platforms. Let’s walk through a simple example.

We’re going to start by creating three different applications within the sample solution: SimplePCLTestApp.WP7, SimplePCLTestApp.WP8 and SimplePCLTestApp.Win8. As the project names suggest the projects should be targetting WP7, WP8 and Win8 respectively. We’re then going to also create a Portable Class Library called SimplePCL. Note, when you go to create the PCL you’ll see a prompt similar to the following image. This allows you to specify which frameworks your going to be targeting. In this case we’ll take the default options as we’re not going to be building for XBox.

image

The next thing to do is to add the Microsoft.Bcl.Async nuget package into the WP7 and PCL projects. The following image illustrates the package that you’re after.

image

Unfortunately at the moment when you attempt to add this package it won’t give you the option to add it to the PCL. It appears there is some incompatibilities with the current version of the nuget package for Microsoft.Bcl.Async and the PCL. Luckily it’s relatively easy to fix manually:

> Unload the PCL project
> Right-click on the PCL project and select Edit SimplePCL.csproj
> Now, replace the following element

<ItemGroup>
  <!– A reference to the entire .NET Framework is automatically included –>
</ItemGroup>

With

<ItemGroup>
<Reference Include="Microsoft.Threading.Tasks">
    <HintPath>..packagesMicrosoft.Bcl.Async.1.0.12-betalibsl4-windowsphone71Microsoft.Threading.Tasks.dll</HintPath>
  </Reference>
  <Reference Include="Microsoft.Threading.Tasks.Extensions">
    <HintPath>..packagesMicrosoft.Bcl.Async.1.0.12-betalibsl4-windowsphone71Microsoft.Threading.Tasks.Extensions.dll</HintPath>
  </Reference>
  <Reference Include="Microsoft.Threading.Tasks.Extensions.Phone">
    <HintPath>..packagesMicrosoft.Bcl.Async.1.0.12-betalibsl4-windowsphone71Microsoft.Threading.Tasks.Extensions.Phone.dll</HintPath>
  </Reference>
  <Reference Include="System.Runtime">
    <HintPath>..packagesMicrosoft.Bcl.1.0.11-betalibsl4-windowsphone71System.Runtime.dll</HintPath>
  </Reference>
  <Reference Include="System.Threading.Tasks">
    <HintPath>..packagesMicrosoft.Bcl.1.0.11-betalibsl4-windowsphone71System.Threading.Tasks.dll</HintPath>
  </Reference>
</ItemGroup>

> Save, and reload the PCL project

The last preparatory step is to add a reference to the PCL project to each of our applications. This is done as per normal by right-clicking the project, selecting Add Reference, and then selecting the PCL project from the solution node.

We’re now ready to start writing some code. We’ll rename Class1 to ExampleClass and add the following code:

public class ExampleClass:INotifyPropertyChanged {
    private string name;
    public string Name {
        get { return name; }
        set {
            if (Name == value) return;
            name = value;
            OnPropertyChanged();
        }
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
   [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    private readonly ManualResetEvent sleepEvent = new ManualResetEvent(false);
    public async Task UpdateName(string newName)  {
        await Task.Factory.StartNew(() =>
                                        {
                                            // This will sleep waiting for a signal that will never happen!
                                            sleepEvent.WaitOne(1000);

                                       });
    Name = newName;
   }
}

This simple class illustrates a couple of different things:

– The use of INotifyPropertyChanged – almost essential for view models, which you will probably want to share across projects if you’re using MVVM. Note the OnPropertyChanged method uses the CallerMemberName attribute, rather than the property name having to be specified when the method is called.

– The UpdateName method is an asynchronous method which launches a background task using Task.StartNew. This is to simulate some long running task (eg service call, or disk I/O). There is no support for Thread.Sleep in the PCL so we’ve used a workaround which involves waiting for a reset event that will never happen.

– The Name property is updated after the background task has completed. If this method was invoked on the UI thread then it’s safe to update the Name property, since the PropertyChanged event also needs to be invoked on the UI thread to prevent a cross threading violation.

We can then add the following code to the main page of each of our applications:

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    var example = new ExampleClass();
    example.PropertyChanged+=ExamplePropertyChanged;
    example.Name = "Initial Name";
    Debug.WriteLine("————————-");
    await example.UpdateName("Updated Name");
    Debug.WriteLine("————————-");
}

private void ExamplePropertyChanged(object sender, PropertyChangedEventArgs e)
{
    var ex = sender as ExampleClass;
    Debug.WriteLine(ex.Name);
}

Running this, in all cases, should yield the following Debug output (you may see some additional assembly/type loading information as well):

Initial Name
————————-
Updated Name
————————-

And there you have it. An example of how you can use a Portable Class Library to abstract our your platform independent code.

Windows Phone 8 SDK: Accessing Content from an SD Card

Windows Phone 8 SDK: Accessing Content from an SD Card

Before you get all excited and worked up about the fact that you can use an SD card with the new Windows Phone SDK there are a couple of limitations that you need to be aware of. Keep in mind that one of the primary scenarios that was being solved was the distribution of apps (errr, did I mention apps…. this is limited to Enterprise apps) and content, rather than being an extension to the device storage.

– You can only access file types that you’ve registered for (this excludes the standard file format – which is a bit nasty if you want your app to say process images or documents supplied on an SD card).

– You can only read from SD card.

Ok, with these limitations in mind, let’s take a shot at reading from an SD card.

First up, we need to get an SD card (oh and a real Windows Phone 8 device to work with) and put some content on it. In this scenario we’re going to use a sqlite database called mydata.sqlite. I simply inserted the Micro SD card, using an SD card adapter, into my laptop and copied across the existing sqlite file. I then inserted the card into my Windows Phone 8 device.

Next, I opened my Windows Phone 8 project and added a couple of nuget packages. These are only required if you’re using sqlite, if you’re using some other file type, you don’t need to worry about these packages.

wp7sqlite – This is a managed implementation of sqlite
sqlite-net – This is a super-easy wrapper that you can use in order to access the content.

image

Unfortunately, whilst these two packages were designed to work together, for some reason the versions that are in nuget are incompatible, requiring some minor modifications to get them to work. Luckily this is mostly a matter of replacing “out” with “ref” in a couple of methods.

The next thing to do is to declare our intent to a) read from the SD card and b) what file types we want to be able to access. Double-click the WMAppManifest.xml to open the designer, switch to the Capabilities tab and check the ID_CAP_REMOVABLE_STORAGE capability.

image

Close the manifest designer, right-click on the WMAppManifest.xml file and select Open With. Select XML (Text) Editor and hit Ok. You need to add a FileTypeAssociation element into the Extensions element. If Extensions doesn’t exist, you may need to create that too – it needs to sit after the Tokens element but before the ScreenResolutions element.

</Tokens>
   <Extensions>
     <FileTypeAssociation Name="sqlite" TaskID="_default" NavUriFragment="fileToken=%s">
       <SupportedFileTypes>
         <FileType ContentType="application/sqlite">.sqlite</FileType>
       </SupportedFileTypes>
     </FileTypeAssociation>
   </Extensions>
   <ScreenResolutions>

Now all that’s left is to write some code in order to access the content from the sd card. If you’re simply going to read from the files you can do so in situ. However, in this case we’re eventually going to want to write to the file, so we’re going to copy it to Isolated Storage first.

// Connect to the current SD card.
var sdCard = (await ExternalStorage.GetExternalStorageDevicesAsync()).FirstOrDefault();

var routeFiles = await sdCard.GetFileAsync("mydata.sqlite");
using (var source = await routeFiles.OpenForReadAsync())
using (
    var target = IsolatedStorageFile.GetUserStoreForApplication()
                                    .OpenFile("writeablecopy.sqlite", FileMode.Create, FileAccess.Write))
{
    await source.CopyToAsync(target);
}

var db = new SQLiteAsyncConnection("writeablecopy.sqlite");
var existing = await db.QueryAsync<MyDataObject>("select * from data");
var data = existing.ToArray();

Don’t forget you’ll want to add appropriate error detection and check that an SD card even exists before you attempt to read from it. For those following the sqlite portion, the MyDataObject class is a relatively simply class, the sqlite-net wrapper handles the conversion between the sqlite data and the .net types:

public class MyDataObject
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string Name { get; set; }
}