Tutoriel : Créer une application OneNote

S’applique à : Blocs-notes consommateur sur OneDrive | Blocs-notes d’entreprise sur Office 365

Ce tutoriel vous montre comment créer une application simple qui utilise l’API OneNote pour obtenir et créer du contenu OneNote. L'application que nous allons créer effectue deux appels à l’aide de l’API OneNote REST :

  • Obtenir le nom et l’identifiant des 10 sections modifiées le plus récemment.

    GET ../notes/sections?select=name,id&top=10&orderby=lastModifiedTime%20desc

  • Créer une page dans une section spécifique.

    POST ../notes/sections/{id}/pages

Choisissez votre plateforme :

Notes

Ce didacticiel a pour but de montrer comment accéder à l’API OneNote, mais il ne contient pas de code prêt pour la production. Lors de la création de votre application, examinez attentivement votre code pour connaître les éventuels problèmes de sécurité, de validation et autres problèmes de qualité du code.

Créer une application OneNote pour iOS

L’application utilise le SDK OneDrive pour iOS pour gérer l’authentification et les appels réseau.

Conditions préalables

Voici ce dont vous aurez besoin pour suivre ce tutoriel :

Créer une application OneNote pour iOS

  1. Créez le projet
  2. Ajoutez la dépendance SDK OneDrive
  3. Construisez l’interface utilisateur
  4. Ajoutez un support d’authentification
  5. Appeler l’API OneNote

Des exemples de code complet pour les fichiers clés sont inclus à la fin du tutoriel.

Créez le projet dans Xcode

  1. Dans Xcode, créez un projet Application à vue unique pour iOS nommé OneNote-iOS-App. Choisissez Objectif C, et sélectionnez les appareils iPhone.

  2. Une fois le projet créé, fermez Xcode. Vous ouvrirez l’espace de travail après avoir créé un fichier Podfile.

Ajoutez la dépendance SDK OneDrive

L'application de ce tutoriel utilise le SDK OneDrive pour l’authentification des comptes Microsoft (anciennement Live Connect) et Azure Active Directory. L'authentification de compte Microsoft est utilisée pour accéder aux ordinateurs portables grand public sur OneDrive. L’authentification Azure AD est utilisée pour accéder aux ordinateurs portables d’entreprise sur Office 365.

  1. Exécutez ces commandes dans le Terminal pour créer un fichier Podfile et ouvrez le fichier dans Xcode.

    cd {path to the OneNote-iOS-App project directory} 
    touch podfile 
    open -a xcode podfile 
    
  2. Ajoutez la dépendance SDK OneDrive au fichier Podfile, puis enregistrez le fichier.

    pod 'OneDriveSDK'
    
  3. Exécutez ces commandes dans le Terminal pour installer la dépendance et ouvrez l’espace de travail du projet dans Xcode. Vous devriez recevoir une confirmation lorsque l’installation est terminée.

    pod install
    open onenote-ios-app.xcworkspace/
    

Applications Xcode 7 qui ciblent iOS 9.0

Si vous ciblez iOS 9 avec Xcode 7, vous devez activer les exceptions PFS. Voir la section Sécurité du transport pour les applications iOS 9 dans le readme du SDK OneDrive pour iOS pour la marche à suivre.

Construisez l’interface utilisateur

Ajoutez un sélecteur qui affiche les 10 dernières sections modifiées de l’utilisateur et un bouton qui crée une page OneNote dans la section sélectionnée.

  1. Dans Xcode, ouvrez Main.storyboard et changez le contrôle de classe de taille (en dessous de la zone de travail) en wCompact/hAny.

  2. Faites glisser une vue de sélecteur et un bouton depuis la bibliothèque d’objets vers la zone de travail. Utilisez Créer une page pour le texte du bouton.

  3. Créez des connexions pour la vue du sélecteur :
    a. Faites glisser la vue du sélecteur vers l’icône Contrôleur de Vue située au-dessus de la zone de travail. Choisissez la sortie dataSource.
    b. Répétez pour la sortie delegate.
    c. Choisir Affichage> Assistant Editeur> Afficher l’Assistant Éditeur et ouvrez ViewController.h dans une deuxième fenêtre.
    d. Faites glisser la vue du sélecteur de la zone de travail dans le bloc de code @interface en maintenant la touche Contrôle appuyée. Insérez une connection Outlet nommée sectionPicker.

  4. Créez des connexions pour le bouton :
    a. Faites glisser le bouton de la zone de travail dans le bloc de code @interface en maintenant la touche Contrôle appuyée. Insérez une connection Outlet nommée createPageButton.
    b. Ouvrez ViewController.m dans l’éditeur de l’assistant.
    c. Faites glisser le bouton de la zone de travail dans le bloc de code @implementation en maintenant la touche Contrôle appuyée. Insérez une connexion Action nommée createPage pour l’événement Touch Up Inside.

  5. Déclarez les protocoles UIPickerViewDelegate et UIPickerViewDataSource.

    ViewController.h devrait ressembler à ceci :

     import <UIKit/UIKit.h>
    
     @interface ViewController : UIViewController<UIPickerViewDelegate, UIPickerViewDataSource>
    
     @property (weak, nonatomic) IBOutlet UIPickerView *sectionPicker;
     @property (weak, nonatomic) IBOutlet UIButton *createPageButton;
    
     @end
    
  6. Dans ViewController.m, ajoutez les méthodes de délégué suivantes pour la vue du sélecteur.

     #pragma mark - Delegate Methods
    -(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
        return 1;
    }
    
    -(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
        return sectionNamesForPicker.count;
    }
    
    -(NSString *)pickerView:(UIPickerView*)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
        return [sectionNamesForPicker objectAtIndex:row];
    }
    

    Ne vous inquiétez pas des erreurs pour sectionNamesForPicker. Nous ajouterons la variable plus tard.

  7. Dans la méthode viewDidLoad, ajoutez le code suivant pour connecter le sélecteur après la ligne [super viewDidLoad].

     self.sectionPicker.delegate = self;
     self.sectionPicker.dataSource = self;
    

Ajoutez un support d’authentification

Le SDK OneDrive gère l’authentification et l’autorisation pour vous. Vous devrez simplement fournir des identifiants pour votre application, puis utiliser l’ODClient. Le SDK appelle l’IU de connexion la première fois que l’utilisateur exécute l’application, puis stocke les informations de compte. (En savoir plus sur l’authentification dans le SDK.)

  1. Dans AppDelegate.m, importez le SDK OneDrive.

     #import <OneDriveSDK/OneDriveSDK.h>
    
  2. Remplacez la méthode didFinishLaunchingWithOptions par le code suivant.

    Ensuite, remplacez les valeurs de propriétés par défaut par les informations de vos applications enregistrées. Si vous testez avec une seule application, vous pouvez commenter les propriétés que vous n’utilisez pas.

      (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
         // Set the client ID and permission scopes of your app registered on the Microsoft account Developer Center.
         static NSString *const msaClientId = @"000000001A123456";
         static NSString *const msaScopesString = @"wl.signin,wl.offline_access,office.onenote_update";
    
         // Set the client ID and redirect URI of your app registered on the Azure Management Portal.
         static NSString *const aadClientId = @"0b18d05c-386d-4133-b481-az1234567890";
         static NSString *const aadRedirectUri = @"https://localhost/";
    
         // Set properties on the ODClient.
         NSArray *const msaScopes = [msaScopesString componentsSeparatedByString:@","];
         [ODClient setMicrosoftAccountAppId:msaClientId
                                     scopes:msaScopes];
    
         [ODClient setActiveDirectoryAppId:aadClientId
                                capability:@"Notes"
                               redirectURL:aadRedirectUri];
         return YES;
     }
    

    Notes

    Cette application vous permet de vous connecter avec un compte à la fois (compte Microsoft ou compte professionnel ou scolaire). Pour voir comment prendre en charge les deux types de comptes et stocker plusieurs comptes, voir l’exemple CloudRoll.

  3. Dans ViewController.h, importez le SDK OneDrive et déclarez une propriété pour l’objet ODClient. Tous les appels au SDK sont effectués via l’objet ODClient.

    a. Ajoutez l’instruction d’import :

      #import <OneDriveSDK/OneDriveSDK.h>
    

    b. Ajouter la propriété client au bloc de code @interface.

      @property (strong, nonatomic) ODClient *client;
    
  4. Dans ViewController.m, ajoutez le code suivant à la fin de la méthode viewDidLoad pour obtenir un ODClient authentifié.

    Le SDK appelle l’IU de connexion la première fois que l’utilisateur exécute l’application, puis stocke les informations de compte.

         [ODClient clientWithCompletion:^(ODClient *odClient, NSError *error) {
             if (!error){
                 self.client = odClient;
                 [self getSections];
             }
             else {
                 NSLog(@"Error with auth: %@", [error localizedDescription]);
             }
         }];
    

    Nous allons ajouter la méthode getSections dans la section suivante.

  5. Dans ViewController.m, ajoutez la méthode sendRequest au bloc de code @implementation.

    Cette méthode ajoute l’en-tête Authorization nécessaire aux requêtes des sections GET et des pages POST, et crée la tâche de transfert de données.

     // Send the request.
     - (void)sendRequest:(NSMutableURLRequest *)request {
    
         // Add the required Authorization header with access token.
         [self.client.authProvider appendAuthHeaders:request completion:^(NSMutableURLRequest *requests, NSError *error) {
    
             // This app also uses the OneDrive SDK to send HTTP requests.
             [[self.client.httpProvider dataTaskWithRequest:(request)
                     completionHandler:^(NSData *data,
                     NSURLResponse *response,
                     NSError *error) {
                         [self handleResponse:data response:response error:error];
             }] resume];
         }];
     }
    

Vous êtes maintenant prêt à passer des appels au service OneNote.

Appeler l’API OneNote

Lorsque l’application se charge, elle récupère le nom et l’ID des 10 dernières sections modifiées et remplit le sélecteur avec les noms des sections. La nouvelle page est créée dans la section sélectionnée.

  1. Dans ViewController.h, ajoutez les propriétés qui stockent la réponse.

    // Variables to store the response data.
    @property (strong, nonatomic) NSHTTPURLResponse *returnResponse;
    @property (strong, nonatomic) NSMutableData *returnData;
    

    Ajoutez tout le code dans les étapes suivantes au bloc de code @implementation dans ViewController.m. Ne vous inquiétez pas des erreurs que vous voyez lorsque vous créez l’application. Elles disparaîtront lorsque le code sera complet.

  2. Dans ViewController.m, ajoutez des variables pour l’URL racine du service OneNote, le dictionnaire pour les noms et les ID des sections, et un tableau pour les noms des sections qui rempliront le sélecteur.

    static NSString const *serviceRootUrl = @"https://www.onenote.com/api/v1.0/me/notes/";
    NSMutableDictionary *sectionNamesAndIds;
    NSArray *sectionNamesForPicker;
    
  3. Ajoutez la méthode getSections pour construire la requête des sections GET.

     // Build the "GET sections" request.
     - (void)getSections {
    
         // Construct the request URI and the request.
         NSString *sectionsEndpoint =
                 [serviceRootUrl stringByAppendingString:@"sections?select=name,id&top=10&orderby=lastModifiedTime%20desc"];
         NSMutableURLRequest *request =
                 [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:sectionsEndpoint]];
         request.HTTPMethod = @"GET";
         if (self.client)
         {
    
             // Send the HTTP request.
             [self sendRequest:request];
         }
         _createPageButton.enabled = false;
     }
    
  4. Ajouter la méthode handleResponse pour gérer la réponse des requêtes des sections GET et des pages POST demandes.

    // Handle the response.
    - (void)handleResponse:(NSData *)data response:(NSURLResponse *)response error:(NSError *) error {
    
        // Log the response.
        NSLog(@"Response %@ with error %@.\n", response, error);
        NSString *stringData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"Body: %@.\n", stringData);
    
        // Store the response.
        self.returnData = [[NSMutableData alloc] init];
        NSMutableData *convertedData = [data mutableCopy];
        [self.returnData appendData:convertedData];
        self.returnResponse = (NSHTTPURLResponse *)response;
    
        NSInteger status = [self.returnResponse statusCode];
    
        // Check for "GET sections" success.
        if (status == 200) {
            NSLog(@"Sections retrieved!\n");
    
            // Get the section data and populate the picker.
            [self getSectionNamesAndIds];
        }
    
        // Check for "POST pages" success.
        else if (status == 201) {
            NSLog(@"Page created!\n");
    
            // Get the page object and parse out some properties.
            NSDictionary *pageProperties = [self convertData];
            NSString *selfLink = [pageProperties objectForKey:@"self"];
            NSDictionary *links = [pageProperties objectForKey:@"links"];
            NSString *clientUrl = [[links objectForKey:@"oneNoteClientUrl"] objectForKey:@"href"];
            NSString *webUrl = [[links objectForKey:@"oneNoteWebUrl"] objectForKey:@"href"];
            NSLog(@"Link to new page endpoint: %@\n", selfLink);
            NSLog(@"Link open page in the installed client: %@\n", clientUrl);
            NSLog(@"Link to open page in OneNote Online: %@\n", webUrl);
        }
        else {
            NSLog(@"Status code: %ld. Check the logged response for more information.", (long)status);
        }
    }
    
  5. Ajoutez la méthode convertData pour convertir les données de réponse en JSON.

    // Get the OneNote entity data from the response.
    - (NSDictionary *)convertData {
    
        // Convert the message body to JSON.
        NSError *parseError;
        NSDictionary *data = [NSJSONSerialization JSONObjectWithData:self.returnData options:kNilOptions error:&parseError];
    
        if (!parseError) {
            return data;
        }
        else {
            NSLog(@"Error parsing response: %@", [parseError localizedDescription]);
            return nil;
        }
    }
    
  6. Ajoutez la méthode getSectionNamesAndIds pour stocker les noms et les ID de section et remplir le sélecteur.

    // Store the section names and IDs, and populate the section picker.
    - (void)getSectionNamesAndIds {
    
        // Get the "value" array that contains the returned sections.
        NSDictionary *results = [self convertData];
    
        // Add the name-id pairs to sectionNamesAndIds, which is used to map section names to IDs.
        if ([results objectForKey:@"value"] != nil) {
            NSDictionary *sections =[results objectForKey:@"value"];
            sectionNamesAndIds = [[NSMutableDictionary alloc] init];
            for (NSMutableDictionary *dict in sections) {
                NSString *sectionName = [dict objectForKey:@"name"];
                NSString *sectionId = [dict objectForKey:@"id"];
                sectionNamesAndIds[sectionName] = sectionId;
            }
        }
    
        // Populate the picker with the section names.
        sectionNamesForPicker = [sectionNamesAndIds allKeys];
        dispatch_async(dispatch_get_main_queue(), ^{[_sectionPicker reloadComponent:0];});
    
        _createPageButton.enabled = true;
    }
    
  7. Modifiez la méthode createPage qui a été créée pour vous lorsque vous avez ajouté l’action du bouton. Ce code crée une page HTML simple.

    // Create a simple page.
    - (IBAction)createPage:(id)sender {
    
        // Get the ID of the section that's selected in the picker.
        NSInteger row = [self.sectionPicker selectedRowInComponent:0];
        NSString *selectedSectionName = sectionNamesForPicker[row];
        NSString *selectedSectionId = sectionNamesAndIds[selectedSectionName];
    
        // Construct the request URI and the request.
        NSString *pagesEndpoint = [NSString stringWithFormat:@"sections/%@/pages", selectedSectionId];
        NSString *fullEndpoint = [serviceRootUrl stringByAppendingString:pagesEndpoint];
        NSString *date = [self formatDate];
        NSString *simpleHtml = [NSString stringWithFormat:@"<html>"
                                "<head>"
                                "<title>A page created from simple HTML from iOS</title>"
                                "<meta name=\"created\" content=\"%@\" />"
                                "</head>"
                                "<body>"
                                "<p>This is some <b>simple</b> <i>formatted</i> text.</p>"
                                "</body>"
                                "</html>", date];
    
        NSData *presentation = [simpleHtml dataUsingEncoding:NSUTF8StringEncoding];
        NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:fullEndpoint]];
        request.HTTPMethod = @"POST";
        request.HTTPBody = presentation;
        [request addValue:@"text/html" forHTTPHeaderField:@"Content-Type"];
        if (self.client)
        {
    
            // Send the HTTP request.
            [self sendRequest:request];
        }
    }
    
  8. Ajoutez la méthode formatDate pour obtenir une date au format ISO 8601 pour le timestamp de la balise meta.

    // Format the "created" date. OneNote requires the ISO 8601 format.
    - (NSString *)formatDate {
        NSDate *now = [NSDate date];
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        NSLocale *enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
        [dateFormatter setLocale:enUSPOSIXLocale];
        [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"];
        return [dateFormatter stringFromDate:now];
    }
    

Après avoir créé l’application, vous pouvez la tester en l’exécutant sur un iPhone ou un émulateur iPhone. Connectez-vous en utilisant votre compte Microsoft ou votre compte professionnel ou scolaire.

Lorsque l’application s’ouvre, choisissez la section dans laquelle vous souhaitez créer une page, puis choisissez Créer une page. Ensuite, vérifiez la Fenêtre Sortie dans Xcode pour les messages de journal. Si les appels fonctionnent, la Fenêtre Sortie affichera l’URI de ressource de la nouvelle page et les liens pour ouvrir la page dans OneNote.

Étapes suivantes

Ajoutez des fonctionnalités, la validation des entrées et la gestion des erreurs.

Par exemple, ajoutez un bouton de déconnexion qui appelle cette méthode :

- (IBAction)signOut:(UIButton *)sender  {
    [self.client signOutWithCompletion:^(NSError *signOutError) {
        self.client = nil;
        NSLog(@"Logged out.");
    }];
}

Voir les articles Développer avec l’API OneNote pour en savoir plus sur ce que vous pouvez faire avec l’API OneNote.

Exemples de code complet pour iOS

AppDelegate.m

#import "AppDelegate.h"
#import <OneDriveSDK/OneDriveSDK.h>

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Set the client ID and permission scopes of your app registered on the Microsoft account Developer Center.
    static NSString *const msaClientId = @"000000001A123456";
    static NSString *const msaScopesString = @"wl.signin,wl.offline_access,office.onenote_update";

    // Set the client ID and redirect URI of your app registered on the Azure Management Portal.
    static NSString *const aadClientId = @"0b18d05c-386d-4133-b481-az1234567890";
    static NSString *const aadRedirectUri = @"https://localhost/";

    // Set properties on the ODClient.
    NSArray *const msaScopes = [msaScopesString componentsSeparatedByString:@","];
    [ODClient setMicrosoftAccountAppId:msaClientId
                                scopes:msaScopes];

    [ODClient setActiveDirectoryAppId:aadClientId
                           capability:@"Notes"
                          redirectURL:aadRedirectUri];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

ViewController.h

#import <UIKit/UIKit.h>
#import <OneDriveSDK/OneDriveSDK.h>

@interface ViewController : UIViewController<UIPickerViewDelegate, UIPickerViewDataSource>

@property (strong, nonatomic) ODClient *client;

// Variables to store the response data.
@property (strong, nonatomic) NSHTTPURLResponse *returnResponse;
@property (strong, nonatomic) NSMutableData *returnData;

// Outlet connections for controls.
@property (weak, nonatomic) IBOutlet UIPickerView *sectionPicker;
@property (weak, nonatomic) IBOutlet UIButton *createPageButton;

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

static NSString const *serviceRootUrl = @"https://www.onenote.com/api/v1.0/me/notes/";
NSMutableDictionary *sectionNamesAndIds;
NSArray *sectionNamesForPicker;

- (void)viewDidLoad {
    [super viewDidLoad];

    self.sectionPicker.delegate = self;
    self.sectionPicker.dataSource = self;

    [ODClient clientWithCompletion:^(ODClient *odClient, NSError *error) {
        if (!error){
            self.client = odClient;
            [self getSections];
        }
        else {
            NSLog(@"Error with auth: %@", [error localizedDescription]);
        }
    }];
}

// Build the "GET sections" request.
- (void)getSections {

    // Construct the request URI and the request.
    NSString *sectionsEndpoint =
            [serviceRootUrl stringByAppendingString:@"sections?select=name,id&top=10&orderby=lastModifiedTime%20desc"];
    NSMutableURLRequest *request =
            [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:sectionsEndpoint]];
    request.HTTPMethod = @"GET";
    if (self.client)
    {

        // Send the HTTP request.
        [self sendRequest:request];
    }
    _createPageButton.enabled = false;
}

// Send the request.
- (void)sendRequest:(NSMutableURLRequest *)request {

    // Add the required Authorization header with access token.
    [self.client.authProvider appendAuthHeaders:request completion:^(NSMutableURLRequest *requests, NSError *error) {

        // This app also uses the OneDrive SDK to send HTTP requests.
        [[self.client.httpProvider dataTaskWithRequest:(request)
                completionHandler:^(NSData *data,
                NSURLResponse *response,
                NSError *error) {
                    [self handleResponse:data response:response error:error];
        }] resume];
    }];
}

// Store the section names and IDs, and populate the section picker.
- (void)getSectionNamesAndIds {

    // Get the "value" array that contains the returned sections.
    NSDictionary *results = [self convertData];

    // Add the name-id pairs to sectionNamesAndIds, which is used to map section names to IDs.
    if ([results objectForKey:@"value"] != nil) {
        NSDictionary *sections =[results objectForKey:@"value"];
        sectionNamesAndIds = [[NSMutableDictionary alloc] init];
        for (NSMutableDictionary *dict in sections) {
            NSString *sectionName = [dict objectForKey:@"name"];
            NSString *sectionId = [dict objectForKey:@"id"];
            sectionNamesAndIds[sectionName] = sectionId;
        }
    }

    // Populate the picker with the section names.
    sectionNamesForPicker = [sectionNamesAndIds allKeys];
    dispatch_async(dispatch_get_main_queue(), ^{[_sectionPicker reloadComponent:0];});

    _createPageButton.enabled = true;
}

// Get the OneNote entity data from the response.
- (NSDictionary *)convertData {

    // Convert the message body to JSON.
    NSError *parseError;
    NSDictionary *data = [NSJSONSerialization JSONObjectWithData:self.returnData options:kNilOptions error:&parseError];

    if (!parseError) {
        return data;
    }
    else {
        NSLog(@"Error parsing response: %@", [parseError localizedDescription]);
        return nil;
    }
}

// Handle the response.
- (void)handleResponse:(NSData *)data response:(NSURLResponse *)response error:(NSError *) error {

    // Log the response.
    NSLog(@"Response %@ with error %@.\n", response, error);
    NSString *stringData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"Body: %@.\n", stringData);

    // Store the response.
    self.returnData = [[NSMutableData alloc] init];
    NSMutableData *convertedData = [data mutableCopy];
    [self.returnData appendData:convertedData];
    self.returnResponse = (NSHTTPURLResponse *)response;

    NSInteger status = [self.returnResponse statusCode];

    // Check for "GET sections" success.
    if (status == 200) {
        NSLog(@"Sections retrieved!\n");

        // Get the section data and populate the picker.
        [self getSectionNamesAndIds];
    }

    // Check for "POST pages" success.
    else if (status == 201) {
        NSLog(@"Page created!\n");

        // Get the page object and parse out some properties.
        NSDictionary *pageProperties = [self convertData];
        NSString *selfLink = [pageProperties objectForKey:@"self"];
        NSDictionary *links = [pageProperties objectForKey:@"links"];
        NSString *clientUrl = [[links objectForKey:@"oneNoteClientUrl"] objectForKey:@"href"];
        NSString *webUrl = [[links objectForKey:@"oneNoteWebUrl"] objectForKey:@"href"];
        NSLog(@"Link to new page endpoint: %@\n", selfLink);
        NSLog(@"Link open page in the installed client: %@\n", clientUrl);
        NSLog(@"Link to open page in OneNote Online: %@\n", webUrl);
    }
    else {
        NSLog(@"Status code: %ld. Check the logged response for more information.", (long)status);
    }
}

// Create a simple page.
- (IBAction)createPage:(id)sender {

    // Get the ID of the section that's selected in the picker.
    NSInteger row = [self.sectionPicker selectedRowInComponent:0];
    NSString *selectedSectionName = sectionNamesForPicker[row];
    NSString *selectedSectionId = sectionNamesAndIds[selectedSectionName];

    // Construct the request URI and the request.
    NSString *pagesEndpoint = [NSString stringWithFormat:@"sections/%@/pages", selectedSectionId];
    NSString *fullEndpoint = [serviceRootUrl stringByAppendingString:pagesEndpoint];
    NSString *date = [self formatDate];
    NSString *simpleHtml = [NSString stringWithFormat:@"<html>"
                            "<head>"
                            "<title>A page created from simple HTML from iOS</title>"
                            "<meta name=\"created\" content=\"%@\" />"
                            "</head>"
                            "<body>"
                            "<p>This is some <b>simple</b> <i>formatted</i> text.</p>"
                            "</body>"
                            "</html>", date];

    NSData *presentation = [simpleHtml dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:fullEndpoint]];
    request.HTTPMethod = @"POST";
    request.HTTPBody = presentation;
    [request addValue:@"text/html" forHTTPHeaderField:@"Content-Type"];
    if (self.client)
    {

        // Send the HTTP request.
        [self sendRequest:request];
    }
}

// Format the "created" date. OneNote requires the ISO 8601 format.
- (NSString *)formatDate {
    NSDate *now = [NSDate date];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSLocale *enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    [dateFormatter setLocale:enUSPOSIXLocale];
    [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"];
    return [dateFormatter stringFromDate:now];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Delegate Methods
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 1;
}

-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return sectionNamesForPicker.count;
}

-(NSString *)pickerView:(UIPickerView*)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    return [sectionNamesForPicker objectAtIndex:row];
}
@end

Créer une application OneNote pour ASP.NET MVC

Cette application web utilise la Bibliothèque d’authentification Active Directory Azure (ADAL) pour .NET pour authentifier les comptes d’école et de travail de plusieurs clients.

Conditions préalables

Voici ce dont vous aurez besoin pour suivre ce tutoriel :

  • Visual Studio 2015. Vous pouvez utiliser la version gratuite Visual Studio Community.
  • Une application Web enregistrée sur le Portail de gestion Azure, avec les autorisations déléguées suivantes :
    • Se connecter et lire le profil utilisateur pour Windows Azure Active Directory
    • Afficher et modifier les blocs-notes OneNote pour OneNote

Notes

Visual Studio enregistre l’application web pour vous lors de la création de l’application, mais vous devrez quand même ajouter des autorisations pour OneNote et générer une clé d’application. (En savoir plus sur l’enregistrement d’application.)

Pour créer une application OneNote à l’aide d’ASP.NET MVC

  1. Créez le projet
  2. Ajoutez la bibliothèque ADAL pour .NET
  3. Construisez l’interface utilisateur
  4. Ajoutez un support d’authentification
  5. Appeler l’API OneNote

Des exemples de code complet pour les fichiers clés sont inclus à la fin du tutoriel.

Créer un projet dans Visual Studio

  1. Dans Visual Studio, créez un projet Application Web ASP.NET nommé OneNote-WebApp.

  2. Choisissez le modèle MVC et assurez-vous que MVC est sélectionné pour l’option Ajouter des dossiers et des références de base.

  3. Choisissez Modifier l’authentification, puis sélectionnezComptes d’école et de travail.

  4. Choisissez Cloud - Organisations multiples et entrez le nom de domaine de votre client développeur (par exemple, contoso.onmicrosoft.com).

Vous pouvez conserver ou effacer le réglage Microsoft Azure Héberger dans le cloud, selon votre choix. Ce n’est pas nécessaire pour ce tutoriel. Conservez tous les autres paramètres par défaut.

Visual Studio enregistre l’application Web avec Azure pour vous, mais vous devez terminer la configuration dans le Portail de gestion Azure.

  1. Dans votre répertoire client dans le portail, choisissez Applications puis cliquez sur l’application OneNote-Web pour ouvrir sa page de configuration.

  2. Dans la section Clés, choisissez une durée pour une nouvelle clé.

  3. Dans la section Autorisations pour d’autres applications, ajoutez l’application OneNote, puis ajoutez l’autorisation déléguée Afficher et modifier les blocs-notes OneNote. (en savoir plus)

  4. Enregistrez vos modifications dans l’application et effectuez une copie de la nouvelle clé avant de fermer le portail. Vous l’utiliserez bientôt.

Ajouter ADAL pour .NET

L’application utilise la Bibliothèque d’authentification Active Directory (ADAL) pour authentifier et autoriser Azure AD. L’application a été créée en utilisant la version 2.19.208020213.

  1. Dans Visual Studio, choisissez Outils> Gestionnaire de packages NuGet > Console du gestionnaire de packages et exécutez la commande suivante dans la console.

    Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory
    

Construisez l’interface utilisateur

Cette application utilise deux vues pour HomeController : Index.cshtml et Page.cshtml.

  1. Remplacez le contenu de Views/Home/Index.cshtml par le code suivant. Cela ajoute une liste déroulante pour sélectionner la section parent, une zone de texte pour entrer le nom de la page et un bouton.

    @model OneNote_WebApp.Models.SectionsViewModel
    
    @{
        ViewBag.Title = "Index";
    }
    
    <h2>OneNote ASP.NET MVC web application</h2>
    
    @Html.Label("Choose a section to create the page in.")
    
    @using (Html.BeginForm("CreatePageAsync", "Home", new AjaxOptions { UpdateTargetId = "create-page" }))
    {
        <div id="create-page">
            @Html.DropDownListFor(
                m => m.SectionId,
                new SelectList(Model.Sections, "Id", "Name", Model.SectionId))
            @Html.ValidationMessageFor(m => m.SectionId)
            <br />
            <br />
            <table>
                <tr>
                    <td>
                        @Html.Label("Enter a name for the new page.")
                        <br />
                        @Html.TextBox("page-name", null, new { @style = "width=80" })
                    </td>
                </tr>
            </table>
            <button>Create page</button>
        </div>
    }
    
  2. Dans le dossier Views/Home, créez une nouvelle vue nommée Page et ajoutez le code suivant. Cette vue affiche les propriétés de la page nouvellement créée.

    @model OneNote_WebApp.Models.PageViewModel
    
    @{
         ViewBag.Title = "Page";
    }
    
    <h2>Page: @Model.Title</h2>
    
    <table>
        <tr>
            <td>@Html.Label("Self link: ")</td>
            <td>@Model.Self</td>
        </tr>
        <tr>
            <td>@Html.Label("Native client link: ")</td>
            <td><a href="@Model.PageLinks.ClientUrl">@Model.PageLinks.ClientUrl</a></td>
        </tr>
        <tr>
            <td>@Html.Label("Web client link: ")</td>
            <td><a href="@Model.PageLinks.WebUrl">@Model.PageLinks.WebUrl</a></td>
        </tr>
    </table>
    

Ajoutez un support d’authentification

La bibliothèque client ADAL pour .NET gère le processus d’authentification et d’autorisation. Vous aurez seulement besoin de fournir des identifiants pour votre application et d’ajouter quelques appels.

  1. Dans le fichier racine Web.config, ajoutez les paires clé / valeur suivantes au nœud appSettings. Notez que ClientId et AADInstance ont déjà été ajoutés par Visual Studio.

    <add key="ida:AppKey" value="ENTER-your-app-key-here" />
    <add key="ida:OneNoteResourceId" value="https://onenote.com/" />
    
  2. Remplacez la valeur par défaut pour la clé d’application avec la clé que vous avez générée plus tôt.

  3. Dans App_Start/Start.Auth.cs, ajoutez l’instruction using suivante.

    using Microsoft.IdentityModel.Clients.ActiveDirectory;
    
  4. Remplacez les variables globales dans la classe Startup par le code suivant. La méthode GetAuthorizedClient dans HomeController utilise également les quatre variables publiques.

    public static string ClientId = ConfigurationManager.AppSettings["ida:ClientId"];
    public static string AppKey = ConfigurationManager.AppSettings["ida:AppKey"];
    public static string AADInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
    public static string OneNoteResourceId = ConfigurationManager.AppSettings["ida:OneNoteResourceId"];
    private string Authority = AADInstance + "common"; 
    
  5. Dans la méthode ConfigureAuth, remplacez la méthode app.UseOpenIdConnectAuthentication par le code suivant. ADAL stocke les jetons et autres informations dans le cache des jetons. (Pour voir ce qui est en cache, ajoutez cette ligne avant de renvoyer la tâche : var cache = context.TokenCache.ReadItems();)

    app.UseOpenIdConnectAuthentication(
       new OpenIdConnectAuthenticationOptions
       {
           ClientId = ClientId,
           Authority = Authority,
           TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
           {
               ValidateIssuer = false
           },
           Notifications = new OpenIdConnectAuthenticationNotifications()
           {
                AuthorizationCodeReceived = (context) =>
                {
                    var code = context.Code;
                    ClientCredential credential = new ClientCredential(ClientId, AppKey);
                    Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authContext =
                       new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(Authority);
                    AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                        code,
                        new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)),
                        credential,
                        OneNoteResourceId
                    );
                    return Task.FromResult(0);
                },
                AuthenticationFailed = (context) =>
                {
                    context.HandleResponse();
                    if (context.Exception.HResult == -2146233088) //IDX10311: Nonce is null
                    {
                        context.OwinContext.Response.Redirect("Home/Index");
                    }
                    return Task.FromResult(0);
                }
            }
        });
    
  6. Dans Controllers/HomeController.cs, ajoutez les instructionsd'utilisation suivantes.

    using Microsoft.IdentityModel.Clients.ActiveDirectory;
    using Microsoft.Owin.Security;
    using Microsoft.Owin.Security.OpenIdConnect;
    using Newtonsoft.Json;
    using System.IO;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Security.Claims;
    using System.Text;
    using System.Threading.Tasks;
    using OneNote_WebApp.Models;
    
  7. Dans la classe HomeController, ajoutez la méthode GetAuthorizedClient. Cette méthode crée et configure le HttpClient utilisé pour effectuer les requêtes REST au service OneNote. Elle récupère également le jeton d’accès et l’ajoute au client.

    private HttpClient GetAuthorizedClient()
    {
        HttpClient client = new HttpClient();
    
        string userObjectId = ClaimsPrincipal.Current.FindFirst("https://schemas.microsoft.com/identity/claims/objectidentifier").Value;
        string tenantId = ClaimsPrincipal.Current.FindFirst("https://schemas.microsoft.com/identity/claims/tenantid").Value;
        ClientCredential credential = new ClientCredential(Startup.ClientId, Startup.AppKey);
        AuthenticationContext authContext = new AuthenticationContext(Startup.AADInstance + tenantId);
    
        try
        {
            // Call AcquireTokenSilent to get the access token. This first tries to get the token from cache.
            AuthenticationResult authResult = authContext.AcquireTokenSilent(
                Startup.OneNoteResourceId,
                credential,
                new UserIdentifier(userObjectId, UserIdentifierType.UniqueId));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        }
        catch (AdalSilentTokenAcquisitionException)
        {
            HttpContext.GetOwinContext().Authentication.Challenge(
                new AuthenticationProperties() { RedirectUri = "/" },
                OpenIdConnectAuthenticationDefaults.AuthenticationType);
            return null;
        }
    
        return client;
    }
    

Vous êtes maintenant prêt à passer des appels au service OneNote et à analyser la réponse.

Appeler l’API OneNote

Lorsque l’application se charge, elle récupère le nom et l’ID des 10 dernières sections modifiées et remplit la liste déroulante avec les noms des sections. La nouvelle page OneNote est créée dans la section sélectionnée.

  1. Dans la classe HomeController, ajoutez des variables globales pour les points de terminaison OneNote et le chemin d’accès au fichier image à ajouter à la nouvelle page.

    public static string OneNoteRoot = "https://www.onenote.com/api/v1.0/me/notes/";
    public static string SectionsEndpoint = "sections?select=name,id&top=10&orderby=lastModifiedTime%20desc";
    public static string PagesEndpoint = "sections/{0}/pages";
    public static string PathToImageFile = @"C:\<local-path>\logo.png";
    
  2. Modifiez les valeurs par défaut de chemin d'accès et de nom de fichier dans la variable PathToImageFile pour pointer vers une image PNG locale.

  3. Remplacez la méthode Index par le code suivant. Cela récupère les sections, prépare SectionsViewModel pour la vue Index et charge la vue.

    public async Task<ActionResult> Index()
    {
        SectionsViewModel viewModel = new SectionsViewModel();
        try
        {
            viewModel.Sections = await GetSectionsAsync();
        }
        catch (Exception ex)
        {
            return View("Error", new HandleErrorInfo(new Exception(ex.Message), "Home", "GetSectionsAsync"));
        }
        return View(viewModel);
    }
    
  4. Ajoutez la méthode GetSectionsAsync pour construire et envoyer la requête des sections GET et pour analyser la réponse.

    [Authorize]
    [HttpGet]   
    public async Task<IEnumerable<Section>> GetSectionsAsync()
    {
        List<Section> sections = new List<Section>();
    
        HttpClient client = GetAuthorizedClient();
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, OneNoteRoot + SectionsEndpoint);
        HttpResponseMessage response = await client.SendAsync(request);
        if (response.IsSuccessStatusCode)
        {
    
            // Parse the JSON response.
            string stringResult = await response.Content.ReadAsStringAsync();
            Dictionary<string, dynamic> result = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(stringResult);
            foreach (var item in result["value"])
            {
                var current = item.ToObject<Dictionary<string, string>>();
                Section section = new Section
                {
                    Name = current["name"],
                    Id = current["id"]
                };
                sections.Add(section);
            }
        }
        else
        {
            throw new Exception("Error getting sections: " + response.StatusCode.ToString());
        }
        return sections;
    }
    
  5. Ajoutez la méthode CreatePageAsync pour construire et envoyer la requête multiple despages POST et pour analyser la réponse. Cette requête crée une page HTML simple.

    [Authorize]
    [HttpPost]
    public async Task<ActionResult> CreatePageAsync()
    {
        HttpClient client = GetAuthorizedClient();
    
        // Get user input.
        string selectedSectionId = Request.Form["SectionId"];
        string pageName = Request.Form["page-name"];
        string pagesEndpoint = string.Format("sections/{0}/pages", selectedSectionId);
    
        // Define the page content, which includes an uploaded image.
        const string imagePartName = "imageBlock1";
        string iso8601Date = DateTime.Now.ToString("o");
        string pageHtml = "<html>" +
                          "<head>" +
                          "<title>" + pageName + "</title>" +
                          "<meta name=\"created\" content=\"" + iso8601Date + "\" />" +
                          "</head>" +
                          "<body>" +
                          "<h1>This is a page with an image</h1>" +
                          "<img src=\"name:" + imagePartName +
                          "\" alt=\"No mis monos\" width=\"250\" height=\"200\" />" +
                          "</body>" +
                          "</html>";
    
        HttpResponseMessage response;
    
        // Build the 'POST pages' request.
        var stream = new FileStream(PathToImageFile, FileMode.Open);
        using (var imageContent = new StreamContent(stream))
        {
            try
            {
                imageContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
                MultipartFormDataContent pageContent = new MultipartFormDataContent
                {
                    {new StringContent(pageHtml, Encoding.UTF8, "text/html"), "Presentation"},
                    {imageContent, imagePartName}
                };
    
                response = await client.PostAsync(OneNoteRoot + pagesEndpoint, pageContent);
                if (!response.IsSuccessStatusCode)
                {
                    throw new Exception(response.StatusCode + ": " + response.ReasonPhrase);
                }
                else
                {
    
                    // Parse the JSON response.
                    string stringResult = await response.Content.ReadAsStringAsync();
                    Dictionary<string, dynamic> pageData = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(stringResult);
                    Dictionary<string, dynamic> linksData = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(pageData["links"].ToString());
                    Links pageLinks = new Links
                    {
                        ClientUrl = new Uri(linksData["oneNoteClientUrl"]["href"].ToString()),
                        WebUrl = new Uri(linksData["oneNoteWebUrl"]["href"].ToString())
                    };
                    PageViewModel pageViewModel = new PageViewModel
                    {
                        Title = pageData["title"],
                        Self = new Uri(pageData["self"]),
                        PageLinks = pageLinks
                    };
                    return View("../home/page", pageViewModel);
                }
            }
            catch (Exception ex)
            {
                return View("Error", new HandleErrorInfo(new Exception(ex.Message), "Home", "CreatePageAsync"));
            }
        }
    }
    
  6. Dans le dossier Modèles, ajoutez une nouvelle classe nommée Resource.cs et utilisez le code suivant. Ceci définit les modèles de domaine qui représentent les sections et les pages OneNote, et les modèles de vue qui représentent les données OneNote dans les vues Index et Page.

    using System;
    using System.Collections.Generic;
    using System.IO;
    
    namespace OneNote_WebApp.Models
    {
    
        // Common properties of OneNote entities.
        public class Resource
        {
            public string Id { get; set; }
            public string CreatedBy { get; set; }
            public DateTimeOffset CreatedTime { get; set; }
            public string LastModifiedBy { get; set; }
            public DateTimeOffset LastModifiedTime { get; set; }
            public Uri Self { get; set; }
        }
    
        // A OneNote section with some key properties. 
        public class Section : Resource
        {
            public bool IsDefault { get; set; }
            public string Name { get; set; }
            public ICollection<Page> Pages { get; set; }
            public Uri PagesUrl { get; set; }
        }
    
        // A OneNote page with some key properties.
        // This app doesn't use the Page model.
        public class Page : Resource
        {
            public Stream Content { get; set; }
            public Uri ContentUrl { get; set; }
            public Links PageLinks { get; set; }
            public string Title { get; set; }
        }
    
        // The links that open a OneNote page in the installed client or in OneNote Online.
        public class Links
        {
            public Uri ClientUrl { get; set; }
            public Uri WebUrl { get; set; }
        }
    
        // The view model used to populate the section drop-down list.
        public class SectionsViewModel
        {
            public string SectionId { get; set; }
            public IEnumerable<Section> Sections { get; set; }
        }
    
        // The view model used to display properties of the new page.
        public class PageViewModel
        {
            public string Title { get; set; }
            public Uri Self { get; set; }
            public Links PageLinks { get; set; }
        }
    }
    

Après avoir créé l’application, vous pouvez l’exécuter avec le débogage F5.

Si vous obtenez une erreur No assembly found containing an OwinStartupAttribute..., ajoutez l’attribut suivant après les instructions using dans la classe Startup.cs dans le répertoire racine. (En savoir plus sur cette erreur.)

[assembly: OwinStartup(typeof(OneNote_WebApp.Startup))]

Connectez-vous à l’application à l’aide d’un compte professionnel ou scolaire ayant au moins un bloc-notes contenant au moins une section. Dans l’application, sélectionnez la section dans laquelle vous souhaitez créer une page, entrez un nom pour la nouvelle page, puis choisissez Créer une page. En cas de succès, l’application affiche le titre et le self, ainsi que les liens de page de la nouvelle page.

Exemples de code complet pour ASP.NET MVC

Startup.Auth.cs

using System;
using System.Configuration;
using System.Threading.Tasks;
using System.Web;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using Microsoft.IdentityModel.Clients.ActiveDirectory;

namespace OneNote_WebApp
{
    public partial class Startup
    {

        // Properties used for authorization.
        public static string ClientId = ConfigurationManager.AppSettings["ida:ClientId"];
        public static string AppKey = ConfigurationManager.AppSettings["ida:AppKey"];
        public static string AADInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
        public static string OneNoteResourceId = ConfigurationManager.AppSettings["ida:OneNoteResourceId"];
        private string Authority = AADInstance + "common";

        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions { });

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = ClientId,
                    Authority = Authority,
                    TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                    {
                        ValidateIssuer = false
                    },
                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        AuthorizationCodeReceived = (context) =>
                        {
                            var code = context.Code;
                            ClientCredential credential = new ClientCredential(ClientId, AppKey);
                            Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authContext =
                                new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(Authority);
                            AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                                code,
                                new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)),
                                credential,
                                OneNoteResourceId
                            );
                            return Task.FromResult(0);
                        },
                        AuthenticationFailed = (context) =>
                        {
                            context.HandleResponse();
                            if (context.Exception.HResult == -2146233088) //IDX10311: Nonce is null
                            {
                                context.OwinContext.Response.Redirect("Home/Index");
                            }
                            return Task.FromResult(0);
                        }
                    }
                });
        }
    }
}

HomeController

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OpenIdConnect;
using Newtonsoft.Json;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using OneNote_WebApp.Models;

namespace OneNote_WebApp.Controllers
{
    [Authorize]
    public class HomeController : Controller
    {

        // Route segments to OneNote resource endpoints.
        public static string OneNoteRoot = "https://www.onenote.com/api/v1.0/me/notes/";
        public static string SectionsEndpoint = "sections?select=name,id&top=10&orderby=lastModifiedTime%20desc";
        public static string PagesEndpoint = "sections/{0}/pages";

        // Path to the image file to add to the page. 
        // Change this to point to a local PNG file before running the app.
        public static string PathToImageFile = @"C:\<local-path>\logo.png";

        // Get sections, add them to SectionsViewModel, and load the view. 
        public async Task<ActionResult> Index()
        {
            SectionsViewModel viewModel = new SectionsViewModel();
            try
            {
                viewModel.Sections = await GetSectionsAsync();
            }
            catch (Exception ex)
            {
                return View("Error", new HandleErrorInfo(new Exception(ex.Message), "Home", "GetSectionsAsync"));
            }
            return View(viewModel);
        }

        // Create and configure the HttpClient used for requests to the OneNote API. 
        private HttpClient GetAuthorizedClient()
        {
            HttpClient client = new HttpClient();

            string userObjectId = ClaimsPrincipal.Current.FindFirst("https://schemas.microsoft.com/identity/claims/objectidentifier").Value;
            string tenantId = ClaimsPrincipal.Current.FindFirst("https://schemas.microsoft.com/identity/claims/tenantid").Value;
            ClientCredential credential = new ClientCredential(Startup.ClientId, Startup.AppKey);
            AuthenticationContext authContext = new AuthenticationContext(Startup.AADInstance + tenantId);

            try
            {
                // Call AcquireTokenSilent to get the access token. This first tries to get the token from cache.
                AuthenticationResult authResult = authContext.AcquireTokenSilent(
                    Startup.OneNoteResourceId,
                    credential,
                    new UserIdentifier(userObjectId, UserIdentifierType.UniqueId));
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            }
            catch (AdalSilentTokenAcquisitionException)
            {
                HttpContext.GetOwinContext().Authentication.Challenge(
                    new AuthenticationProperties() { RedirectUri = "/" },
                    OpenIdConnectAuthenticationDefaults.AuthenticationType);
                return null;
            }
            return client;
        }

        [Authorize]
        [HttpGet]
        // Build the 'GET sections' request and parse the response. The request gets the 10 most recently modified sections.
        public async Task<IEnumerable<Section>> GetSectionsAsync()
        {
            List<Section> sections = new List<Section>();

            HttpClient client = GetAuthorizedClient();
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, OneNoteRoot + SectionsEndpoint);
            HttpResponseMessage response = await client.SendAsync(request);
            if (response.IsSuccessStatusCode)
            {

                // Parse the JSON response.
                string stringResult = await response.Content.ReadAsStringAsync();
                Dictionary<string, dynamic> result = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(stringResult);
                foreach (var item in result["value"])
                {
                    var current = item.ToObject<Dictionary<string, string>>();
                    Section section = new Section
                    {
                        Name = current["name"],
                        Id = current["id"]
                    };
                    sections.Add(section);
                }
            }
            else
            {
                throw new Exception("Error getting sections: " + response.StatusCode.ToString());
            }
            return sections;
        }

        [Authorize]
        [HttpPost]
        // Build the multipart POST request and parse the response. The request creates a page in the selected section.
        public async Task<ActionResult> CreatePageAsync()
        {
            HttpClient client = GetAuthorizedClient();

            // Get user input.
            string selectedSectionId = Request.Form["SectionId"];
            string pageName = Request.Form["page-name"];
            string pagesEndpoint = string.Format("sections/{0}/pages", selectedSectionId);

            // Define the page content, which includes an uploaded image.
            const string imagePartName = "imageBlock1";
            string iso8601Date = DateTime.Now.ToString("o");
            string pageHtml = "<html>" +
                                "<head>" +
                                "<title>" + pageName + "</title>" +
                                "<meta name=\"created\" content=\"" + iso8601Date + "\" />" +
                                "</head>" +
                                "<body>" +
                                "<h1>This is a page with an image</h1>" +
                                "<img src=\"name:" + imagePartName +
                                "\" alt=\"No mis monos\" width=\"250\" height=\"200\" />" +
                                "</body>" +
                                "</html>";

            HttpResponseMessage response;

            // Build the 'POST pages' request.
            var stream = new FileStream(PathToImageFile, FileMode.Open);
            using (var imageContent = new StreamContent(stream))
            {
                try
                {
                    imageContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
                    MultipartFormDataContent pageContent = new MultipartFormDataContent
                    {
                        {new StringContent(pageHtml, Encoding.UTF8, "text/html"), "Presentation"},
                        {imageContent, imagePartName}
                    };

                    response = await client.PostAsync(OneNoteRoot + pagesEndpoint, pageContent);
                    if (!response.IsSuccessStatusCode)
                    {
                        throw new Exception(response.StatusCode + ": " + response.ReasonPhrase);
                    }
                    else
                    {

                        // Parse the JSON response.
                        string stringResult = await response.Content.ReadAsStringAsync();
                        Dictionary<string, dynamic> pageData = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(stringResult);
                        Dictionary<string, dynamic> linksData = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(pageData["links"].ToString());
                        Links pageLinks = new Links
                        {
                            ClientUrl = new Uri(linksData["oneNoteClientUrl"]["href"].ToString()),
                            WebUrl = new Uri(linksData["oneNoteWebUrl"]["href"].ToString())
                        };
                        PageViewModel pageViewModel = new PageViewModel
                        {
                            Title = pageData["title"],
                            Self = new Uri(pageData["self"]),
                            PageLinks = pageLinks
                        };
                        return View("../home/page", pageViewModel);
                    }
                }
                catch (Exception ex)
                {
                    return View("Error", new HandleErrorInfo(new Exception(ex.Message), "Home", "CreatePageAsync"));
                }
            }
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}

Index.cshtml, Page.cshtml et Resource.cs sont montrés dans leur intégralité dans les instructions.

Voir aussi