Tutorial: creación de una aplicación de OneNote

Se aplica a: Blocs de notas para consumidores de OneDrive | Blocs de notas empresariales de Office 365

Este tutorial le muestra cómo crear una aplicación simple que utiliza la API de OneNote para obtener y crear contenido de OneNote. La aplicación que crearemos realiza dos llamadas utilizando la API REST de OneNote:

  • Obtenga el nombre e id. de las 10 secciones modificadas más recientemente.

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

  • Cree una página en una sección específica.

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

Elija su plataforma:

Nota

Este tutorial tiene como objetivo demostrar cómo acceder a la API de OneNote, pero no contiene código listo para la producción. Al crear su aplicación, revise cuidadosamente su código en busca de posibles problemas de seguridad, validación y otros problemas de calidad del código.

Crear una aplicación de OneNote para iOS

La aplicación usa el OneDrive SDK para iOS para manejar la autenticación y las llamadas de red.

Requisitos previos

Esto es lo que necesitará para seguir este tutorial:

Para crear una aplicación de OneNote para iOS

  1. Crear el proyecto
  2. Agregue la dependencia de OneDrive SDK
  3. Construya la interfaz de usuario
  4. Añada soporte de autenticación
  5. Llamar a la API de OneNote

Ejemplos de código completo para los archivos de muestra clave se incluyen al final del tutorial.

Crear el proyecto en Xcode

  1. En Xcode, cree un proyecto de Aplicación de vista única para iOS llamado AOneNote-iOS-App. Escoja Objective-C, y elija dispositivos iPhone.

  2. Después de crearse el proyecto, cierre Xcode. Abrirá el área de trabajo después de crear un Podfile.

Agregar la dependencia de OneDrive SDK

La aplicación en este tutorial usa la SDK de OneDrive para ambas cuentas de Microsoft (anteriormente Live Connect) y la autenticación de Azure Active Directory. La autenticación de cuenta Microsoft se usa para acceder a blocs de notas de consumidor en OneDrive. La autenticación de Azure AD se usa para acceder a blocs de notas de empresa en Office 365.

  1. Ejecute estos comandos en Terminal para crear un Podfile y abra el archivo en Xcode.

    cd {path to the OneNote-iOS-App project directory} 
    touch podfile 
    open -a xcode podfile 
    
  2. Agregue la dependencia del SDK de OneDrive al Podfile y luego guarde el archivo.

    pod 'OneDriveSDK'
    
  3. Ejecute estos comandos en Terminal para instalar la dependencia y abra el área de trabajo del proyecto en Xcode. Debería recibir confirmación cuando se complete la instalación.

    pod install
    open onenote-ios-app.xcworkspace/
    

Aplicaciones de Xcode 7 dirigidas a iOS 9.0

Si su objetivo es iOS 9 con Xcode 7, debe habilitar las excepciones PFS. Consulte la sección Seguridad de transporte de aplicaciones de iOS 9 en el léame del SDK de OneDrive para iOS para obtener instrucciones.

Construir la interfaz de usuario

Agregue un selector que muestre las 10 secciones modificadas más recientemente del usuario y un botón que cree una página de OneNote en la sección seleccionada.

  1. En Xcode, abra Main.storyboard y cambie el control de clase de tamaño (debajo del lienzo) a wCompact/hAny.

  2. Arrastre una vista de selector y un botón de la Biblioteca de objetos al lienzo. Utilice Crear página para el texto del botón.

  3. Crear conexiones para la vista del selector:
    a. Arrastre con la tecla control la vista de selector al icono de Controlador de vista arriba del lienzo. Elija la salida dataSource.
    b. Repita para la salida delegate.
    c. Elija Ver> Editor de asistente > Mostrar asistente de editor y abra ViewController.h en la segunda ventana.
    d. Arrastre con la tecla control la vista de selector en el lienzo en el bloque de código @interface. Inserte una conexión de Salida llamada sectionPicker.

  4. Crear conexiones para el botón:
    a. Arrastre con la tecla control el botón en el lienzo en el bloque de código @interface. Inserte una conexión de Salida llamada createPageButton.
    b. Abra ViewController.m en el editor de asistente.
    c. Arrastre con la tecla control el botón en el lienzo en el bloque de código @implementation. Insertar una conexión de Acción llamada createPage para el evento Touch Up Inside.

  5. Declare los protocolos UIPickerViewDelegate y UIPickerViewDataSource.

    ViewController.h debería verse así:

     import <UIKit/UIKit.h>
    
     @interface ViewController : UIViewController<UIPickerViewDelegate, UIPickerViewDataSource>
    
     @property (weak, nonatomic) IBOutlet UIPickerView *sectionPicker;
     @property (weak, nonatomic) IBOutlet UIButton *createPageButton;
    
     @end
    
  6. En ViewController.m, agregue los siguientes métodos de delegación para la vista del selector.

     #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];
    }
    

    No se preocupe por los errores de sectionNamesForPicker. Agregaremos la variable más tarde.

  7. En el métodoviewDidLoad, agregue el siguiente código para conectar el selector después de la línea [super viewDidLoad].

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

Agregar soporte de autenticación

El SDK de OneDrive maneja la autenticación y la autorización por usted. Simplemente deberá proporcionar identificadores para su aplicación y luego usar el ODClient. El SDK invoca la IU de inicio de sesión la primera vez que el usuario ejecuta la aplicación y luego almacena la información de la cuenta. (Más información acerca de autorización en el SDK).

  1. En AppDelegate.m, importe el SDK de OneDrive.

     #import <OneDriveSDK/OneDriveSDK.h>
    
  2. Reemplace el método didFinishLaunchingWithOptions con el siguiente código.

    Luego, reemplace los valores de propiedad del marcador de posición con la información de su(s) aplicación(es) registrada(s). Si solo está probando con una aplicación, puede convertir en comentario las propiedades que no esté utilizando.

      (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;
     }
    

    Nota

    Esta aplicación le permite iniciar sesión con una cuenta a la vez (cuenta de Microsoft o cuenta profesional o educativa). Para ver cómo admitir ambos tipos de cuentas y almacenar varias cuentas, consulte la muestra CloudRoll.

  3. En ViewController.h, importe el SDK de OneDrive y declare una propiedad para el objeto ODClient. Todas las llamadas al SDK se realizan a través del objeto ODClient.

    a. Agregue la declaración de importación:

      #import <OneDriveSDK/OneDriveSDK.h>
    

    b. Añada la propiedad client al bloque de código @interface.

      @property (strong, nonatomic) ODClient *client;
    
  4. En ViewController.m, agregue el siguiente código al final del método viewDidLoad para obtener un ODClient autenticado.

    El SDK invoca la IU de inicio de sesión la primera vez que el usuario ejecuta la aplicación y luego almacena la información de la cuenta.

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

    Añadiremos el método getSections en la siguiente sección.

  5. En ViewController.m, agregue el método sendRequest al bloque de código @implementation.

    Este método agrega el encabezado requerido Autorización a las secciones GET y las solicitudes de páginas POST, y crea la tarea de transferencia de datos.

     // 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];
         }];
     }
    

Ahora está listo para hacer llamadas al servicio de OneNote.

Llamar a la API de OneNote

Cuando se carga la aplicación, obtiene el nombre y el id. de las 10 secciones modificadas más recientemente y rellena el selector con los nombres de las secciones. La nueva página se crea en la sección seleccionada.

  1. En ViewController.h, agregue propiedades que almacenen la respuesta.

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

    Agregue todo el código en los siguientes pasos al bloque de código @implementation en ViewController.m. No se preocupe por los errores que verá mientras crea la aplicación. Desaparecerán después de que se complete el código.

  2. En ViewController.m, agregue variables para la URL raíz del servicio de OneNote, el diccionario para los nombres de las secciones y los id., y una matriz para los nombres de las secciones que poblarán el selector.

    static NSString const *serviceRootUrl = @"https://www.onenote.com/api/v1.0/me/notes/";
    NSMutableDictionary *sectionNamesAndIds;
    NSArray *sectionNamesForPicker;
    
  3. Agregue el método getSections para crear la solicitud de secciones 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. Agregue el método handleResponse para manejar la respuesta de las secciones GET y solicitudes de páginas POST.

    // 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. Agregue el método ConvertData para convertir los datos de respuesta a 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. Agregue el método getSectionNamesAndIds para almacenar los nombres de las secciones y los id. y rellenar el selector.

    // 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. Edite el método createPage que se creó para usted cuando agregó la acción del botón. Este código crea una página 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. Agregue el método formatDate para obtener una fecha de formato ISO 8601 para la marca de hora de la etiqueta 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];
    }
    

Después de crear la aplicación, puede probarla ejecutándola en un emulador de iPhone o en un iPhone. Inicie sesión con su cuenta de Microsoft o cuenta profesional o educativa.

Cuando se abra la aplicación, elija la sección donde desea crear una página y luego elija Crear página. Luego verifique la ventana de salida en Xcode en busca de los mensajes de registro. Si las llamadas funcionan, la ventana de salida mostrará el URI de recursos de la nueva página y los vínculos para abrir la página en OneNote.

Siguientes pasos

Agregue funcionalidad, validación de entrada y control de errores.

Por ejemplo, agregue un botón de cerrar sesión que llame a este método:

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

Consulte los artículos Desarrollar con la API de OneNote para saber más sobre lo que puede hacer con la API de OneNote.

Ejemplos de código completo para 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

Crear una aplicación de OneNote para ASP.NET MVC

Esta aplicación web utiliza Biblioteca de autenticación de Active Directory Azure (ADAL) para .NET para autenticar cuentas profesionales y educativas de varios inquilinos.

Requisitos previos

Esto es lo que necesitará para seguir este tutorial:

  • Visual Studio 2015. Puede usar la edición gratuita de Visual Studio Community.
  • Una aplicación web registrada en el Portal de administración de Azure, con los siguientes permisos delegados:
    • Iniciar sesión y leer el perfil del usuario para Windows Azure Active Directory
    • Ver y modificar bloc de notas de OneNote para OneNote

Nota

Visual Studio registra la aplicación web por usted durante la creación de la aplicación, pero aún necesitará agregar permisos para OneNote y generar una clave de aplicación. (Más información acerca del registro de la aplicación).

Para crear una aplicación de OneNote con ASP.NET MVC

  1. Crear el proyecto
  2. Agregar el ADAL para la biblioteca .NET
  3. Construir la interfaz de usuario
  4. Añada soporte de autenticación
  5. Llamar a la API de OneNote

Ejemplos de código completo para los archivos de muestra clave se incluyen al final del tutorial.

Crear el proyecto en Visual Studio

  1. En Visual Studio, cree un proyecto de Aplicación web ASP.NET llamado OneNote-WebApp.

  2. Elija la plantilla MVC y asegúrese de que MVC está seleccionado en la opción Agregar carpetas y referencias principales.

  3. Elija Cambiar autenticación y luego elija Cuentas profesional y educativa.

  4. Elija Nube: múltiples organizaciones y escriba el nombre de dominio de su cuenta empresarial de desarrollador (por ejemplo, contoso.onmicrosoft.com)

Puede mantener o borrar la configuración del Host en la nube de Microsoft Azure, según se desee. No es necesario para este tutorial. Mantenga todas las demás configuraciones predeterminadas.

Visual Studio registra la aplicación web en Azure por usted, pero debe terminar de configurarla en el Portal de administración de Azure.

  1. En su directorio de cuentas empresariales en el portal, elija Aplicaciones y luego haga clic en la aplicación OneNote-Web para abrir su página de configuración.

  2. En la sección Claves, elija una duración para una nueva clave.

  3. En la sección Permisos a otras aplicaciones, agregue la aplicación OneNote y luego agregue el permiso delegado Ver y modificar bloc de notas de OneNote. (más información)

  4. Guarde los cambios en la aplicación y haga una copia de la nueva clave antes de cerrar el portal. La usará pronto.

Agregar ADAL para .NET

La aplicación usa la Biblioteca de autenticación de Active Directory (ADAL) para autenticar y autorizar a Azure AD. La aplicación fue creada usando la versión 2.19.208020213.

  1. En Visual Studio, elija Herramientas> Administrador de paquetes NuGet> Consola de administrador de paquetes y ejecute el siguiente comando en la consola.

    Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory
    

Construir la interfaz de usuario

Esta aplicación utiliza dos vistas para HomeController: Index.cshtml y Page.cshtml.

  1. Reemplace el contenido de Vistas/Inicio/Index.cshtml con el siguiente código. Esto agrega una lista desplegable para seleccionar la sección primaria, un cuadro de texto para introducir el nombre de la página y un botón.

    @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. En la carpeta Vistas/Inicio, cree una nueva vista llamada Página y agrege el siguiente código. Esta vista muestra las propiedades de la página recién creada.

    @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>
    

Agregar soporte de autenticación

La biblioteca de cliente ADAL para .NET maneja el proceso de autenticación y autorización. Solo deberá proporcionar identificadores para su aplicación y agregar un par de llamadas.

  1. En el archivo raíz Web.config, agregue los siguientes pares de clave/valor al nodo appSettings. Observe que ClientId y AADInstance ya han sido agregados por Visual Studio.

    <add key="ida:AppKey" value="ENTER-your-app-key-here" />
    <add key="ida:OneNoteResourceId" value="https://onenote.com/" />
    
  2. Reemplace el valor del marcador de posición para la clave de la aplicación con la clave que generó anteriormente.

  3. En Aplicación_Inicio/Start.Auth.cs, agregue la siguiente declaración using.

    using Microsoft.IdentityModel.Clients.ActiveDirectory;
    
  4. Reemplace las variables globales en la clase Startup con el siguiente código. El método GetAuthorizedClient en HomeController también usa las cuatro variables públicas.

    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. En el método ConfigureAuth, reemplace el método app.UseOpenIdConnectAuthentication con el siguiente código. ADAL almacena tokens y otra información en el caché de tokens. (Para ver lo que se almacena en la memoria caché, agregue esta línea antes de devolver la tarea: 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. En Controladores/HomeController.cs, agregue las siguientes declaraciones using.

    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. En la clase HomeController, agregue el método GetAuthorizedClient. Este método crea y configura el HttpClient utilizado para realizar las solicitudes REST al servicio de OneNote. También obtiene el token de acceso y lo agrega al cliente.

    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;
    }
    

Ahora está listo para hacer llamadas al servicio de OneNote y redistribuir la respuesta.

Llamar a la API de OneNote

Cuando se carga la aplicación, obtiene el nombre y el id. de las 10 secciones modificadas más recientemente y rellena la lista desplegable con los nombres de las secciones. La nueva página de OneNote se crea en la sección seleccionada.

  1. En la clase HomeController, agregue variables globales para los extremos de OneNote y la ruta al archivo de imagen para agregar a la nueva página.

    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. Cambie la ruta del marcador de posición y el nombre de archivo en la variable PathToImageFile para apuntar a una imagen PNG local.

  3. Reemplace el método Index con el siguiente código. Esto obtiene las secciones, prepara SectionsViewModel para la Vista de índice, y carga la vista.

    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. Agregue el método GetSectionsAsync para crear y enviar la solicitud de secciones GET y redistribuir la respuesta.

    [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. Agregue el método CreatePageAsync para crear y enviar la solicitud multiparte de Páginas POST y redistribuir la respuesta. Esta solicitud crea una página 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. En la carpeta Modelos, agregue una nueva clase llamada Resource.cs y use el siguiente código. Esto define los modelos de dominio que representan secciones y páginas de OneNote, y los modelos de vista que representan datos de OneNote en las vistas Índice y Página.

    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; }
        }
    }
    

Después de crear la aplicación, puede ejecutarla con la depuración F5.

Si obtiene un error No se encontró ningún ensamblado que contenga un OwinStartupAttribute..., agregue el siguiente atributo después de las declaraciones using en la clase Startup.cs en el directorio raíz. (Más información acerca de este error).

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

Inicie sesión en la aplicación utilizando una cuenta profesional o educativa que tenga al menos un bloc de notas que contenga al menos una sección. En la aplicación, elija la sección donde desea crear una página, escriba un nombre para la nueva página y luego elija Crear página. Si tiene éxito, la aplicación muestra el título y la misma, y vínculos de página de la nueva página.

Ejemplos de código completo para 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.cshtmly Resource.cs se muestran en su totalidad en las instrucciones.

Vea también