Microsoft’s Windows App Studio Beta : Connecting a Menu App to Azure Mobile Service
Scope
This article aims to connect the Menu App from Windows App Studio with Azure Mobile Service, using .Net back end.
Introduction
Windows App Studio is a service that allows any person without programming skills to create applications for Windows Phone and Windows. In just 4 steps: have an idea, add content, choose the style and use the application. The service provides a set of templates to help the users in creating various applications, theses templates are great starting points for specific uses which are more frequently used.
To understand all the steps for creating an app using App Studio see the article Creating Windows Phone and Window 8.1 applications using Microsoft App Studio. This article explains the Contoso Template and the Web Template.
Menu Template
Menu Template is one template provide by App Studio , and it is used for the following scenario:
“Do you own a restaurant, or have a favorite place you go every week? Use this template to show your customers or your friends about the delicious meal they’ll find there. With easy-to-navigate sections and pictures for starters, main courses and desserts.”
The template provides
-
A menu for
-
Starters
Contains a list of all starters
- Mains
Contains a list of all mains
-
Desserts
Contains a list of all desserts
- Beverages
Contains a list of all beverages
-
- A list of special offers
When the template is created, the default data uses static resources
If we click in “Edit data”, we will see the following screen
Windows App Studio allows us to export and import data, but each time we need to edit data, we need to publish the new version in the Store unless we select dynamic resources. For help in this process we will create a .Net Backend in Azure Mobile Service that allows us to manage the data that will be consumed by the Menu App.
See the default Menu App, for Windows Phone 8.1 and Windows 8.1 that was generated by
Understanding the source code
The source code provided has a solution that contains the following projects:
- AppStudio.Windows – project for Windows Store App
- AppStudio.WindowsPhone – project for the Windows Phone App
- AppStudio.Shared – shared project used for both target (it allow to reuse code)
- AppStudio.Data – project that contains the model and data source.
In AppStudio.Data project is possible to generate the class diagrams for understand the model and the data sources used in the application. This will be useful later.
The Model
The model contains all classes that represent the structure of the data used in the application.
Each class has more properties (DefaultTitle, DefaultSummary, DefaultImageUrl and DefaultContent), that uses the properties showed in class diagram and these properties only helps the automation used by App Studio , for this reason it was ignored.
The data sources
The data sources contains all classes that will provide the data that will fill the UI.
Each data source has a LoadDataAsync method that is called by each target to fill the data in UI.
Code
See the changes made in default Menu App, here:Step 2: Add class diagrams and fixes issues related with nomenclature.
Note: It is possible to change any code in the solution, but it is not possible to upload those changes back to Windows App Studio . Any change in AppStudio should be merged with changes made in Visual Studio.
Requirements
To use Azure Mobile Services it’s required to have an Azure Account and the Azure SDK should be installed.
Azure Account
Before starting the backend development it’s required to create an Azure account in the Azure Website . For new users there is a trial version that can be used, see more about it here .
Azure SDK
Get the Azure SDK and install it, from Downloads .
How to create the Azure Mobile Service in Azure Portal
For see details about how to create an Azure Mobile Service in Azure Portal and how to create the Visual Studio 2013 project, see the article
How to create the MyMenuApp Azure Mobile Service.
How to create the Azure Mobile Services
In the topic, “Understanding the source code > the model” we saw the model used in the Menu App, and it is important for the services. Recap, the model has theses classes
Each class represents specific information inside of the app and the service should allow us to store data for each class (this is the insert operation) and of course support for getting all items, get item by id, update an item and delete an item.Based in these classes, we will create the follow services
- MainSchemaController – the service for managing the MainSchemas
- SpecialOffersSchemaController – the service for managing the SpecialOffersSchemas
- DessertsSchemaController – the service for managingthe DessertsSchemas
- StartersSchemaController – the service for managing the StartersSchemas
- BeveragesSchemaController – the service for managing the BeveragesSchemas
Each service ends with the word “Controller” because this is a pattern from WebApi , which is the base for Azure Mobile Services and starts with the name of the related object, normally called Dto . Each developer should be aware of this, because these names will be used internally and if it does not match with the kind of pattern it can cause some problems in consuming the services, in serialization, or when client apps request specific queries.The data objects (Dtos) will be:
- MainSchema
- SpecialOffersSchema
- DessertsSchema
- StartersSchema
- BeveragesSchema
Each one will have the same structure as in the client app and they will inherit from EntityData which is the class from Azure Mobile Service that represents the system properties and are useful for offline mode.
To simplify the sample, we will map the dtos to the database.
Other solutions could be, to have the Dtos mapped with the model. This article, Build a service using an existing SQL database with the Mobile Services .NET backend , shows an example that has Dtos and a model, which are mapped to each other and the model is related with the database.
The first class created is a base class for the Dtos that contains shared properties.
Represents a base class for all Dtos and it inherits from EntityData.
public class DtoBase : EntityData
{
public string Title { get; set; }
public string Subtitle { get; set; }
public string Image { get; set; }
public string Description { get; set; }
}
The BeveragesSchema class
public class BeveragesSchema : DtoBase { }
The DessertsSchema class
public class DessertsSchema : DtoBase { }
The MainSchema class
public class MainSchema : DtoBase { }
The StartersSchema class
public class StartersSchema : DtoBase { }
The SpecialOffersSchema class
This class inherits from EntityData and not from the DtoBase because it does not share all properties like the others objects.
public class SpecialOffersSchema : EntityData
{
public string Dessert1 { get; set; }
public string Main1 { get; set; }
public string Starter1 { get; set; }
public string Title { get; set; }
public string Subtitle { get; set; }
}
Class Diagram
Here are the class diagrams
Note: All Dtos must be created inside the DataObject folder because when we create the table controller this object will be searched for there.
Services
Each service will be an Azure Mobile Service Table Controller
http://www.saramgsilva.pt/wp-content/uploads/2014/09/090914_1243_MicrosoftsW13.png
Each service should be defined as the following
http://www.saramgsilva.pt/wp-content/uploads/2014/09/090914_1243_MicrosoftsW14.png
The BeveragesSchemaController
Which the output will be something like
public class BeveragesSchemaController : TableController
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
MobileServiceContext context = new MobileServiceContext();
DomainManager = new EntityDomainManager(context, Request, Services);
}
//GET tables/BeveragesSchema1
public IQueryable GetAllBeveragesSchema()
{
return Query();
}
// GET tables/BeveragesSchema1/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult GetBeveragesSchema(string id)
{
return Lookup(id);
}
//PATCH tables/BeveragesSchema1/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task PatchBeveragesSchema(string id, Delta patch)
{
return UpdateAsync(id, patch);
}
// POST tables/BeveragesSchema1/48D68C86-6EA6-4C25-AA33-223FC9A27959
public async Task PostBeveragesSchema(BeveragesSchema item)
{
BeveragesSchema current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
//DELETEtables/BeveragesSchema1/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task DeleteBeveragesSchema(string id)
{
return DeleteAsync(id);
}
}
}
For the other services, the process is the same, only change the dto selected and the name of the controller. Note: The service will be inside the Controllers folder.
Class diagram
After creating all service, we will have
Validate data
Each service should validate the input data, to make sure that the following operation will not fail because the input is wrong. For example, suppose that the input object wasn´t sent in the right way, for this reason the serialization fails, it can be a request with n null input, that is not correct and it will throw an NullReferenceException in our service. Other case is when a required property is not filled and the service try to save or edit it and then it throw an DbEntityValidationException
Here is the code for insert a BeverageSchema that validate data
public async Task PostBeveragesSchema(BeveragesSchema item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
if (string.IsNullOrEmpty(item.Title)
|| string.IsNullOrEmpty(item.Subtitle)
|| string.IsNullOrEmpty(item.Image)
|| string.IsNullOrEmpty(item.Description))
{
return BadRequest("There are properties that are not defined.");
}
var current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
The same validation can be done in the others dtos.
The DomainManager
Each service has an Initialize method where it defined the DomainManager as following
DomainManager =new EntityDomainManager
This property is an IDomainManager and is used internally for all operations in the database, in this case it will be an EntityDomainManager of Beverages Schema.
The EntityDomainManager<T>
This class is an implementation of IDomainManager that contains the implementation for all operations required for the database, using the MobileServiceContext.
The MobileServiceContext
This class represents the DbContext Jump for the services that allow us to do the CRUD operation in the database the easy way. This class will be used by EntityDomainManager. The MobileServiceContext was changed because when each service was created. It was also automatically added the following DataSets
public DbSet BeveragesSchemas { get; set; }
public DbSet DessertsSchemas { get; set; } public DbSet MainSchemas { get; set; }
public DbSet SpecialOffersSchemas { get; set; }
public DbSet StartersSchemas { get; set; }
With this, we are mapping the Dto to the database. To understand more about this concept, which is related with Entity Framework, see the documentation about it,DbContext Class .
The Database
There are different ways to create the database, it can be created manually in SQL Server Management Studio , in Visual Studio or can be created using Code First .
This article will use Code First, that means we create the model first and then create the database based in the model structure.this process happens when we do a deploy. Like was mentioned earlier, our model is defined by the Dtos class.
When the project was created, we removed some code that was ignored, and with it we deleted the code related with the Database Initializer, that uses the classDropCreateDatabaseIfModelChanges it is an implementation of IDatabaseInitializer that will DELETE, recreate, and optionally re-seed the database only if the model has changed since the database was created.
If the model doesn’t change we can use it.
Are we sure that the model will not change in future?
Maybe this is not the best solution for create the database. For create the database and prevent future changes in model (in our case the dtos), we will use Entity Framework Migrations .
Note: There are others IDatabaseInitializer that can be used, but the problem is same, data will lost if the model changes.
Before we enable migration, we need to get the connection string to connect to the database and need to allow our IP to access the database.
Defining the connection string
The connection string must be defined in Web.config and can be a connection string from a local database, for local usage, or from the database created with the Azure Mobile Service.
The connection string from MyMenuApp_db database can be find in the Portal , by selecting the MyMenuApp Azure Mobile Service and then in Configure, as following
And then scroll to
In the project to go the Web.Config file and paste there the connection string
Note: Later, in the deployment process, this value is overridden with the connection string defined in Azure Mobile Service.
Defining the allowed IP for the database
For localhost tests it is required to allow our IP to access to the database.we need to go to the Portal , select the database MyMenuApp_db and then click in Dashboard, as following
Scroll down until to find the following menu in the right
And then allow the current IP
Migration
To have migration support we need to start with Enable-Migration. To do this, open the Tools menu in Visual Studio and then open the Package Manager Console
Now, in the Package Manager Console enable migration and add migration as following
The Migration folder was added to the project and it contains the configurations file and the migration V_0. This migration contains all information to create the database and the tables, it is used for revert the process if necessary.
Seed
In the Configuration file, it is possible to find the Seed method, that fills the database with some initial data or when there is any change in the model. it can be useful to update data in the database.
In our case, we will use it to fill the database with the static data from the Menu App.
Each data source in AppStudio.Data project, has the _data field that contains it. Here are the changed made
Now we need to add the DbMigrator to the WebApiConfig.Register method, as following
var migrator = newDbMigrator(newConfiguration());
migrator.Update();
s this that will create the database or will update the database following the current model.
Be aware that the seed method is called each time this code runs!
See more about it in this article How to make data model changes to a .NET backend mobile service .
Running the Services
Now that the services are ready, we can run the services in localhost or in the server. For testing it could useful to use the localhost first.
Localhost
To run the services in localhost, press the key F5. The following page will be shown
Click on “Try it out” to see the documentation page
This documentation is generated automatically, it allows us to know what is available, and the type of requests and responses we can do. We can play a bit with this, by clicking on one option, let’s see one case
Click on “try it out”, and the following window should appear
This allows us to make a request to get all the special offers from the service. Attention, there are a limit of items we can get, the best practice is to request some items and will request more when they are needed (It is used for create pagination).Click in the “send” and we will get the following response
This data is the data defined in Seed method.
Server
To deploy the services to the server, click on the project and open the context menu, then click on Publish as following
The then select Microsoft Azure Mobile Services to associate the project to the MyMenuApp Azure Mobile Service.
After it, click on the Publish button and then it is possible to follow the deployment in Web Publish Activity
Our default browser will open a window with the service.
If we click on “try it out”, it requires a key to access the documentation, that key is provided in the Portal , by selecting the MyMenuApp Azure Mobile Service and then at the bottom has the option for it
By clicking in the Manage Keys we will get
How to see details about errors
When we run the service, we get this windows
That means there is a problem. To understand what happened we can use the Logs from the MyMenuApp for see the errors.
Go to the Portal , by selecting the MyMenuApp Azure Mobile Service and then click on Logs, as follows
And then we get the list
Select the error and click at the bottom on the “details” button, and we will see the error
This error was made by adding an additional property in the model and wasn´t added the migration for update it in the database. See more about this subject in this articleTroubleshoot the Mobile Services .NET Backend .
How to do the remote debugging
When we run the code in localhost we can debug the services, but in some cases it can be useful to debug the code that is running in the server, it is called remotedebugging. In the MyMenuApp Azure Mobile Service > Configure be sure you have this on
Note: For how uses Visual Studio 2013 Update 2 or later it is turn on automatically In Visual Studio, open the View menu and the click in Server Explorer that will open the window as following
Then expand the Mobile Service and select the MyMenuApp service and click in attach debugger
The default browser will open the service and we shouldn´t close it until the debugging is done! Note: For it work we should deploy to the server using Debug Mode, in Release Mode it will not work. See more about it in Runtime Debugging . Set the breakpoint and do the request, then the breakpoint will be hit
Note: The services should be published as in debug mode.
Code
See the code created for AppStudion.Menu.Backend, here
Manage Images
In Azure Mobile Service, is best practice is to use Azure Blob Storage for saving the images used in the client apps. We only need to save, in the Azure SQL Database (MyMenuuApp_db), the image url.
This article will not cover this topic. To see how to implement this feature see the following article Upload images to Azure Storage by using Mobile Services . Which covers the topic for .Net Back End & Windows Store and .Net Back End & Windows Phone.
How to consume the Azure Mobile Services in Menu App
Now that we have the services running in the server, with the default data, is time to connect the Menu App with the MyMenuApp Azure Mobile services.
There two ways to add the Azure Mobile Service Client: installing the Nuget Package or using Connected Service.
Select the AppStudio.Data project, and then open the Manage Nuget Packages
Install the Windows Azure Mobile Services nuget package like the following
Is required to install this package in each target (Windows 8.1 and Windows Phone 8.1 apps).
Using Connected ServiceClick in the target project, and with the mouse open the context menu, then click in “Add” and “Connect Service…”
After it, login in using your Azure account and you will see your Azure Mobile Services as following
By clicking in the MyMenuApp Azure Mobile Service we will add the Nuget package for Azure Mobile Service
The MobileService<T><
package
id
=
"WindowsAzure.MobileServices"
version
=
"1.2.2"
targetFramework
=
"wpa81"
/>
After it, create the MobileService<T> class in DataSource folder in the AppStudio.Data project, as following
///
///DefinestheMobileServicewrapper.
///
///ThetypeoftheDTO.
publicsealedclassMobileService
{
privatestaticMobileServiceClient_appStudioBackEnd;
///
///Getstheapplicationstudiobackend.
///
///Theapplicationstudiobackend.
privatestaticMobileServiceClientAppStudioBackEnd
{
get
{
return_appStudioBackEnd??(_appStudioBackEnd=newMobileServiceClient("",""));
}
}
///
///Initializesanewinstanceofthe class.
///
publicMobileService()
{
Table=AppStudioBackEnd.GetTable();
}
///
///Getsorsetsthetable.
///
///
///Thetable.
///
publicIMobileServiceTableTable{get;set;}
}
Then for each data source do something like
public async override Task> LoadDataAsync()
{
var mobileService = new MobileService();
return await mobileService.Table.ToListAsync();
}
After this, run the Menu App.
Now the app has dynamic data that can be changed without changing the Menu App.