Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Getting Started Personal Tab

Mika Berglund edited this page Feb 6, 2021 · 4 revisions

Writing a Personal Tab Application

The easiest tab application you can write for Teams is a personal tab application. That's because you only need a content page that represents the UI of your application. You don't need to have a configuration page like you do with channel tabs for instance.

In this sample, we'll demonstrate how you use Blazorade Teams to create a personal tab application that will authenticate the user with Azure AD, get an Access Token to Microsoft Graph, and connect to it to get basic information about the user.

Prerequisites

Before continuing with this sample, make sure that you have completed the following sections.

  • Add Reference - Using the Nuget package will do for this demonstration.
  • Register Application - This application needs the User.Read delegated permission, which is added by default to all applications you register with Azure AD.
  • Wiring Up - Use the client ID of the application you registered when configuring your application.
  • Login Page - If you are using authentication in your application, you need to have a login page that Blazorade Teams uses together with Teams to do interactive login, in case that is needed.

Adding the Page and View Components

Even though not necessarily required, you can consider it as a good practice to separate different UI elements into separate components. In this case, we have the content page for our personal tab, which is represented by a page component.

For this sample, we will have the following two components.

  • Pages/PersonalTab - The content page for our personal tab application.
  • Shared/UserInfoView - A component that uses Microsoft Graph to read basic information about the logged in user.

UserInfoView Component

We'll start with the view component. Locate the Shared folder in your project, and add a new Razor component to that folder. Let's call it UserInfoView. Even though you can write all your code in the .razor file, you might want to consider separating your code from the UI. So, let's add a class file to the same Shared folder, and use the file name UserInfoView.razor.cs. This will automatically associate the class file with the component.

Now you have the following two files in your Shared folder.

  • UserInfoView.razor
    • UserInfoView.razor.cs

Open up the code file (UserInfoView.razor.cs), and add the following code to the file.

using System;
using System.Threading.Tasks;
using Blazorade.Teams.Model;
using Microsoft.AspNetCore.Components;

namespace TeamsTabAppServer.Shared
{
    partial class UserInfoView
    {

        [Parameter]
        public ApplicationContext Context { get; set; }

    }
}

We'll come back to the actual implementation of this component. For now, this is enough that we can use the component in our page.

PersonalTab Page Component

Locate the Pages folder in your Blazor application, and add a new Razor component to it. Let's call it PersonalTab.razor.

Clear all of the file's content, and add the following.

@page "/personaltab"

<TeamsApplication RequireScopes="User.Read">
    <ApplicationTemplate Context="ctx">
        <UserInfoView Context="@ctx" />
    </ApplicationTemplate>
</TeamsApplication>

The page component does not have any code to store in a separate code file. In fact, this is all you need to have in your page component. The TeamsApplication component will take care of the rest for you.

It is not necessary to specifically name the context variable ctx, but it is named in the sample above to highlight the fact that the context object is provided to your template by the TeamsApplication component. If you don't explicitly name the variable, it will use the default name context.

Connecting to Microsoft Graph

OK, so we're back with the UserInfoView component. This component will be connecting to Microsoft Graph to get basic information about the logged in user. This should be enough to demonstrate how easy such a task is with Blazorade Teams.

Add Reference to Microsoft.Graph

The first thing you need to do is to add a reference to the Microsoft.Graph Nuget package.

Create an Authentication Provider

In order to be able to communicate with Microsoft Graph using the Microsoft.Graph library, you need to have an authentication provider. The authentication provider will be responsible for authenticating each request sent to Microsoft Graph.

So to do that, add a new class to your project. Let's call it AuthenticationProvider. You will need the following using statements in your class file.

using Blazorade.Teams.Model;
using Microsoft.Graph;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

Then, your AuthenticationProvider class would look like this.

internal class AuthenticationProvider : IAuthenticationProvider
{
    public AuthenticationProvider(ApplicationContext context)
    {
        this.Context = context
            ?? throw new ArgumentNullException(nameof(context));
    }

    private ApplicationContext Context;

    public async Task AuthenticateRequestAsync(HttpRequestMessage request)
    {
        var authResult = await this.Context.TeamsInterop.Authentication
            .GetAuthenticationResultAsync(this.Context.Context);
        request.Headers.Authorization = new AuthenticationHeaderValue(
            "Bearer", 
            authResult.AccessToken
        );
    }
}

The AuthenticateRequestAsync will use the interop classes provided by Blazorade Teams to get the authentication information for the user. This information is cached in the client my MSAL.js, so it will be fast to get. Or, if the information has expired, MSAL.js will take care of refreshing the information for us.

Implement UserInfoView Component

Now we are ready to write the implementation of our UserInfoView component. First, make sure you have the following using statements in your UserInfoView.razor.cs class file you created above.

using Blazorade.Teams.Model;
using Microsoft.AspNetCore.Components;
using Microsoft.Graph;
using System.Threading.Tasks;

Then, add the following parameter properties to your class. Note that the Context parameter is already implemented, but is included here for the sake of completeness. These parameters are used to hold the information that we are displaying in the component.

[Parameter]
public ApplicationContext Context { get; set; }

[Parameter]
public string DisplayName { get; set; }

[Parameter]
public string Email { get; set; }

[Parameter]
public string FirstName { get; set; }

[Parameter]
public string JobTitle { get; set; }

[Parameter]
public string LastName { get; set; }

[Parameter]
public string MobilePhone { get; set; }

[Parameter]
public string Upn { get; set; }

Then, we just need to add the OnParametersSetAsync method to our class, and we're done. Add the following method implementation to your UserInfoView component class.

protected async override Task OnParametersSetAsync()
{
    var authProvider = new AuthenticationProvider(this.Context);
    GraphServiceClient client = new GraphServiceClient(authProvider);
    var me = await client.Me.Request().GetAsync();

    this.DisplayName = me.DisplayName;
    this.FirstName = me.GivenName;
    this.LastName = me.Surname;
    this.JobTitle = me.JobTitle;
    this.Email = me.Mail;
    this.MobilePhone = me.MobilePhone;
    this.Upn = me.UserPrincipalName;

    await base.OnParametersSetAsync();
}

That completes the application.

Next Steps

Now that you have completed writing the application, it is time to test it. Please have a look at Getting Started - Using App Studio to learn how you can very easily run your app inside of Teams on your local machine.

Summary

As you can see, Blazorade Teams makes it so much easier to write Teams application, when you don't have to take care of every little detail. You can just focus on writing your application.

The source code listed on this page is also available in the Blazorade Teams repository, in the TeamsTabAppServer sample application.