Scope
The purpose of this article is to connect the Menu App from Windows App Studio with Azure Mobile Service, using the .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 to create various applications, theses templates are great starting points for specific uses that 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 Conto so Template and the Web Template.
Menu Template
Menu Template is a template provide by App Studio and it is used for the following purpose:
“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:
Step 1: Add default Menu App generated by AppStudio.
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 targets (it allows the reuse of code)
- AppStudio.Data: project that contains the model and data source
In the AppStudio.Data project it is possible to generate the class diagrams to 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 the class diagram and these properties only help 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 the UI.
Code
See the changes made in the 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.
RequirementsTo 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 SDKGet the Azure SDK and install it, from
Downloads.
How to create the Azure Mobile Service in Azure PortalFor the details of how to create an Azure Mobile Service in the 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.
To 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 the WebApi, that 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 that 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, that are mapped to each other and the model is related with the database.
Dtos
The first class created is a base class for the Dtos that contain shared properties.
The Dtobase class
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 DiagramHere 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.
Each service should be defined as in the following:
The BeveragesSchemaController Which the output will be something like:
- public class BeveragesSchemaController : TableController<BeveragesSchema>
- {
- protected override void Initialize(HttpControllerContext controllerContext)
- {
- base.Initialize(controllerContext);
- MobileServiceContext context = new MobileServiceContext();
- DomainManager = new EntityDomainManager<BeveragesSchema>(context, Request, Services);
- }
-
-
- public IQueryable<BeveragesSchema> GetAllBeveragesSchema()
- {
- return Query();
- }
-
-
- public SingleResult<BeveragesSchema> GetBeveragesSchema(string id)
- {
- return Lookup(id);
- }
-
-
- public Task<BeveragesSchema> PatchBeveragesSchema(string id, Delta<BeveragesSchema> patch)
- {
- return UpdateAsync(id, patch);
- }
-
-
- public async Task<IHttpActionResult> PostBeveragesSchema(BeveragesSchema item)
- {
- BeveragesSchema current = await InsertAsync(item);
- return CreatedAtRoute("Tables", new { id = current.Id }, current);
- }
-
-
- 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 the services, we will have something.
Validate data
Each service should validate the input data, to ensure 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. Another case is when a required property is not filled and the service tries to save or edit it and then it throws a DbEntityValidationException.
Here is the code to insert a BeverageSchema that validates the data:
- public async Task<IHttpActionResult> 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 other dtos.
The DomainManagerEach service has an Initialize method where it defines the DomainManager as in the following:
DomainManager =new EntityDomainManager<BeveragesSchema>(context, Request, Services);
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 for the services that allow us to do the CRUD operations in the database the easy way. This class will be used by the EntityDomainManager.
The MobileServiceContext was changed because when each service was created, it was also automatically added to the following DataSets:
- public DbSet<Data.BeveragesSchema> BeveragesSchemas { get; set; }
- public DbSet<DataObjects.DessertsSchema> DessertsSchemas { get; set; } public DbSet<DataObjects.MainSchema> MainSchemas { get; set; }
- public DbSet<DataObjects.SpecialOffersSchema> SpecialOffersSchemas { get; set; }
- public DbSet<DataObjects.StartersSchema> StartersSchemas { get; set; }
With this, we are mapping the Dto to the database.
To understand more about this concept that is related to the Entity Framework, see the documentation about it,
DbContext Class.
The Database
There are various 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. As said 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 class
DropCreateDatabaseIfModelChanges that 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 the future?
Maybe this is not the best solution for creating the database. To create the database and prevent future changes in the model (in our case the dtos), we will use
Entity Framework Migrations.
Note: There are others of
IDatabaseInitializer that can be used, but the problem is the same, the data will be 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 found in the
Portal, by selecting the MyMenuApp Azure Mobile Service and then in Configure as in the following:
And then scroll to:
In the project, go to 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 the Azure Mobile Service.
Defining the allowed IP for the database
For localhost tests it is required to allow our IP to access the database. We need to go to the
Portal, select the database MyMenuApp_db and then click in Dashboard as in the following:
Scroll down to find the following menu in the right:
And then allow the current IP as in the following:
MigrationTo 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 as in the following:
Now, in the Package Manager Console enable migration and add migration as follows:
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 to revert the process if necessary.
SeedIn 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 the AppStudio.Data project has the _data field that contains it. Here are the changes made:
Now we need to add the
DbMigrator to the WebApiConfig.Register method as in the following:
- var migrator = new DbMigrator(new Configuration());
- migrator.Update();
Is 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.
LocalhostTo 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 to create pagination).
Click in the “send” and we will get the following response:
This data is the data defined in the Seed method.
ServerTo deploy the services to the server, click on the project and open the context menu, then click on Publish as in the following:
Then select Microsoft Azure Mobile Services to associate the project to the MyMenuApp Azure Mobile Service.
Then 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 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 window:
That means there is a problem. To understand what happened we can use the Logs from the MyMenuApp to see the errors.
Go to the
Portal, then select 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 article
Troubleshoot 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 remote debugging.
In the MyMenuApp Azure Mobile Service seelct Configure and be sure you have this on:
Note: For how to use Visual Studio 2013 Update 2 or later, it is turned on automatically.
In Visual Studio, open the View menu and the click in Server Explorer that will open the window as in the following:
Then expand the Mobile Service and select the MyMenuApp service and click "Attach Debugger".
The default browser will open the service and we shouldn´t close it until the debugging is done!
Note: For it to 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 as in the following:
Note: The services should be published as in debug mode.
CodeSee the code created for AppStudion.Menu.Backend, here:
Step 4: Changes the BackEnd project: add the Dtos, add Services, changes the MobileServiceContext and add support for migrations.Manage Images
In Azure Mobile Service, it is a best practice 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. That 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, it is time to connect the Menu App with the MyMenuApp Azure Mobile services.
There are two ways to add the Azure Mobile Service Client: installing the Nuget Package or using a Connected Service.
Using Managed Nuget Pacakges
Select the AppStudio.Data project and then open the "Manage Nuget Packages..." as in the following:
Install the
Windows Azure Mobile Services Nuget package as in the following:
It is necessary 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…”.
Then login in using your Azure account and you will see your Azure Mobile Services as in the following:
By clicking in the MyMenuApp Azure Mobile Service we will add the Nuget package for Azure Mobile Service as in the following:
- <package id="WindowsAzure.MobileServices" version="1.2.2" targetFramework="wpa81" />
The MobileService<T>Then create the MobileService<T> class in the DataSource folder in the AppStudio.Data project as in the following:
-
-
-
-
- public sealed class MobileService<T>
- {
- private static MobileServiceClient _appStudioBackEnd;
-
-
-
-
-
- private static MobileServiceClient AppStudioBackEnd
- {
- get
- {
- return _appStudioBackEnd ?? (_appStudioBackEnd = new MobileServiceClient("<the service url>", "<the application key from Portal>"));
- }
- }
-
-
-
-
- public MobileService()
- {
- Table = AppStudioBackEnd.GetTable<T>();
- }
-
-
-
-
-
-
-
- public IMobileServiceTable<T> Table { get; set; }
- }
Then for each data source do something like:
- public async override Task<IEnumerable<SpecialOffersSchema>> LoadDataAsync()
- {
- var mobileService = new MobileService<SpecialOffersSchema>();
- 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.
Code
See the code here:
Step 5: Changes the client app: add support for consuming MyMenuApp Azure Mobile Service.