Universal App Development Using Office 365 API

About Office 365 API:

The office 365 API has a REST service that helps to access the data from the subscription. The office 365 subscription includes the Exchange, SharePoint and AD services. Office 365 API gives access to all those services via REST methods. The authentication to the service happens via the Azure AD. The single sign-on with Azure AD to authenticate your users, and let them access email, files, calendar, and user information, and the petabytes of data that are stored in Office 365.

Office 365 SDK

Office 365 SDK uses the oAuth to authenticate. It requires you to manage the authentication token, and construct the correct URL and queries for the API. The Office 365 SDK for Visual studio reduce the complexity of the code written for the queries and the access. The Office Developer Tools for Visual Studio includes the SDK for .NET and JS. For Universal App the Visual Studio tools offers an easy way to authenticate and access the REST API. The Office client SDK currently supports only the Windows Apps. For Windows Phone apps we need to use the REST API.

Development Tools

To start developing a Universal App for Windows you need to have the below setup

Office 365 Subscription

• Visual Studio Community Edition and Other edition

Office developer tools for VS 2013

• Nuget Library for the Active Directory Authentication

• Azure Active Directory Setup from Office 365 for the Windows Phone App

Create & Integrate Universal App with Office 365 SDK

1. Open Visual Studio 2013 and select the Visual C# -> Store App -> Universal Apps
2. Select the Blank App and enter the App Name to be UniversalOffice365 and click Ok.

New Project

3. After clicking on Ok a Windows App, Windows Phone App and Shared Projects are created.

Window Apps

Windows App with Office 365 Client SDK

1. Select the Windows App. In the Solution Explorer window, right click your project -> Add -> Connected Service.

Office 365 Client SDK

2. A Services Manager dialog box will appear. Choose Office 365 -> Office 365 API and click Register your app.

3. On the sign-in dialog box, enter the username and password for your Office 365 tenant. After signed in with the User Id and Password will see the list of services.

4. Select the My Files service and click on the Permissions on the right side. This will open the Permission window. Select the Read option. Click Apply and Click Ok.

Services Manager

5. Once the services are added Office 365 related references will be added to the Project for the Windows Apps.
6. The App permission and the key will be added to the App.xaml file in the UniversalOfficeSDK.Shared project
7. Now the App is integrated with the Office 365 SDK.

Create Model and Helper Class for Windows App

1. Select the UniversalOffice365.Shared from the solution. Create the folders DataModel & Helper

Create Model

2. Create a class called SharePointFile under the DataModel folder.

3. Add the below code.
public class SharePointFile
{
public String Name { get; set; }
}

4. Install the Nuget package for the “Active directory Authentication Library”. To install use the package manager console and type the command “Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory -Pre”. In the sample below I installed the Prerelease version of it. If you install the stable version the API might be slightly different.

Install The Nuget Package

Nuget Manager Console

Nuget Manager Console

5. Under the Helper folder Add a class called AuthenticationHelper.cs and add below code to the class

public partial class AuthenticationHelper
{
public static readonly string DiscoveryServiceResourceId = “https://api.office.com/discovery/”;
const string AuthorityFormat = “https://login.windows.net/{0}/”;
static readonly Uri DiscoveryServiceEndpointUri = new Uri(“https://api.office.com/discovery/v1.0/me/”);
static readonly string ClientId = App.Current.Resources[“ida:ClientID”].ToString();
static ApplicationDataContainer AppSettings = ApplicationData.Current.LocalSettings;
static string _authority = String.Empty;
static string _lastTenantId = “common”;
const string _lastTenantIdKey = “LastAuthority”;
static AuthenticationContext authContext = null;
public static Uri AppRedirectURI
{
get
{
return WebAuthenticationBroker.GetCurrentApplicationCallbackUri();
}
}

public static string LastTenantId
{
get
{
if (AppSettings.Values.ContainsKey(_lastTenantIdKey) && AppSettings.Values[_lastTenantIdKey] != null)
{
return AppSettings.Values[_lastTenantIdKey].ToString();
}
else
{
return _lastTenantId;
}
}
set
{
_lastTenantId = value;
AppSettings.Values[_lastTenantIdKey] = _lastTenantId;
}
}

public static string Authority
{
get
{
_authority = String.Format(AuthorityFormat, LastTenantId);

return _authority;
}
}

public static async Task<AuthenticationResult> GetAccessToken(string serviceResourceId)
{
AuthenticationResult authResult = null;
if (authContext == null)
{

#if WINDOWS_PHONE_APP
AuthorizationParameters parameters = new AuthorizationParameters();
#else
AuthorizationParameters parameters = new AuthorizationParameters(PromptBehavior.Auto,false);
authContext = new AuthenticationContext(Authority);
authResult = await authContext.AcquireTokenAsync(serviceResourceId, ClientId, AppRedirectURI, parameters);
#endif
}
else
{
authResult = await authContext.AcquireTokenSilentAsync(serviceResourceId, ClientId);
}

LastTenantId = authResult.TenantId;
return authResult;
}

}

6. Now open the mainpage.xaml from the UniversalOffice365.Windows project. Add the below Xaml in the MainPage.xaml.

<Grid Background=”{ThemeResource ApplicationPageBackgroundThemeBrush}”>
<StackPanel>
<Button Name=”GetFiles” Content=”GetFiles” HorizontalAlignment=”Left” Margin=”269,105,0,0″ VerticalAlignment=”Top” Height=”60″ Width=”171″ Click=”GetFiles_Click”/>
<ProgressBar Margin=”10″ Visibility=”Collapsed” Name=”prgRing” Height=”50″ HorizontalAlignment=”Stretch” Foreground=”YellowGreen” IsIndeterminate=”True” />
<ListBox Margin=”20,10,20,30″ x:Name=”lstMyFiles” Height=”Auto” Width=”Auto” ItemsSource=”{Binding Files, ElementName=page}”>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text=”{Binding Name}” Margin=”4″/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>

7. Now open the MainPage.xaml.cs and add the below code

public sealed partial class MainPage : Page
{
public ObservableCollection<SharePointFile> Files { get; set; }
public MainPage()
{
this.InitializeComponent();
Files = new ObservableCollection<SharePointFile>();
}
private async void GetFiles_Click(object sender, RoutedEventArgs e)
{
prgRing.Visibility = Windows.UI.Xaml.Visibility.Visible;
Files.Clear();
DiscoveryClient discoveryClient = new DiscoveryClient(
async () =>
{
var authResult = await AuthenticationHelper.GetAccessToken(AuthenticationHelper.DiscoveryServiceResourceId);

return authResult.AccessToken;
}
);
var appCapabilities = await discoveryClient.DiscoverCapabilitiesAsync();
var myFilesCapability = appCapabilities
.Where(s => s.Key == “MyFiles”)
.Select(p => new { Key = p.Key, ServiceResourceId = p.Value.ServiceResourceId, ServiceEndPointUri = p.Value.ServiceEndpointUri })
.FirstOrDefault();
if (myFilesCapability != null)
{
SharePointClient myFilesClient = new SharePointClient(myFilesCapability.ServiceEndPointUri,
async () =>
{
var authResult = await AuthenticationHelper.GetAccessToken(myFilesCapability.ServiceResourceId);

return authResult.AccessToken;
});
var myFilesResult = await myFilesClient.Files.ExecuteAsync();
do
{
var myFiles = myFilesResult.CurrentPage;
foreach (var myFile in myFiles)
{
Files.Add(new SharePointFile { Name = myFile.Name });
}
myFilesResult = await myFilesResult.GetNextPageAsync();

} while (myFilesResult != null);
if (Files.Count == 0)
{
Files.Add(new SharePointFile { Name = “No files to display!” });
}
lstMyFiles.ItemsSource = Files;
prgRing.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
else
{
MessageDialog dialog = new MessageDialog(string.Format(“This Windows app does not have access to users’ files. Please contact your administrator.”));
await dialog.ShowAsync();
}
}
}

8. Now execute the Windows Application GetFiles button will be displayed. Clicking on Get Files, it should ask for the Office 365 Login first. Then it asks for the consent to grant permission for My Files. Once successful all the files in OneDrive will be displayed in the App.

Windows Application Get Files

That’s it for the Windows App. Now proceed to setup for the Windows Phone 8.1 app. As of now there is no support for Office 365 client SDK for windows phone. So we need to use the REST API for the Phone project.

Windows Phone 8.1 App with Office 365

1. This sample WP 8.1 app will use the Mail from Office 365 and get all the messages from the Inbox folder. Make sure you have less email in the Inbox. Since this is sample app if you have many emails the app might be very slow or might get some time out error.

2. Select the UniversalOffice365.WindowsPhone project. Right click and Set as Startup Project.

3. Right click on the Project again and select New Item and select Interface. Name the Interface as IWebAuthenticationContinuable.cs add the below code

interface IWebAuthenticationContinuable
{
void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args);
}

4. Open the MainPage.Xaml and the below code
<Grid Background=”{ThemeResource ApplicationPageBackgroundThemeBrush}”>
<StackPanel>
<Button Name=”GetFiles” Content=”GetFiles” HorizontalAlignment=”Left” Margin=”50″ VerticalAlignment=”Top” Height=”60″ Width=”171″ Click=”GetFiles_Click”/>
<ScrollViewer VerticalScrollBarVisibility=”Auto” Height=”450″>
<TextBlock Name=”MessageText” FontSize=”18″ TextWrapping=”Wrap” />
</ScrollViewer>
<ProgressBar Margin=”10″ Visibility=”Collapsed” Name=”prgRing” Height=”50″ HorizontalAlignment=”Stretch”
Foreground=”YellowGreen” IsIndeterminate=”True” />
</StackPanel>
</Grid>

5. Before adding code to the class, we need to add Authentication and access settings in the Azure AD. Need to add the application to the AD and assign the access.

Add Application to Azure Active Directory

1. You need to be the Office 365 Admin to set up this AD. Login to the Office 365 Portal as Admin. Select the Admin menu to open the Admin console.

2. Scroll down to the Admin section and click on Azure AD.

Azure Active Directory

3. Depends on the subscription the Azure Access will be available. If the Azure is not setup, create the Azure subscription using the Office 365 Login id. If you have already Azure Subscription it will login to the Azure subscription.

4. In the Azure subscription select the Active Directory and Select the Domain Name to add the Application.

Azure Subscription

5. Select the Native Client Application and enter the name UniversalOffice365.

Universal Office 365.

6. Enter the redirect URL as below https://outlook.office365.com/ and then click on the Tick to create the Application.

Redirect URL

7. After adding the application scroll down to bottom Add Application green button. Add the Office 365 Exchange Online and the Windows Azure Active Directory. In the Delegate Permission select the below
Windows Azure Active Director

For Active Directory choose below.

For Active Directory
Click on Save to save the permission to the Application.

8. Now a CLIENT ID will be generated for the Application. Use the Client ID for the subsequent code in the windows phone app.

CLIENT ID

Add the code to get the Mail Inbox

1. Now open the Windows Phone project. Select the MainPage.xaml.cs and add the below code. Make sure you inherit the MainPage from IWebAuthenticationContinuable. In the below code make sure you use the correct URL for the Authority and the ClientID.

public sealed partial class MainPage : Page, IWebAuthenticationContinuable
{
string Authority = “https://login.windows.net/<YOUROFFICE SUBSCRIPTION NAME>.onmicrosoft.com”;
string Resource = “https://outlook.office365.com/”;
string ClientID = “<CLIENT ID from AD>”;
string RedirectUri = “https://outlook.office365.com/”;

public ObservableCollection<SharePointFile> Files { get; set; }
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
Files = new ObservableCollection<SharePointFile>();
}

/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name=”e”>Event data that describes how this page was reached.
/// This parameter is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// TODO: Prepare page for display here.

// TODO: If your application contains multiple pages, ensure that you are
// handling the hardware Back button by registering for the
// Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
// If you are using the NavigationHelper provided by some templates,
// this event is handled for you.
}

private void GetFiles_Click(object sender, RoutedEventArgs e)
{
prgRing.Visibility = Windows.UI.Xaml.Visibility.Visible;
RequestCode();
}

public async void ContinueWebAuthentication(Windows.ApplicationModel.Activation.WebAuthenticationBrokerContinuationEventArgs args)
{
string access_token = await RequestToken(args.WebAuthenticationResult);
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Bearer”, access_token);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(“application/json”));
HttpResponseMessage response = httpClient.GetAsync(“https://outlook.office365.com/api/v1.0/me/folders/inbox/messages?$select=Subject,Body,ToRecipients”).Result;
if (response.IsSuccessStatusCode)
{
MessageText.Text = (response.Content.ReadAsStringAsync().Result);
}
}
private void RequestCode()
{
string authURL = string.Format(
“{0}/oauth2/authorize?response_type=code&resource={1}&client_id={2}&redirect_uri={3}”,
Authority,
Resource,
ClientID,
RedirectUri);
WebAuthenticationBroker.AuthenticateAndContinue(new Uri(authURL), new Uri(RedirectUri), null, WebAuthenticationOptions.None);
}

private async Task<string> RequestToken(WebAuthenticationResult rez)
{
if (rez.ResponseStatus == WebAuthenticationStatus.Success)
{
string code = ParseCode(rez.ResponseData);
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, string.Format(“{0}/oauth2/token”, Authority));
string tokenreq = string.Format(
“grant_type=authorization_code&code={0}&client_id={1}&redirect_uri={2}”,
code, ClientID, Uri.EscapeDataString(RedirectUri));
request.Content = new StringContent(tokenreq, Encoding.UTF8, “application/x-www-form-urlencoded”);

HttpResponseMessage response = await client.SendAsync(request);
string responseString = await response.Content.ReadAsStringAsync();

var jResult = JObject.Parse(responseString);
return (string)jResult[“access_token”];
}
else
{
throw new Exception(String.Format(“Something went wrong: {0}”, rez.ResponseErrorDetail.ToString()));
}
}

private string ParseCode(string result)
{
int codeIndex = result.IndexOf(“code=”, 0) + 5;
int endCodeIndex = result.IndexOf(“&”, codeIndex);
// Return the access code as a string
return result.Substring(codeIndex, endCodeIndex – codeIndex);
}
}

2. Now open the App.xaml.cs on the Shared Project. Add the code for OnActivated event. This event will be fired after the authentication happens from the WP 8.1. Add the below code at the end of App.xaml.cs
#if WINDOWS_PHONE_APP
protected override void OnActivated(IActivatedEventArgs args)
{
var rootFrame = Window.Current.Content as Frame;
var wabPage = rootFrame.Content as IWebAuthenticationContinuable;
if (wabPage != null)
{
wabPage.ContinueWebAuthentication(args as WebAuthenticationBrokerContinuationEventArgs);
}
Window.Current.Activate();
}
#endif

3. Run the windows phone app now. This sample will get the json string and show in the output. Later you can use the json to parse and show it to listbox or controls. You can use http://jsonclassgenerator.codeplex.com/ to generate the CS file and get the object. But this sample don’t use this classes it just display the string json.

Windows Phone App

Hope the above code helps. The complete source code will be available soon. I am working on the code to just strip off the O365 integration to be made available to download.

Share Point Data Fundamentals

About the author Senthamil Selvan:

Senthamil SelvanSenthamil Selvan is a Windows Consumer Apps MVP. He has over 13+ years of experience in IT industry. He has experience in pre-sales, design, development and deployment of SharePoint and Office 365 Applications. He is passionate on Windows Phone and Windows tablet app design and development. He is managing his own Windows Phone UG in Singapore. He had developed several App for windows phone and tablet. Below are the few apps from his collection on the Windows store.

Math Formulas for Windows Phone
Animal Taxonomy for Windows Phone
SG Parking for Windows Phone
Mani Samayal for Windows Phone
Ultimate Player for Windows 8
SG Things To Do for Windows 8
SEA SPC 2014 Universal App
SCU APAC 2015 Universal App

Twitter handle: @altfo
Blog: http://altfo.wordpress.com

Check out last years European SharePoint Conference video:

European SharePoint Conference 2015 takes places in Stockholm Sweeden from 9-12 November 2015.

Share this on...

Rate this Post:

Share: