Monday, June 2, 2014

Azure Mobile Services .NET Backend Tips

,
I've been working with Azure Mobile Services since it was released and until recently only the JavaScript backend was available, built using node.js. Although it is very mature with many options, the community was pressuring for a .NET option and now it is available.

Modeled much like a standard Web API / MVC project at first glance, there may be a few things that you like to take advantage of in these types of projects that throw you for a loop when using the new .NET option. These include Dependency Injection, Entity Framework (Migrations and Relationships), and the help page.

Getting Started

You have two options for getting a project started.

1. Go to the Azure Portal and create a new Azure Mobile Service and download the project
(http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started/)


2. Start New Project from Visual Studio 2013 SP2 and choose "Web" -> "Windows Azure Mobile Service"


For this example, I went with option #1 and called it "mytodotips". Download the solution and be sure to build it to get all of the necessary nuget packages and ensure that your environment is set.

Entity Framework, Code First, Migrations, and Relationship Challenges

There are a few items here that may leave you scratching your head here, frustrating you, and depending on your temper perhaps throwing things. So, let me see if I can keep your mouse in one piece.

Migrations

Do this first! Open Package Manager Console, Tools -> NuGet Package Manager -> Package Manager Console, and type the following command

enable-migrations

the result will create a new folder in your solution called "Migrations" containing a file named "Configuration.cs", thus enabling code first migrations when your schema changes. In order to complete the change, open the WebApiConfig.cs file in the "App_Start" folder.

Comment out the Database.SetInitializer(...); line, and you may also comment out or delete the class that is called within the method.  This method drops and recreates the database each time the application is run.

Insert the following code above the SetInitializer(...); line to call the Configurator class just created by "enable-migrations" and explicitly apply the latest migration unless it has already been applied.

var migrator = new DbMigrator(new Configuration());
migrator.Update(); 

 The following namespaces will also need to be added to your imports

using System.Data.Entity.Migrations;
using mytodotipsService.Migrations;

Open Package Manager Console and run add-migration init, in doing so sets the initial migration and establishes the migration table.

Now whenever you add to your models, you can run the same Add-Migration "migration name" in the Package Manager Console and then hit F5 to update the local machine database or publish to Azure and run the service to update the Azure SQL Server database.

Relationships

Relationships are pretty easy, however there are a few maintenance items in the OnModelCreating method I have found that help me get past some errors when running "update-database" or "add-migration".

Each class in Azure Mobile Services that has a table behind inherits from EntityData which implements ITableData. When make FK relationships you may receive errors when indexes are being created/altered. I have found by setting the Id field to be the PK on the table that sometimes these can be alleviated.

modelBuilder.Properties<string>()
     .Where(p => p.Name == "Id")
     .Configure(p => p.IsKey());


Another option I also put on all new model classes is the following, this tells the database that the Id field is auto generated and is not required to be set when creating a new class.

modelBuilder.Entity<entityname>()
     .Property(m => m.Id)
     .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Now this a simply a personal preference that I'm sure many will disagree with, but I happen to like my tables to be singular.

 modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

Dependency Injection

My favorite DI engine for sometime has been AutoFac, and by accident I discovered its baked into Azure Mobile's .NET back end as well.

Now that I have the Entity Framework Code First context all set the way I like, I can now make sure I don't have to new up in every controller.

In our WebApiConfig.cs class, there is a ServiceConfig.Initialize(...) call to kick off the configuration process of the application. It accepts a ConfigBuilder class accepting options for your service, but also has an overload to accept a Func to register your own dependencies which happens to be an autofac container.

Here is how to add the database context, for example, using AutoFac.

  HttpConfiguration config = ServiceConfig.Initialize(new ConfigBuilder(options, (configuration, builder) =>
  {
        mytodotipsContext context = new mytodotipsContext();
        builder.RegisterInstance(context).As<mytodotipsContext>().SingleInstance();
  }));

And now in our ToDoItemController.cs we can add a constructor and alter the Initializer method to the following.

public class TodoItemController : TableController<TodoItem>
{
mytodotipsContext context;
public TodoItemController(mytodotipsContext myContext)
{
this.context = myContext;
}
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
  // mytodotipsContext context = new mytodotipsContext();
DomainManager = new EntityDomainManager<TodoItem>(context, Request, Services);
}

Help Page

So, you've got Entity Framework setup with relationships, Dependency Injection going with AutoFac and now you are checking out the help page and getting nothing. What happened?



There are a few issues we want to attack here.
  • Where is the data model?
  • I only want to show JSON
  • and a few more as we fix the top 2

Data Model Missing
This is a common issue with serializers when there are circular properties.  In this case there is a Profile class that has ToDo items that has a Profile property.  See the Code First Mapping here:


modelBuilder.Entity<ToDoItems>().HasRequired(t => t.Profile)
                .WithMany(p => p.ToDoItems)
                .HasForeignKey(t => t.ProfileId);

What happens here is when the JsonSerializer and XmlSerlizer  starts to walk the property tree; they get in an infinite loop and eventually exhaust the maximum errors and exit. In order to fix this, we will add the following to the WebApiConfig.cs class inside the Register method. *note only adding this for JsonFormatters, but can be handled for Xml just as well.

config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;


Now we can F5, see the help page and the object model represented in Json but the application/xml and text/xml boxes still show with the error.  As mentioned in our to do list above we only wanted to support Json. To do so, add the following to the configuration now.

// Remove default XML handlervar matches = config.Formatters .Where(f => f.SupportedMediaTypes .Where(m => m.MediaType.ToString() == "application/xml" || m.MediaType.ToString() == "text/xml") .Count() > 0) .ToList();foreach (var match in matches) config.Formatters.Remove(match);

And finally, I like to properly case Json.

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

This single line will make JavaScript devs happy. Instead of seeing the objects like this:

[
    {
        "Text": "sample string 1",
        "Complete": true,
        "Id": "sample string 3",
        "__version": "QEBA",
        "__createdAt": "2014-06-02T16:40:40.641Z",
        "__updatedAt": "2014-06-02T16:40:40.641Z",
        "__deleted": true
    },

they are cased properly like this:

[
    {
        "text": "sample string 1",
        "complete": true,
        "id": "sample string 3",
        "__version": "QEBA",
        "__createdAt": "2014-06-02T16:40:40.641Z",
        "__updatedAt": "2014-06-02T16:40:40.641Z",
        "__deleted": true
    },
There are other features such as Notification Hubs and Scheduled Jobs which are awesome additions to any application. Be sure to check these out when leveraging Azure Mobile Services, regardless of whether you are using .NET or JavaScript as your back end of choice.

Leave a comment if you have a tip or trick you like to use or pass on as well.
Read more →

Friday, April 18, 2014

ASP.NET Presentations at DEVIntersection

,
Had a great time presenting Async Application Development and the Social Authentication options available in ASP.NET this week at DevIntersection.

Building Async Applications in ASP.NET


Async has become much easier over time to code and maintain with the async/await keywords and adding the capabilities in WebForms applications can improve overall page response times if done correctly.

Here are the additional links and the slides from the session.



Bring Your Own Authentication yo MVC

As I mentioned in my session on Social loin integration, adding the capability is very easy through since the addition of OWIN/Katana middleware authentication host plumbing that is out of the box in ASP.NET.  A couple of highlights from the talk:
  • Add social logins where appropriate
    • Enterprise or internal company applications might not apply
  • Leverage test user in Facebook's Developer portal
    • Don't use your own account or your friends and family
    • Add an under 13 account in the test user if you need to support children accounts
Here are the slides and additional links.

Again thanks for coming out and hope to see you in the fall at DEVIntersection and Anglebrackets!
Read more →

Monday, March 17, 2014

DEVIntersection: 3 Days of ASP.NET, Azure, SQL & More!

,
Come out to DEVIntersection April 13-16 at the JW Marriott in Orlando to get a chance to interact with a number of community experts such as Scott Guthrie, Scott Hanselman, Douglas Crockford and many more.

I'll be giving two talks in the ASP.NET track:

AS12: Building Asynchronous ASP.NET Applications

Learn how to take advantage of the new async/await operations to keep your applications responsive and avoid the performance bottlenecks. In comparison to how async code has been written with callbacks, the new way allows for cleaner more readable debug-able code. In this presentation topics covered WebForms, MVC, EF6 some tooling.

AS11: Bring Your Own Authentication (BYOA) to MVC

Most of us are familiar with the the phrase "Bring Your Own Device", where business users have over time influenced internal IT to move to the users platform instead of vice versa.  Leveraging the social sign on credentials such as Facebook, Microsoft, Twitter etc will not only eliminate the code you need to create, re-create or manage but also ease the sign on process for your potential users. ASP.NET provides the underlying OAuth framework to easily make the connection and manage the integration, this session will walk through leveraging social sign credentials in your applications in a few simple steps. 

Also don't miss out on the co-located <anglebrackets /> at no extra cost where you'll get an opportunity to hear web experts like John Papa, Dan Wahlin, Elijah Manor Rob Eisenberg and more speak about AngularJS, Durandal and other current and emerging web tech you won't want to miss out on.

Use discount code "BOYER" for an additional $50 off registration.
Read more →

Thursday, February 20, 2014

Town Hall Style, Windows 8 Development Shoot or Aim?

,
Had the first meeting of the year last night for the Orlando Windows Phone / Windows 8 Group and instead of going down the planned presenter lead meeting format it turned more into a "Town Hall" style with some good topics I thought I'd share.

Where does everyone go to learn how to build or develop for Windows 8.1?

As anyone who can use the web, you w ill find a number of popular blogs that have articles written on how to get started using this or that, including my own, but how relevant are they considering how fast Windows 8 development is moving and changing for that matter.  One attendee mentioned the LayoutAwarePage and how it was a thing and now its "just there".  Or how there were only 3 views to deal with and now there are many.

Brian, from the Orlando .NET User Group, likes Microsoft's Virtual Academy and also stated that when looking at blogs the first piece of information is the date the article was posted to know whether or not to keep going.

Pluralsight.com is also another very well known resource for getting up to speed on almost any technology, and their catalog grows daily.

Monetization strategies for apps?

Of course, a very common topic.  How the heck do you make money on your apps?  Charge for them, ads, in app purchases, both, so on and so forth.  There has been a lot of conversation around this topic and sure enough the recent Flappy Bird app incident has everyone in a swirl to find the next big one.

Alex Perez, from Neuralnet, gave some insight into their experience on in app purchases how they attacked the issue.  Free with in app purchases was the most successful way, BUT you have to hook your users and make them want to keep coming back to the app is the key.

I don't this is a big secret, the secret is finding the hook -- right?

Should I build apps for Windows 8.1 now or wait to see what happens after BUILD 2014?

When Windows 8 hit the development community, a lot of the .NET community hit it learning the tools the new stuff throwing apps, blogging it etc. Some even went at the HTML/WinJS framework option reusing the libraries that were available building RSS readers, games, etc.

Then 8.1 hit and the game was changed. Tools got better, controls were added, more views, the OS was smaller, better, faster. Question on the floor - shoot or just aim?  

Strategies for sharing code?

I love the MVVM pattern for mobile development - Windows Phone, Windows 8.* and anything Xamarin supports.  With Portable Class Libraries and the lifted license restrictions and full support through Xamarin there is no reason not use it.  BUT, do not get caught in hours of trying to force something into the pattern simply to put it into the pattern.  Get the product out there, and rev. Refactor and release often.

Apps or Web?

It just depends right? What is the target audience, the device support, does it need connectivity, what is the skill set of the team you have and so on.  There is no right answer. The answer is -> know what questions to ask.

All great discussions, really enjoyed the format.  What are your thoughts on any or all of these issues, and have you tried this format at your local user group? Would you?
Read more →

Tuesday, January 14, 2014

Custom URIs added to I'm Here App

,
I took a few moments to add custom URI launchers for my I'm Here app on Windows Phone so it could be used in Rob Irving's Car Dash app.  It was a really quick add to the app, however the one are I found to be a pain was testing it.  I actually had to write another phone app to test it. Not that it was a chore, just didn't consider that when I started, I made an assumption I could've just typed i the URI in Internet Explorer or mocked an SMS message like you can in iOS.

If you have a Windows Phone App that offers functionality that other apps can use there is no reason not to offer custom launchers.  It takes about an hour total development time, and the benefit can more than just adding the functionality.

In my case, one I learned how to do it. Two, I get free marketing from another very successful app. Make sure you document your URI on the Nokia page here to let every other developer know for extra exposure. And finally, made a nice connection in the developer community.  Who knows, maybe the next big thing will happen when Rob and I team up...

If you want to use I'm Here in your app here is the simple launcher URI code to do so.

// launch the app
await Windows.System.Launcher.LaunchUriAsync(new Uri("imhere:"));
// launch the app and share location via SMS

await Windows.System.Launcher.LaunchUriAsync(new Uri("imhere://share/text"));
// launch the app and share location via Email

await Windows.System.Launcher.LaunchUriAsync(new Uri("imhere://share/email"));
// launch the app and share location via Social Apps

await Windows.System.Launcher.LaunchUriAsync(new Uri("imhere://share/social"));

// launch the app and share location via WhatsApp application
await Windows.System.Launcher.LaunchUriAsync(new Uri("imhere://share/whatsapp"));


Be sure to checkout my apps and the other links below to take advantage of the custom URIs in you own apps.

Rob Irving on Twitter
Nokia URI Association Schemes List
URI associations for Windows Phone - How To
Reserved file and URI associations for Windows Phone 8
Read more →

Thursday, January 2, 2014

Microsoft MVP - ASP.NET

,
This year started off with a nice surprise, an email with the subject "Congratulations 2014 Microsoft MVP!"

I am humbled and excited, as this is the first time for me, and as always to be a part of such a great community. I enjoy the time I spend at community events, speaking to other developers and hearing their challenges, ideas and what great projects they are working on.

ASP.NET is the category of my award, and although most know me for some the Windows Phone work I have done; Web API, MVC, and JavaScript/TypeScript is where I have spent a majority of my time. Mobile is as much about the back end services as it is about the front end.

2014 is going to be another great year.  I am already putting together my speaking schedule, working on new material and projects and can't wait to see the new stuff from the other new and renewed MVPs.

Thanks to all of my supporters in the community! Especially those in Florida who I get to see on a regular basis.
Read more →

Friday, November 22, 2013

Being a successful mobile developer - Windows Phone, Marketing & Xamarin

,

Why Windows Phone?

This is not a new question, but a question or topic that I get involved a lot.  Why do you have a Windows Phone? Why do you build apps for that platform? You should be learning Java and Objective C and putting your apps on iOS and Android; that's where the users are.

That is the message from the media, family, tech pundits and co-workers. And the numbers say that as well; the latest report shows that Android holds a ridiculous global market share of 80%, Apple with 12% and Windows Phone at 4% respectively.  So why should I build an app for Windows Phone first?

Its about visibility.

Visibility

Apple has more than 1 million apps on the iOS platform and Android just over 800,000. It is virtually impossible without spending an enormous amount of time, money and or energy getting an app exposure to the user base.  However, through programs like Nokia's DVLUP you can manage to get very visibility in the marketplace, increased reviews and downloads and through the combination of all of these. Revenue will begin to climb. Now, there is some learning to be done by the developer when it comes to monetizing your app; I won't go into the various strategies as there have been many workshops/articles/blogs published so definitely look into those.

Building a Brand / Marketing

Build it and they will come is not a marketing campaign strategy! I'm pretty involved in the community and talk with a lot of developers, read quite a few email and message board threads about how they have a new app for this or that...please review, download etc.  But that is the last place I see it ever mentioned.

Here are a few suggestions:

  • Build a Facebook Fan Page - it's free
  • Azure Websites - every subscriber gets 10 free site, build one for your app
  • Blog about the technology you used in your app, why you chose to do it. 
  • Contact Media outlets about your app - wpcentral.com, wmpoweruser.com
  • Use social media to your advantage - twitter, Facebook, LinkedIn, Google+, Instagram (yes) & learn what a hashtag (#) is and use those to your advantage. If you don't know ask a teenager.

Design

Now none of the above will matter if your app is a battleship grey page with black comic sans font. Spend some time on design.  Now I know, not all developers are good designers. Guess what? Not all designers are good developers.  Find a friend who knows Photoshop, team up! There is this really cool online collaboration tool - Team Foundation Service that's free for up to 5 users, collaborate on a project and make it happen.

Build with Other Platforms in Mind - Xamarin

Now that you have a great idea, either put together a great design or found a friend & have a marketing strategy.  Build your app with the correct tools and architecture so when you have Android and iOS users wanting it, you can respond in a reasonable amount of time.

Xamarin and Microsoft have teamed up to bring a closer integration in Visual Studio 2013 to allow you to create native iOS and Android applications (not HTML5 & JavaScript) using C# and Portable Class Libraries. Thus maximizing your code reuse.

Microsoft also just announce full Azure Mobile Services support for Xamarin.

I will be blogging more examples, in the meantime visit www.xamarin.com and follow @xamarinhq & @jamesmontemagno (Xamarin Developer Evangelist) on twitter.

Please feel free to contact me via twitter @spboyer concerning xamarin, portable class libraries, windows phone development, windows 8 development or anything.
Read more →

Friday, November 15, 2013

Presenting Azure Mobile Services @ DVLUP Day Tampa 11/16/2013

,
Nokia, through its DVLUP program, is putting on DVLUP day in various cities from Nov. 16 - Dec 6.  I'll be in Tampa on the 16th of November presenting Azure Mobile Services.

I'll give an overview of:

  • Getting Started
  • Push Notifications
  • Visual Studio 2013 Tools for Azure
  • General Q & A


I will also be around all day if you have any questions about Portable Class Libraries or Advanced features of Azure Mobile Services such as complex data types, authentication, etc.

Event Summary

Spend a day with two of our top Nokia Developer Ambassadors, Bill Reiss (@billreiss) and Atley Hunter (@atleyhunter). Together, Bill and Atley will guide you through the process of publishing your apps to the Windows Phone Store - either from scratch, or porting from iOS or Android.

Whether you’re a first-time developer, or a seasoned pro who wants to know more about Windows Phone, this event is for you.

If you are in the Tampa Area, there is still space so sign up! There are other dates and locations available and they can be found on the DVLUP site (http://www.dvlup.com/Events/138).

You will need to have your DVLUP account ID. If you haven’t signed up already, sign up today at  www.dvlup.com

 To win a device you need to complete one of these DVLUP challenges:

http://www.dvlup.com/Challenge/32

http://www.dvlup.com/Challenge/125

Your app must be published within 14 days of your event to win.

If you are attending, be sure to tweet and use the hashtag #DVLUPday #tampa and follow @dvlup

Read more →

Saturday, August 24, 2013

Azure Mobile Services & Portable Class Libraries - Part 2 Authentication Cont'd

,
In Part 1 I covered a simple implementation of the Authentication feature and portable class libraries from the Azure Mobile Services SDK.  However, as mentioned in the "Good & Bad So Far" section; there is not a whole lot of code reuse other than the Azure endpoint and secret key.  Let's refactor a bit by adding some interfaces, conditional compile statements and the MVVM Light Event Bus to help the same solution operate cleaner.

The "after" code for part one is available here.

Building Our Core

PortableAzure.Core is our Portable Class Library that is being shared with the Windows 8 and  Windows Phone project in the attempt to reuse as much code as possible.  However, as mentioned in Part 1 the authentication portion of the Azure Mobile Service SDK is a platform specific implementation due to the UX pieces of that component and how it is presented varies.

Platform Adapter (PlatformAdapter.cs)

In the Services folder, add a new class called PlatformAdapter.cs.  This is an abstract class that will be used as the base class for the platform specific implementation.

    public abstract class PlatformAdapter
    {
        public static PlatformAdapter Current { get; set; }
        public abstract IIdentity Identity { get; }
    }

Identity (IIdentity.cs)

Add a new Identity interface, IIdentity.cs to be used as the implementation to execute the Authenticate method as well as store the MobileServiceUser upon logging in.

    public interface IIdentity
    {
        void Authenticate();
        MobileServiceUser User { get; set; }
    }


 Messages

Add a Messages folder to the root and a class called LoginMessage.cs to newly created folder.

Using the Event Bus from MVVM Light, a LoginMessage will be sent from the platform specific MainPage.xaml then subsequently handled in the MainViewModel.  The LoginMessage is just an empty class at this point.

    namespace PortableAzure.Core.Messages {
        public class LoginMessage { } 
    }

Adding Adapters to the Platforms

On each plaftform we need to now inherit from the PlatformAdapter.cs class in the Services namespace from the Core library as well as implement the IIdentity interface thus replacing the code shown in part one with this code.

Windows Phone

Add an "Adapters" folder to the root of the project and then a Platform.cs class which inherits from PlatformAdapter.

namespace PortableAzure.Phone8.Adapters
{
    public class Platform : PlatformAdapter
    {
        public IIdentity _identity = new Identity();

        public override IIdentity Identity
        {
            get
            {
                return _identity;
            }
        }
    }
}


Next, add the Identity class which is where all of the heavy lifting is done for the login logic.

namespace PortableAzure.Phone8.Adapters
{
    public class Identity : IIdentity
    {
        public async void Authenticate()
        {
            var app = ((App)Application.Current);

            string message = string.Empty;

            while (this.User == null)
            {
                try
                {
                    User = await app.Azure.MobileService.LoginAsync(MobileServiceAuthenticationProvider.Twitter);

                    message = string.Format("You are now logged in - {0}", User.UserId);
                }

                catch (InvalidOperationException)
                {
                    message = "You must log in. Login Required";
                }
            }

            MessageBox.Show(message);
        }

        public MobileServiceUser User { get; set; }
    }
}   
   
   
   
Now that the Windows Phone implementation is complete we need to tell the Service library what is the current class is for the PlaformAdapater.  This is set in the App.xaml.cs class in the App contstructor:

public App()
{
   Azure = new AzureMobileServices();

   PortableAzure.Core.Services.PlatformAdapter.Current = new Platform();

   ...

Windows 8

To implement the PlatformAdapter class in the Windows 8 application, you could follow the same steps as documented for the Phone project, but that is duplication and not manageable over time.

So in this case we will use add the existing Identity and Platform classes then add conditional compile statements to the areas of the classes where needed to address the small differences for Windows versus Phone.

Add Existing item by holding the Alt key and dragging the file, or the whole folder from the Phone project to the Windows 8 Project.  Thanks Matt Hidinger for this little trick. You could also just go through the right click -> add existing -> add as link process but now that you know the "Hold Alt + Drag" why??

Here are the completed Platform and Identity classes.  You will need to repeat the setting of the current platform in the App.xaml.cs constructor.

Platform.cs


#if NETFX_CORE

namespace PortableAzure.Win8.Adapters

#endif



#if WINDOWS_PHONE

namespace PortableAzure.Phone8.Adapters

#endif

{
    public class Platform : PlatformAdapter
    {
        public IIdentity _identity = new Identity();

        public override IIdentity Identity
        {
            get
            {
                return _identity;
            }
        }
    }
}

Identity.cs

#if NETFX_CORE

namespace PortableAzure.Win8.Adapters

#endif


#if WINDOWS_PHONE

namespace PortableAzure.Phone8.Adapters

#endif

{
    public class Identity : IIdentity
    {
        public async void Authenticate()
        {

#if WINDOWS_PHONE

            var app = ((App)Application.Current);

#endif


#if NETFX_CORE

            var app = ((PortableAzure.Win8.App)(Windows.UI.Xaml.Application.Current));

#endif

            string message = string.Empty;

            while (this.User == null)
            {
                try
                {
                    User = await app.Azure.MobileService.LoginAsync(MobileServiceAuthenticationProvider.Twitter);

                    message = string.Format("You are now logged in - {0}", User.UserId);

                }

                catch (InvalidOperationException)
                {
                    message = "You must log in. Login Required";
                }
            }

#if WINDOWS_PHONE

            MessageBox.Show(message);

#endif

#if NETFX_CORE

            var messageDialog = new Windows.UI.Popups.MessageDialog(message);

            await messageDialog.ShowAsync();

#endif

        }

        public MobileServiceUser User { get; set; }

    }

}

Note, be sure to use the full namespace OR add more #if at the top for the imports.

Cleanup & Consolidation

Now that there is a single place where the application executes the call to Authenticate, through the magic of #if and reusing existing files, time to delete some code.  Nice right?

In Part, each of the front end projects had code in the MainPage.xaml.cs file within the "Loaded" handler to execute the Azure authentication code.  That can be replaced by using the Event Messaging Bus provided by MVVM Light and sending the LoginMessage.

Messenger.Default.Send<LoginMessage>(new LoginMessage());

In the MainViewModel, add the handler in the constructor and the Login subroutine to call the Authenticate method in the Identity interface.

 public MainViewModel()
 {
     Messenger.Default.Register<LoginMessage>(this, m => { Login(); });
  }

 public void Login()
 {
     if (PlatformAdapter.Current.Identity.User == null)
     {
         try
         {
           PlatformAdapter.Current.Identity.Authenticate();
         }
          catch (Exception ex)
         {
             Debug.WriteLine(ex.ToString());
         }
     }
 }

Now when either platform is run, the Login entry point happens in the MainViewModel upon loading of the main page.  Another option, if you wanted to eliminate the messaging, would be to add a login button and have the ICommand call the Login method thus eliminating any code behind in the MainPage.xaml but that depends on your applications needs.

Windows Phone
Windows 8 / RT



Wrapping Up Authentication

One item to mention, in this example every time the app is run on either platform the user will have to authenticate.  When the MobileServiceUser is successfully authenticated, there are two properties that you can save; MobileServiceAuthenticationToken and UserId respectively.  In a subsequent execution of the app, create a new instance of the MobileServiceUser and set the CurrentUser property of the AzureMobileService.MobileService. For Example:

var user = new MobileServiceUser(mySavedUserId);

user.MobileServiceAuthenticationToken = mySavedMobileServiceAuthenticationToken;

App.MobileService.CurrentUser = user;

Part 1 and Part 2 has shown a simple introduction of how to use portable class libraries with Azure Mobile Services and through the use of a little indirection reuse all the code possible BUT also keep the MVVM implementation and code organization as clean as possible.

Final Code for Part 2 located here

Read more →

Monday, August 5, 2013

Azure Mobile Services & Portable Class Libraries - Part 1 Authentication

,
Azure Mobile Services is undoubtedly one of the best platforms to emerge from the Azure group over the last year. If you are a mobile developer and not taking advantage of it; I encourage you to do so.  There are many video and blog posts available to get you started at http://www.windowsazure.com/en-us/develop/mobile/ .

One of the features you may not be aware of is Azure Mobile Services is a Portable Class Library (PCL) available through nuget. If you are not familiar with PCL's see my "Move Your ViewModels" series.

There is a caveat however when using Azure Mobile Services in your PCL; although all of the data calls to the services are available, using the Identity feature is not and must be implemented in a platform specific way.

The Identity feature allows your application to leverage the user's Microsoft, Google, Facebook or Twitter account to login to the application and abstract the overhead of OAuth or provider specific authentication models into a single call.

var user = MobileService.LoginAsync(MobileServiceAuthenticationProvider.Twitter);

The Challenge - Maximize Code Reuse

There is no secret that Model-View-View-Model (MVVM) is a preferred pattern for xaml developers, but it is also know that sometimes breaking patterns is needed either due to time constraints or other restrictions.

In the effort to maintain the MVVM pattern in this scenario a platform abstraction is needed to accomplish to goal of reusing as much code as possible.  Matt Hidinger did a great talk at BUILD 2013 this year on this topic, give a watch on his blog.

Scenario - Setting up your solution

I won't walk through setting up a Mobile Service on Azure, see this post for instructions, so let's assume we have a Windows Phone & Windows Store application where we'd like to share code in a Portable Class Library and allow the user to login with their Twitter account. The project solution should contain 3 projects:


  • PortableAzure.Win8 - Windows 8 Blank  Application
  • PortableAzure.Phone8 - Windows Phone 8 Application
  • PortableAzure.Core - Portable Class Library Project
    •  .NET Framework 4.0 & higher
    • Windows Phone 7.5 & higher
    • Windows Store Apps

I have added the following nuget packages to the projects

  • Microsoft.Net.Http
  • Portable.MvvmLightLibs
  • WindowsAzure.MobileServices

There is some plumbing related to the MVVM structure that is needed as well.  Get the "before" code here http://sdrv.ms/14ufYYZ , your solution explorer should look like the image here ->.


Adding Azure 


Assumption(s) - you have created a Azure Mobile Service.

First, you will want to add a new class to the Services folder in the PortableAzure.Core project and call it AzureMobileServices. I have also added an empty interface out of habit and to use for IoC (Inversion of Control).

namespace PortableAzure.Core.Services
{
    public class AzureMobileServices : IAzureMobileServices
    {
        public MobileServiceClient MobileService = new MobileServiceClient(
            "https://portableazure.azure-mobile.net/",
            "[your app key]"
        );
        public AzureMobileServices()
        {
        }
    }
    public interface IAzureMobileServices
    {
    }
}


The app key and url comes from the Azure portal when you complete the setup; you will want to choose "Connect to an Existing Project". Either Windows Phone or Windows 8 is an acceptable choice.

Next step is to setup the Twitter authentication, or other provider of your choosing.  (reference)

Now that that is complete, we'll add the necessary platform specific code to the Windows Phone & Windows 8 platforms to prompt the user to login using their Twitter account.

Windows Phone

Open the App.xaml.cs and create a new property for the AzureMobileService class from the Core project.

    public partial class App : Application
    {
        /// <summary>
        /// Provides easy access to the root frame of the Phone Application.
        /// </summary>
        /// <returns>The root frame of the Phone Application.</returns>
        public static PhoneApplicationFrame RootFrame { get; private set; } 
        public AzureMobileServices Azure { get; private set; } 
        /// <summary>
        /// Constructor for the Application object.
        /// </summary>
        public App()

Then in the App constructor create the new instance of the AzureMobileService class.

Azure = new AzureMobileServices();
 In order to prompt the user, open the MainPage.xaml.cs file and add the following code to the PhoneApplicationPage_Loaded event.

 private async void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            MobileServiceUser user = null;
            while (user == null)
            {
                string message;
                try
                {
                    user = await((App)Application.Current).Azure.MobileService.LoginAsync(MobileServiceAuthenticationProvider.Twitter);
                    message = string.Format("You are now logged in - {0}", user.UserId);
                }
                catch (InvalidOperationException)
                {
                    message = "You must log in. Login Required";
                }
                MessageBox.Show(message);
            }
        }


Windows 8

The implementation is essentially the same for Windows 8 with the exception of how to show a message box.

private async void Page_Loaded(object sender, RoutedEventArgs e)
        {
            MobileServiceUser user = null;
            while (user == null)
            {
                string message;
                try
                {
                    user = await((App)Application.Current).Azure.MobileService.LoginAsync(MobileServiceAuthenticationProvider.Twitter);
                    message = string.Format("You are now logged in - {0}", user.UserId);
                }
                catch (InvalidOperationException)
                {
                    message = "You must log in. Login Required";
                }
                var dialog = new MessageDialog(message);
                dialog.Commands.Add(new UICommand("OK"));
                await dialog.ShowAsync();

            }
        }

The Good & Bad - so far

To this point everything is working great and we have now effectively added the authentication to each platform using the Identity features in Azure Mobile Services. But other than the url and the key of the Azure Mobile Service; there isn't a lot of code reuse in this scenario.

This is a necessity when there are platform specific implementations of a feature.  In this case, the UI needs to present differently and cannot re-use the xaml or controls that are a part of the login utility for the specified provider.

The bad part of this is it breaks the MVVM pattern to a degree by putting some of the logic in the code behind.

In the next installment, I'll show how to add an abstraction layer and use the MVVM Light Event Bus to push some of this code back to our view models.

Here is the completed code for Part 1.





Read more →

Thursday, March 28, 2013

Cross Mobile Development with Icenium

,
I have recently spent some time with Telerik's new product offering for cross mobile development called Icenium and I have to say it is quite nice.  Paired with KendoUI Mobile you can't go wrong with a great set of tools for cross mobile platform development if you are an HTML + CSS + JavaScript developer.

Icenium

Icenium is a cloud based IDE, there is also a Windows WPF Click-Once app, that allows you as a developer to leverage your existing HTML, CSS and JavaScript skills to develop hybrid cross mobile platform applications.  Assistance of publishing your applications to the Google Play and Apple Store, integrated debugging and development environment, source control integration (including Git) and much more.  See http://www.icenium.com for more information.

I will mention also that the underlying bits of Icenium is PhoneGap (Apache-Cordova) which provides and API through JavaScript (cordova.js) to the device functions such as the camera other hardware capabilities.  For more information on that piece, Jim Cowart (@ifandelse) recently did a blog entry on their blog - "Demystifying Cordova and PhoneGap".

Getting Started

Head over to Icenium.com and click the "Get Started" button. Choose either the browser (cloud) based IDE or download the Windows app.


Once the application is launched select New Project -> Cross Platform Device Application (Kendo UI Mobile). Name the project "MyBloodPressure" and click Ok.

In doing so, Icenium presents the built in "Hello World" type template. Shows how geolocation, transitions, styling using Kendo UI Mobile etc.  If you run the application by either hitting F5 or clicking the "Run" icon atop the IDE you'll also see the awesome tools for viewing the various mobile devices currently supported as well.

After you spend a few minutes playing with the emulators and realizing how cool that all is, we'll rip out some stuff add some sauce to this and get cooking.

Reorganizing the Project for Organization

I'm a very big proponent of being able to look at a project and know what the heck is going without having to hunt down someone or run the code and step through it to find out how it's all composed.  

In a C#/XAML world in I use the MVVM pattern with MVVM Light for my projects. I like to see the view folder, viewmodel folder etc. when developing the app.  For doing so here I will leverage RequireJS  for structuring the organization.  

Removing unnecessary files

Delete the hello-world.js from the scripts folder as we will not be using this for the project.

Folder structure

First, lets create a few folders.  At the root of the project create an app folder that contains view, viewmodel and model.

For any scripts that are 3rd party libraries, I prefer to put those in the scripts folder and any that are related directly to the application specific functionality I organize them within the app folder appropriately.  Given that, I'll move the kendo.mobile.min.js, jquery.min.js and also add require.js to the scripts folder

Next, add a new JavaScript file to the app folder by right clicking and selecting add new file. Name is main.js; this will be the entry point to the application.

Also add a JavaScript file to the app folder named app.js, this will serve as the singelton for exposing the viewmodels and could also be referred to as the view model locator.

First item of business is to tell require.js where to find the modules we either have or will be creating in our application. Add the following to main.js to configure require.js.

require.config({
    paths: {
        jQuery: "../scripts/jquery.min",
        kendo: "../scripts/kendo.mobile.min",
        view: "../app/view",
        viewmodel: "../app/viewmodel",
        app: "../app"
    },
    shim: {
        jQuery: {
            exports: "jQuery"
        },
        kendo: {
            deps: ["jQuery"],
            exports: "kendo"
        }
    }
});

What this is doing, if you are not familiar, is telling require.js that when a module is defined like

define(['viewmodel/bp'], function(bp) { ... } );

it knows to go look for bp.js inside of the "[root]/app/viewmodel" folder and not a relative path etc.  In the shim portion of the code we are stating that kendo has a dependency on jQuery and should wait for that library to load first.  For more information on requirejs and the config method see http://requirejs.org/docs/api.html#config .

Finally in the main.js file add the following to create the app module, put it in scope and init the application.

var app;
require(["app/app"], function (application) {
    console.log('initializing');
    app = application;
    app.init();
});

Last order of business is to add the code to app.js to tell kendo to initialize the mobile application.  Here is the full app.js code for now.

define(["jQuery", "kendo"], function ($, kendo) {
    var _kendoApplication;
    return {
        init: function () {
            console.log('app init');
            _kendoApplication = new kendo.mobile.Application(document.body,
                    { transition: "slide", layout: "mobile-tabstrip" });
        }
    }
});   

The init function is called when the application first fires up setting the transitons of the app the 'slide' and telling kendo what the layout root of the app is; in this case 'mobile-tabstrip'.

Wiring Up Index.html

Now that the scripts, view, viewmodel, entry points etc. are all setup; open index.html.

In the <head> tag remove everything except the references to the .css and cordova.js files and the we need to add the script reference to main and require.js for our entry point.  After that all scripts will be loaded using AMD and require.js . 

    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="cordova.js"></script>
        <script data-main="app/main" src="scripts/require.js"></script>
        <link href="kendo/styles/kendo.mobile.all.min.css" rel="stylesheet" />
        <link href="styles/main.css" rel="stylesheet" />
    </head>

Also remove the script tag at the bottom of the file that refers to the kendo.mobile.application as we have now moved that to the app.js init function.

Finally, remove all <div> tag sections with a data-role of view other that the first one.  These will be separated into individual html files and stored in the views folder in Part 2 of the series.  The final html document should appear as:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="cordova.js"></script>
        <script data-main="app/main" src="scripts/require.js"></script>
        <link href="kendo/styles/kendo.mobile.all.min.css" rel="stylesheet" />
        <link href="styles/main.css" rel="stylesheet" />
    </head>
    <body>
        <div data-role="view" id="tabstrip-home" data-title="Hello World!">
            <h1>Welcome!</h1>
            <p>
                Icenium&trade; enables you to build cross-platform device applications regardless of your
                development platform by combining the convenience of a local development toolset with the
                power and flexibility of the cloud.
            </p>
        </div>
     
        <div data-role="layout" data-id="mobile-tabstrip">
            <header data-role="header">
                <div data-role="navbar">
                    <span data-role="view-title"></span>
                </div>
            </header>
            <div data-role="footer">
                <div data-role="tabstrip">
                    <a href="#tabstrip-home" data-icon="home">Home</a>
                    <a href="#tabstrip-uiinteraction" data-icon="share">UI Interaction</a>
                    <a href="#tabstrip-geolocation" data-icon="globe">Geolocation</a>
                </div>
            </div>
        </div>
     
    </body>
</html>

Conclusion

If you run the application you can see that the application still operates as it did in the very beginning, with the exception of the additional views not appearing, but the advantage here is that the overall structure allows for manageability moving forward as complexity is added to the project through data services and additional views. 

If there is something that you would like to see in a series or have a question please add a comment. 




Read more →

Monday, March 25, 2013

Custom Routing with IRouteConstraint for ASP.NET Web API

,
I will admit that Regex and I do not speak anymore.  In fact, even when we did it was never a really nice conversation and sometimes ended in me cursing and/or leaving the room.

If you have had this same experience when creating custom routes in ASP.NET MVC then you know what I'm talking about.

IRouteConstraint
IRouteConstraint has been around for some time in MVC, but it is also available in Web API too because of course it is based on the same stack for routing.

Undoubtedly, the most difficult part of routes is debugging or getting the Regex right. I recently re-lived this experience when having to create a custom API route for a project something along the lines of

/api/{controller}/{model}/{road}/{id}

where {model} must exist in a list of valid string values and {road} is a pattern of XX9999 and then obviously the {id} must be an integer for the specific record in the list.

So, initially you start putting the Regex together for the id, "^\d+$", and then the road might be something like   "^[a-zA-Z]{2}\d{4}$".  But how should I handle the in list for the {model} param?

Sure we could put together the Regex for that, but debugging all of this is a pain even in the short term.  Also if the constraint itself is something of an edge case where the value must be a filename that exists, or a guid in memory etc; IRouteConstraint is the answer.

IRouteConstraint requires you to implement one method, Match, which returns a boolean. In the method below we are looking for one of the values being passed in the values[] parameter to a list used in the constructor.


    public class FromValuesListConstraint : IRouteConstraint
    {
        public FromValuesListConstraint(params string[] values)
        {
            this._values = values;
        }
        private readonly string[] _values;
        public bool Match(HttpContextBase httpContext,
            Route route,
            string parameterName,
            RouteValueDictionary values,
            RouteDirection routeDirection)
        {
            // Get the value called "parameterName" from the
            // RouteValueDictionary called "value"
            string value = values[parameterName].ToString();
             // Return true is the list of allowed values contains
            // this value.
            return _values.Contains(value, StringComparer.CurrentCultureIgnoreCase);
        }
    }


In order to use this from the WebApiConfig.cs class, create your route like the following.


config.Routes.MapHttpRoute(
               name: "CustomRouteNoDayOrAction",
               routeTemplate: "api/{controller}/{model}/{road}/{id}",
               defaults: null,
               constraints: new
               {
                   model = new FromValuesListConstraint("ford", "chevy", "dodge", "toyota"),
                   road = @"^[a-zA-Z]{2}\d{4}$",
                   id = @"^\d+$"
               }
);

When you run and test your routes, you can now put a break point on the FromValuesListConstraint Match method and debug the routing.




Read more →

Wednesday, February 6, 2013

South Florida Code Camp

,
I will be giving two talks this Saturday at South Florida Code Camp, being held at Nova University in Ft. Lauderdale, Fl.  For directions and more information visithttp://www.fladotnet.com/codecamp/. Schedule for other sessions here.

My Sessions


Read more →

Friday, February 1, 2013

Develop Windows 8 & Windows Phone Apps and Win Cash!

,
From February 1 through June 2013, publish a new Windows 8 or Windows Phone app and enter my sweepstakes page to win up to $1000 in cash prizes.  WHAT?!?!  

Pretty cool right.  Get extra $$ for what you are already doing.  Publish you app in the store the go to http://spboyer.me/appsforcash and submit your app.

3 Winners each month!
$1000
$500
$250

Follow me on twitter @spboyer and let me know when you submit it and I'll personally look at the app and give it a review and let all my friends to give it a look as well for extra exposure.

See official rules here



BONUS POINTS AND AWARDS

FREE NOKIA PHONE

If this is your FIRST Windows Phone App you may qualify for a Free Nokia Lumia Phone.


TELERIK WINDOWS 8 Controls

I will pick 1 Winner each month from the Windows 8 Submissions to receive a free licensed copy of Telerik's Windows 8 Controls

Read more →

Tuesday, January 29, 2013

Nothing great was ever achieved without enthusiasm...

,
Over the past month I have had the opportunity to give some thought to what I wanted to accomplish this year in my life, career, and health. And during those times of thought I have often gone back to a speech I listened or re-listened to by the late Jimmy Valvano.

Jimmy V was a great college basketball coach and was unfortunately diagnosed and later passed away from bone cancer. But shortly before his death he gave a riveting speech at the 1993 ESPN ESPY Awards. There are some great things he said, but one statement lost in many outtakes that stuck with me was

"Nothing great was ever achieved without enthusiasm" ...Ralph Waldo Emerson

I think about that statement and how it relates to life, but also how I approach code, software development and teaching. Enthusiasm is the name of the game.  I'm passionate in how I present it, teach it, talk about it and code it. 

The question I have always wondered is how can the few of us who think this way make that feeling contagious? Spread that disease?

I know how I feel after taking a good 5 mile run or so and beating a goal or my last time thinking, "hell yes!" and that's the same feeling I get when a project is complete or I inspire a developer to do something different or try a new path and then later they tell me "thanks, just what I needed".

Recently, after a .NET User Group meeting I sat and had a beer with a few friends from the group and we had this very discussion and the conversation was really good.  I heard stuff like...

"It's not their project...."

"...making the other guy money, why be passionate"

"...some companies are better at making their devs feel ownership..."

What are your thoughts?  What can make you more enthusiastic or pump up that 9-5'er you know at your office?

Start the conversation....
Read more →

Monday, January 28, 2013

Portable MVVM Light - Move Your View Models : Part 2

,
In the first part I covered how to get the initial project setup and share the ViewModels and ViewModelLocator between a Windows Phone 8 project and a Windows Store Application.  In this post, I'll add a DataService and a Model class that will be used to get the most recent posts from the Windows Phone Blog and display the results.

Adding DataService and Async to Portable Class Library

The purpose of the DataService in the context of this project is to retrieve the RSS feed from the Windows Phone Blog (http://blogs.windows.com/windows_phone/b/wpdev/rss.aspx) using the async methods available in the 4.5 Framework, return a collection of our Headline class object for the UI to handle and display.

Headline Class Model

The Headline class is the object that will be loaded and a collection of these will be built and returned from the data service method.  Create a new folder in the Mvvm.PCL project called "Model" and add a new file called Headline.cs.


    public class Headline
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public string Url { get; set; }
        public DateTime Published { get; set; }
    }


IDataService

In good practice, create an interface for the DataService class.  This would allow for taking advantage of dependency injection if you chose to do so. Add a new interface file to the model folder called IDataService.cs.  Here is the interface:


namespace Mvvm.PCL.Model
{
public interface IDataService
{
void GetHeadlines(Action<List<Headline>, Exception> callback);
}
}

The interface defines a single method that accepts a delegate with a collections or List<T> of Headline and an Exception parameter.

DataService

Next, in the same folder, add the DataService.cs file and implement the interface.

    public class DataService : IDataService
    {
        public void GetHeadlines(Action<List<Headline>, Exception> callback)
        {
            throw new NotImplementedException();
        }
    }


HttpWebRequest

Most simple requests for data are done with the WebClient class, however this class is not available in Portable Class libraries and is really only an abstraction of what must be used and that is the HttpWebRequest.

Add a new method to the class called MakeAsyncRequest accepting a url (string) as a parameter and set the method to return a Task<string>. Within the method I'll use the Task.Factory.FromAsync method to call the url asynchronously returning the Task<WebRequest> then use a continuation to read the WebResponse.


        private static Task<string> MakeAsyncRequest(string url)
        {
            HttpWebRequest request = WebRequest.CreateHttp(url);
            request.Method = "GET";

            Task<WebResponse> task = Task.Factory.FromAsync(
                request.BeginGetResponse,
                (asyncResult) => request.EndGetResponse(asyncResult),
                (object)null);

            return task.ContinueWith(t => ReadStreamFromResponse(t.Result));
        }

        private static string ReadStreamFromResponse(WebResponse response)
        {
            using (Stream responseStream = response.GetResponseStream())
            using (StreamReader sr = new StreamReader(responseStream))
            {
                string strContent = sr.ReadToEnd();
                return strContent;
            }
        }

The GetHeadlines method can now be completed. First add the static url.

 private readonly string uri = "http://blogs.windows.com/windows_phone/b/wpdev/rss.aspx";


Then declare a variable to hold the results of the MakeAsyncRequest method and set the call with the await keyword so the UI thread is not blocked.

var t = await MakeAsyncRequest(uri);

You will also have to mark the method as async or the compiler will give you an error telling you to do so.


public async void GetHeadlines(Action<List<Headline>, Exception> callback)
{
...
}

The results returned are a string type and there are a couple of options to get it into a nice format to work with.  Your first option might be to use the Silverlight SyndicationFeed class which is in the System.ServiceModel.Syndication namespace. However, it is not inherently available in the portable classes and you'll need to go searching for it on your dev machine. Hint (C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.ServiceModel.Syndication.dll).

I'm choosing to use LINQ and doing Linq to XML here to get what I need out of the results string and inflate my classes and return it.

Here is the completed method.


        public async void GetHeadlines(Action<List<Headline>, Exception> callback)
        {
            // locally scoped exception var
            Exception err = null;
            List<Headline> results = null;
            try
            {
                var t = await MakeAsyncRequest(uri);
                StringReader stringReader = new StringReader(t);
                using (var xmlReader = System.Xml.XmlReader.Create(stringReader))
                {
                    var doc = System.Xml.Linq.XDocument.Load(xmlReader);
                    results = (from e in doc.Element("rss").Element("channel").Elements("item")
                               select
                                   new Headline()
                                   {
                                       Title = e.Element("title").Value,
                                       Description = e.Element("description").Value,
                                       Published = Convert.ToDateTime(e.Element("pubDate").Value),
                                       Url = e.Element("link").Value
                                   }).ToList();
                }
            }
            catch (Exception ex)
            {
                // should do some other
                // logging here. for now pass off
                // exception to callback on UI
                err = ex;
            }
            callback(results, err);
        }


That covers all of the code needed in the Portable Class(es) for getting the data, just need to edit the MainViewModel class constructor to create the DataService class, implement the new method and create a Headlines property.

MainViewModel
Add a new property for the headlines to be bound to by the UI.


        private List<Model.Headline> _headlines;
        public List<Model.Headline> Headlines
        {
            get { return _headlines; }
            set
            {
                _headlines = value;
                RaisePropertyChanged(() => Headlines);
            }
        }

In the constructor, create an instance of the DataService and execute the method.  I did mention earlier that there is an IDataService for DI, but for this example an concrete DataService class is created.


        public MainViewModel()
        {
            /// create a new dataservice class
            var service = new DataService();
       
            /// call getHeadlines passing headlines and exception delegate vars
            service.GetHeadlines((headlines, err) => {
                if (err != null)
                {
                    /// if there is an error should create a property and bind to it for better practices
                    System.Diagnostics.Debug.WriteLine(err.ToString());
                }
                else
                {
                    /// set the property
                    this.Headlines = headlines;
                }
            });
        }



Adding the UI Elements

Windows Phone

Open the MainPage.xaml page and wrap the previous TextBlock from part 1 in a StackPanel then add a ListBox.  Set the ItemsSource property of the ListBox to {Binding Headlines, Mode=TwoWay}, then add a simple template with a TextBlock to show the title of the story.


        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel>
            <TextBlock Text="{Binding Hello, Mode=TwoWay}" Foreground="White" FontSize="18" />
            <ListBox ItemsSource="{Binding Headlines, Mode=TwoWay}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <ListBoxItem>
                                <TextBlock Text="{Binding Title}" />
                            </ListBoxItem>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                     
            </ListBox>
            </StackPanel>
        </Grid>

Windows Store

The store app is just as easy.  In MainPage.xaml, add a GridView controls, set the ItemsSource to {Binding Headlines, Mode=TwoWay}, but in this case I'll define an ItemTemplate outside of the control called PCLItemTemplate and display the Title and the Description.


        <GridView ItemsSource="{Binding Headlines, Mode=TwoWay}" Grid.Row="1" ItemTemplate="{StaticResource PCLItemTemplate}" />
     

    <Page.Resources>
        <DataTemplate x:Key="PCLItemTemplate">
            <StackPanel Orientation="Vertical" Width="500" Height="250">
                <TextBlock Foreground="White" Text="{Binding Title}" FontSize="18" HorizontalAlignment="Center" Margin="20,10,20,0" TextTrimming="WordEllipsis"/>
                <TextBlock Foreground="White" Text="{Binding Description}" Style="{StaticResource ItemTextStyle}" HorizontalAlignment="Center" Margin="20,10" TextTrimming="WordEllipsis"/>
            </StackPanel>
        </DataTemplate>
    </Page.Resources>


Summary

 Running either apps presents the data in a different context and there is complete control as to the presentation and design choices based on the platform.  If you are looking to create Windows Store apps and/or Windows Phone applications  Portable Class Libraries is a great way to leverage code within your multiple platform target solution.  MvvmLight is a choice of mine and many others and fits very well too thanks to others in the community.



Full source code available here: http://sdrv.ms/WpBGqS
Read more →
Powered by Blogger.
 
Creative Commons License
TattooCoder.com by Shayne Boyer is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.