Connect:    



Event Calendar

Some useful links

Online Courses

Articles


A software architect, Azure expert, and former Microsoft evangelist, Mike Benkovich dedicates huge amounts of his time to helping his fellow developers and burgeoning programmers learn about new technologies and platforms. Mike’s website equips developers with tips and resources to help them get to grips with technologies including cloud, data and devices, and he produces online courses covering areas like Azure enterprise development and serverless computing. Mike is also a chronic sharer of puns, so head over to his Twitter feed if you’re after a laugh (or a groan).

BenkoBLOG by Tags


Blog Roll...
Conferences
Regional User Groups

Blog

Working with Xamarin Forms and Navigation

@MikeBenkovich 12/16/2014

I'm creating a Xamarin.Forms project, using XAML for markup that includes an authentication page when the app starts. I am using a TabbedPage (also tried CarouselPage) as the container of my main UI and plan to have several pages displayed. The first page (myDashboard) checks to see if the user has authenticated and if not I want to display a modal login page. When they return I would like to load data based on their user id.

What's happening is that the Dashboard page loads and is immediately overlaid by the myLogin page, but then all the DisplayAlerts show in succession before I do anything. When I call PopModalAsync() on the login page the OnAppearing method doesn't continue, which indicates to me that the await call had no effect in interrupting the process flow, as if it's already completed the calls after the PushModalAsync() call. (I plan to remove the DisplayAlert calls when it's working as expected.)

My code looks like this...in the App class:


    var mainPage = new TabbedPage() { Children = { new myDashboard() } };
    return mainPage;
    

 

In the myDashboard() class:

    protected async override void OnAppearing()
   {
       base.OnAppearing();
       try
       {

           await DisplayAlert("Alert", "OnAppearing Start", "ok", null);

           if (App.context.IsLoggedIn == false)
           {
               await Navigation.PushModalAsync(new myLogin());

               if (App.context.IsLoggedIn == true)
               {
                   // await LoadData();
                   PageLabel.Text = "Hello " + App.context.UserInfo;
               }
           }

           await DisplayAlert("Alert", "OnAppearing LoggedIn", "ok", null);

           await LoadData();
           await DisplayAlert("Alert", "OnAppearing Complete", "ok", null);
       }
       catch (Exception ex)
       {
           var err = ex.Message;
       }
   }
   

What am I missing?

It appears that because this code is in the OnAppearing() event which is called during a Pop or a Push that the behavior isn’t what is expected. I found an approach in the Xamarin Forums which wires up an event to the login page to send an event and then subscribe to it from the caller (see how-to-navigate-between-contentpages). I removed the code in the OnAppearing event, reserving it for handling core initialization and if the user is logged in I’ll load the data. To implement this approach subscribe to the event in the constructor of your main page…

 

    public myDashboard()
    {
        InitializeComponent();
        MessagingCenter.Subscribe<myLogin>(this, "LoginComplete",(sender) => LoadData());
    }
    

Then in the login page add code to send the message right after calling PopModalAsync() to close the window.

 

    
    public async void OnButtonClicked(object sender, EventArgs e)
    {
        var rc = await DisplayAlert("Alert!", "Logged in as " + myPhone.Text, "Ok", "Cancel");
        if (rc == true)
        {
            App.context.IsLoggedIn = true;
            await Navigation.PopModalAsync();
            MessagingCenter.Send<myLogin>(this, "LoginComplete");
        }
    }
    

It works, but is there a better way?


How to detect an iOS device when working with Xamarin and Visual Studio

@MikeBenkovich 12/02/2014

Originally posted on: http://geekswithblogs.net/benko/archive/2014/12/03/how-to-detect-an-ios-device-when-working-with-xamarin.aspx

Xamarin + WAMS = Happiness (well, most of the time)

imageFirst some background…I spent the last couple months trying to figure out the best approach for cross-platform development stuff. After some research and working thru some POC’s with Apache Cordova, Native and Xamarin we decided to go down the path of Xamarin as the tool of choice. We did this for a few reasons, including that we can use C# for the code, that with Xamarin Forms it supports XAML as our markup which has a native backend for handling responsive design, and because we would like to have one set of code running across the different device platforms, and we can go deep on a platform to light up features as needed. For learning it there’s a nice set of xamples you can start from in GitHub that show working demo apps.

Secondly we’re using Azure Mobile Services (WAMS) with the .NET implementation so we can customize the authentication process to suit our needs (more on that in another post). The Node.js implementation is fast, but it has its limitations when we have multiple environments, need to work with specific 3rd party libraries, and we wanted to be able to debug completely offline. The new generation of WAMS with .NET does this by providing a WebAPI style implementation that lets me run the service locally and have complete control. All is good.

To build for iOS the configuration requires not just Xamarin but also a mac build machine. I went to Best Buy and found a reasonably inexpensive mini device, and with some cable magic I can connect it to a spare monitor and set it up. It takes a bit of configuration and creation of accounts with Apple to get it working as a dev machine, including registering with the developer program and getting a certificate to build with. The documentation on Xamarin’s site is pretty good on this.

All is good, and I’m able to build out the examples and deploy to my Windows Phone and Android devices, but when I try to detect an iPad (attached to my mac-mini build machine) it says no devices are attached.  When I click the drop down list of debug devices it shows the iOS simulator options. I don’t see the iOS device I have attached to my build machine! What to do?

image

Searching the issue finds some ideas, but after an hour or so of restarting Visual Studio, the mac, and reconnecting the build host and then restarting Visual Studio I find that sometimes it sees my device but then quickly switches to the simulator as the only options to test on. I prefer to run on real devices (a result of attempting to use the Android simulators and waiting in vain for them to start), and also I don’t have the monitor hooked up to the mac except when I turn it on to log in. I found this Stack Overflow post which further down had a nugget of info that solved my problem.

In a multi-project solution in Visual Studio the place to look is the configuration manager. Right click on the solution and open it up. Change the iOS project from iPhoneSimulator to iPhone and Bang! your issue is solved.

image 

Now when I look at my targets for the iOS project it shows my device.

image

All is good. Happy Coding!


Cloud Tip #9-Add Microsoft.IdentityModel to the GAC with a Startup Task

@MikeBenkovich 04/07/2012

Access Control Services is one of the many services that are part of the Windows Azure Platform which handles an authentication conversation for you, allowing you an easy way to integrate cloud identity from providers like Yahoo, Google, Facebook and Live ID with your application. You need an active Azure Subscription (click here to try the 90 day Free Trial), add an ACS service namespace, then add a Secure Token Service (STS) reference to your  application (you’ll need the Windows Identity SDK and tools for Visual Studio to add the Federation Utility that does that last part – download here).

imageIf you’ve seen an error that says ‘Unable to find assembly Microsoft.IdentityModel’ and wondered what’s the deal? In the documentation for working with a Secure Token Service (STS) you might have seen that this assembly is not part of the default deployment of your Windows Azure package, and that you’ll need to add the reference to your project and set the deployment behavior to deploy a local copy with the application…all good, right?

So you follow the instructions and still get the error. One reason for this is that you might be seeing an error caused by calling methods from the serviceRuntime which changes the appdomain of your webrole. In that case you should consider adding a Startup Task to load the WIF assembly in the Global Assembly Cache.

The basic logic is that in the startup of the web role you’ll need to inject a startup task to run the gacutil executable to do the installation. I created a startup folder in my web project to contain the scripts and files necessary, including a copy of gacutil.exe, a configuration file for it, and a batch file “IdentityGac.cmd” to contain the script commands needed.

I copied the gactuil.exe and config files from my C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\x64 directory, and put them in the Startup folder. Next I created a cmd file (in notepad) with the commands to install the assembly into the GAC. I found a post that discusses how to create a script to do the installation on http://blogs.infosupport.com/adding-assemblies-to-the-gac-in-windows-azure/ where it installs the Windows Identity files and then sets the windows update service to on demand, installs the SDK, then runs gacutil.

    @echo off
    sc config wuauserv start= demand
    wusa.exe "%~dp0Windows6.1-KB974405-x64.msu" /quiet /norestart
    sc config wuauserv start= disabled
    e:\approot\bin\startup\gacutil /if e:\Approot\bin\Microsoft.IdentityModel.dll

I add these files to the Startup folder, and then open the properties for the 3 files and set the build action to none and “Copy to Output Directory” to Copy Always. This ensures that these files will be present in the deployed instance for my startup task. Next we edit the startup tasks in the Service Definition file, adding a section for <Startup>, and a <Task… to run our script file.

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="MplsKickSite.Azure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="MplsKickSite" vmsize="ExtraSmall">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
    </Endpoints>
    <Startup>
      <Task commandLine="Startup\IdentityGac.cmd" executionContext="elevated" taskType="simple">
      </Task>
    </Startup>
    <Imports>
      <Import moduleName="Diagnostics" />
      <Import moduleName="RemoteAccess" />
      <Import moduleName="RemoteForwarder" />
    </Imports>
  </WebRole>
</ServiceDefinition>

In Steve Marx’s post on Startup Task Tips & Tricks he suggests that when debugging a new startup task to set the taskType to background instead of simple so that it won’t prevent Remote Desktop from getting configured. If you’re interested to download the Startup folder I used I’ve uploaded a zip archive file with the files here.

Happy Coding!

Digg This

Cloud Tip #8-Using ACS without SSL

@MikeBenkovich 04/06/2012

Today I showed a work around for when you are showing ACS on a site that is running without setting up the SSL piece.


<
system.web>
  <!--Hack to get past request token on non-SSL site—>
  <httpRuntime requestValidationMode="2.0" />
  <pages validateRequest="false" controlRenderingCompatibilityVersion="4.0" 
        
clientIDMode="AutoID"></pages>

          ...

imageNote that shutting off validation of requests is not recommended, as it opens exploits against your site. For a better way of approaching this, Sandrino Di Mattia does a great job of explaining the right way of how to deploy and use the access control service in an Azure deployed solution.

http://fabriccontroller.net/blog/a-few-tips-to-get-up-and-running-with-theazure-appfabric-access-control-service

Make sure you add a reference to Microsoft.IdentityModel v3.5.0.0 and then set the properties of the assembly to copy local with the deploy.

On another track we looked at how to explore the claims that are included as part of the returned identity. In the Azure event I also showed a page that shows the contents of the user identity and display information about the claims contained in the token returned from ACS. I created a page in a secure location, then added a simple data grid to the page (called GridView1 and then in the page load I pull the identity information from the authenticated user data. The code for the PageLoad is below:

  

        protected void Page_Load(object sender, EventArgs e)
        {

           
try
            {
               
// Cast the Thread.CurrentPrincipal
                IClaimsPrincipal icp = Thread.CurrentPrincipal as IClaimsPrincipal
;

               
// Access IClaimsIdentity which contains claims
                IClaimsIdentity claimsIdentity = (IClaimsIdentity
)icp.Identity;

               
// icp.Identity.Name;
                // txtAuthName.Text = claimsIdentity.Name;
                
                txtAuthType.Text = claimsIdentity.AuthenticationType;
                txtIsAuthenticated.Text = claimsIdentity.IsAuthenticated.ToString();


               
var myClaims = from c in
claimsIdentity.Claims
                              
select new
{ c.ClaimType, c.Value };


                GridView1.DataSource = myClaims;
                GridView1.DataBind();


               
// Enable secret content for administrators
                if (Thread.CurrentPrincipal.IsInRole("Administrator"
))
                {
                   
this.secretContent.Visible = true
;
                }
            }
           
catch (Exception ex)
            {
                txtAuthType.Text = ex.Message;
            }
        }

Enjoy!

Digg This

Cloud Tip #3–Find good examples

@MikeBenkovich 03/31/2012

imageYesterday in Minneapolis we delivered the first Windows Azure Kick Start event of the series we’re running this spring to help developers learn and understand how to use the new tools and techniques for building cloud based applications. As part of that event we wrote a lot of code as a demonstration of how this stuff comes together and I’ve uploaded it to www.benkotips.com in case you’re interested in the download. The solution includes several projects including:

  • MplsKickSite - An existing ASP.NET web site that we migrated to Windows Azure, implementing the RoleEntryPoint interface and adding references to the Microsoft.WindowsAzure.StorageClient for working with storage, and Microsoft.WindowsAzure.ServiceRuntime to give us instance information. We also added cloud identity to the site using Access Control Services to secure a data entry page with data hosted in a SQL Azure database
  • WPFUpload which is a Windows application which includes logic to support drag and drop to upload files into Windows Azure Blob Storage, and if they are images to add work to a queue to create thumbnail images
  • UploadDataLib which is a class library that implements Windows Azure Table Storage logic for working with the images uploaded by WPFUpload and the ThumbMaker worker role projects.
  • ThumbMaker which is a worker role class that demonstrated working with Tables and Queues and the System.Drawing library to create thumbnail images and brand them with a custom logo message
  • PhoneApp1 which demonstrates how to use a Windows Phone Silverlight user control to handle the login conversation with ACS
  • NugetPhone which is a second example of ACS in use with devices, except that instead of spending 10 minutes to write the code like we did with PhoneApp1 we use the Nuget package manager to include a package (Install-Package Phone.Identity.AccessControl.BasePage) to perform the authentication for us and make the 4 code changes to implement the logic…2 minutes to demo

The decks and recordings of similar sessions are available on the Soup to Nuts Cloud Computing page of my site (http://bit.ly/s2nCloud). You can download the solution and project files and run every thing with the Compute and Storage Emulator, but you’ll need an active subscription to deploy to the cloud. If you don’t have Azure benefits you can activate from an MSDN Subscription you can always give the 90 day Free Trial a try.

Enjoy!

Digg This