Monthly Archives: August 2013

Portable Azure Mobile Services DTOs when using Xamarin and C#

As part of an upcoming talk I am giving I am spending a lot of time working on a demo that shows how to do push notifications cross-device. One concept that is really drummed in when working in this space is that building reusable C# is key to leveraging the savings from building Windows Phone, iOS, Android apps this way.

A C# Azure Mobile Services client library exists for each of the platforms and it’s really easy to use your standard C# classes as Data Transfer Objects (DTOs) for storage in Azure as a result. One item that tripped me up on Android and iOS was that I found I could write data to the cloud easily and while I could get a set of resulting objects back their properties were either null or in their default state. Not useful!

This is how my class looked – I had arrived at this after using DataMember and JsonProperty objects and finding, at first appearances, that I didn’t need either for the code to actually work. I was wrong :).

public class Task : IBusinessEntity
{
     public Task () {}

     public int ID { get; set; }
     public string Name { get; set; }
     public string Notes { get; set; }
     public bool Done { get; set; }
     public string Assignee { get; set; }
}

The challenge in decorating the above class with DataMember is that this class isn’t actually natively supported on Windows Phone – you will get a NotSupportedException the first time your application attempts to run any code that uses this class. The suggested fix in the Exception is to utilise the JsonProperty attribute instead which doesn’t actually work on Android or iOS deployment. So… this is the fix I came up with – it’s not pretty but it is leveraging one way to build portable C# code (note there is no default symbol defined for iOS builds which doesn’t help!) Behold…

public class Task : IBusinessEntity
{
    public Task () {}

    public int ID { get; set; }

#if !WINDOWS_PHONE
    [DataMember(Name = "name")]
#endif
    public string Name { get; set; }

#if !WINDOWS_PHONE
    [DataMember(Name = "notes")]
#endif
    public string Notes { get; set; }

#if !WINDOWS_PHONE
    [DataMember(Name = "done")]
#endif
    public bool Done { get; set; }

#if !WINDOWS_PHONE
    [DataMember(Name = "assignee")]
#endif
    public string Assignee { get; set; }
}

I think you’ll find that compiler pre-processor directives like this will quickly become your friend when writing C# to target multiple platforms.

Tagged , , , , , ,

Debug iOS App from Visual Studio with Xamarin extension using the iPhone Simulator.

This is a really quick and easy tip for those starting out doing iOS development with Xamarin (and specifically with the Visual Studio extensions). If you don’t have access to an iOS device and want to debug on the Simulator that ships with Xcode make sure you do the following:

Set the “Platform” to “iPhoneSimulator” for the project.

1. Select the Solutions Configuration menu (allows you typically to choose Debug or Release) and is next to the “Start” debug button.
2. In the Configuration Manager for your iOS App select “Platform” and change to “iPhoneSimulator” (highlighted below).
3. Save the changes and you should now be able to debug.

Selecting iPhoneSimulator

I scratched my head on this for a while ;).

BTW, did I say how cool it is that you can develop Android and iOS apps from right inside Visual Studio? You still need a Mac and Xcode for iOS but Android is there for the taking (you can even edit the axml layout files directly inside Visual Studio!)

Tagged , , , ,

How to add a Site-to-Site VPN to an Azure Virtual Network after setup.

I have recently been working on a couple of engagements that involve utilising the site-to-site connectivity features of Windows Azure Virtual Networks. On one engagement we went through the setup of the Virtual Network early on before the customer’s network team had gotten involved and we just skipped the setup of the site-to-site connection at network creation time because we could come back and define it later.

What we found, however, was once the Virtual Network was setup and populated with DNS servers and Virtual Machines we were unable to change the site-to-site settings using the Azure Management Portal – they were greyed out. We defined the Local Network within the Management Portal but were unable to associate it with the Virtual Network.

A key thing to note before you read on – if you haven’t defined any subnets on your Virtual Network and your address space is in use already you can stop reading now. You will not be able to add a VPN connection to your environment. This is because the Azure Gateway solution requires its own subnet (it’s essentially a set of specially configured Windows VMs) and if you don’t have a subnet with no addresses in use then you will need to start over.

If the above paragraph doesn’t apply to you – read on.

  1. Setup your Local Network (on-prem / DC) via the Azure Management Portal by clicking on +NEW in the bottom left of screen and selecting Network Services > Virtual Network > Add Local Network. Fill in all the necessary details.
  2. Open up PowerShell and make sure you have initialised your environment so it will work with your Azure Subcription.
  3. Retrieve the Virtual Network Configuration for the network you wish to add the gateway to.
    Get-AzureVNetConfig -ExportToFile "c:\temp\MyAzNets.netcfg"
    
  4. This produces an XML file you can edit. ¬†You should see something similar to the below (we had already provisioned a “vpnsubnet” that was reserved for future VPN use).
    <?xml version="1.0" encoding="utf-8"?>
    <NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration">
      <VirtualNetworkConfiguration>
        <Dns>
          <DnsServers>
            <DnsServer name="POCDNS01" IPAddress="10.16.210.132" />
            <DnsServer name="POCDNS02" IPAddress="10.16.210.133" />
          </DnsServers>
        </Dns>
        <LocalNetworkSites>
          <LocalNetworkSite name="OnPremiseNetwork">
            <AddressSpace>
              <AddressPrefix>10.150.0.0/14</AddressPrefix>
              <AddressPrefix>10.154.0.0/15</AddressPrefix>
            </AddressSpace>
            <VPNGatewayAddress>95.11.12.124</VPNGatewayAddress>
          </LocalNetworkSite>
        </LocalNetworkSites>
        <VirtualNetworkSites>
          <VirtualNetworkSite name="pocvnet" AffinityGroup="pocvnet-ag">
            <AddressSpace>
              <AddressPrefix>10.16.210.0/23</AddressPrefix>
            </AddressSpace>
            <Subnets>
              <Subnet name="appsubnet">
                <AddressPrefix>10.16.210.0/25</AddressPrefix>
              </Subnet>
              <Subnet name="dcsubnet">
                <AddressPrefix>10.16.210.128/25</AddressPrefix>
              </Subnet>
              <Subnet name="ressubnet">
                <AddressPrefix>10.16.211.0/25</AddressPrefix>
              </Subnet>
              <Subnet name="vpnsubnet">
                <AddressPrefix>10.16.211.128/25</AddressPrefix>
              </Subnet>
            </Subnets>
            <DnsServersRef>
              <DnsServerRef name="POCDNS01" />
              <DnsServerRef name="POCDNS02" />
            </DnsServersRef>
          </VirtualNetworkSite>
        </VirtualNetworkSites>
      </VirtualNetworkConfiguration>
    </NetworkConfiguration>
    
  5. Firstly I thought I could just add in my Gateway details to VirtualNetworkSite and re-submit but when I submitted the file back to Azure I receieved this response:

    Set-AzureVNetConfig : “An exception occurred when calling the ServiceManagement API. HTTP Status Code: 400. Service Management Error Code: BadRequest. Message: Missing subnet referenced ‘GatewaySubnet’ in virtual network ‘pocvnet’.. Operation Tracking ID:”

    Oooooohhh, I see, the Gateway’s expecting a reserved subnet with name “GatewaySubnet” to exist. Let’s modify the file and change the details on line 39 (rename the subnet). My VPN setup is shown on lines 21 – 25.

    <?xml version="1.0" encoding="utf-8"?>
    <NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration">
      <VirtualNetworkConfiguration>
        <Dns>
          <DnsServers>
            <DnsServer name="POCDNS01" IPAddress="10.16.210.132" />
            <DnsServer name="POCDNS02" IPAddress="10.16.210.133" />
          </DnsServers>
        </Dns>
        <LocalNetworkSites>
          <LocalNetworkSite name="OnPremiseNetwork">
            <AddressSpace>
              <AddressPrefix>10.150.0.0/14</AddressPrefix>
              <AddressPrefix>10.154.0.0/15</AddressPrefix>
            </AddressSpace>
            <VPNGatewayAddress>95.11.12.124</VPNGatewayAddress>
          </LocalNetworkSite>
        </LocalNetworkSites>
        <VirtualNetworkSites>
          <VirtualNetworkSite name="pocvnet" AffinityGroup="pocvnet-ag">
              <Gateway profile="Small">
              <ConnectionsToLocalNetwork>
                <LocalNetworkSiteRef name="OnPremiseNetwork"/>
              </ConnectionsToLocalNetwork>
              </Gateway>
            <AddressSpace>
              <AddressPrefix>10.16.210.0/23</AddressPrefix>
            </AddressSpace>
            <Subnets>
              <Subnet name="appsubnet">
                <AddressPrefix>10.16.210.0/25</AddressPrefix>
              </Subnet>
              <Subnet name="dcsubnet">
                <AddressPrefix>10.16.210.128/25</AddressPrefix>
              </Subnet>
              <Subnet name="ressubnet">
                <AddressPrefix>10.16.211.0/25</AddressPrefix>
              </Subnet>
              <Subnet name="GatewaySubnet">
                <AddressPrefix>10.16.211.128/25</AddressPrefix>
              </Subnet>
            </Subnets>
            <DnsServersRef>
              <DnsServerRef name="POCDNS01" />
              <DnsServerRef name="POCDNS02" />
            </DnsServersRef>
          </VirtualNetworkSite>
        </VirtualNetworkSites>
      </VirtualNetworkConfiguration>
    </NetworkConfiguration>
    
  6. Now that the file is updated let’s resubmit it back to Azure for action:
    Set-AzureVNetConfig "c:\temp\MyAzNets.netcfg"
    

That was it! If you switch back to your Azure Portal you’ll see some changes – the “GatewaySubnet” magically transforms into simply “Gateway” in the UI and your on-premise Local Network will be associated with site-to-site connectivity. After a period you will start to see changes in your Virtual Network as Azure provisions the VPN endpoints and starts to spin up instances and connect to the on-premise gateway.

Azure PowerShell Cmdlets FTW!

Tagged , , ,