Tutorial: Usar servicios de aplicaciones cliente

En este tema se describe cómo crear una aplicación para Windows que use servicios de aplicaciones cliente para autenticar usuarios y recuperar funciones y ajustes de usuario.

En este tutorial realizará las siguientes tareas:

  • Crear una aplicación de formularios Windows Forms y utilizar el diseñador de proyectos de Visual Studio para habilitar y configurar servicios de aplicaciones cliente.

  • Crear una aplicación de servicio Web ASP.NET simple para hospedar los servicios de aplicaciones y probar la configuración de cliente.

  • Agregar la autenticación de formularios a la aplicación. Empezará utilizando un nombre de usuario y una contraseña codificados de forma rígida para probar el servicio. A continuación, agregará un formulario de inicio de sesión especificándolo como un proveedor de credenciales en la configuración de la aplicación.

  • Agregar funcionalidad basada en la función, habilitando y mostrando un botón sólo para los usuarios que tengan la función de "administrador".

  • Tener acceso a la configuración web. Empezará cargando la configuración web de un usuario autenticado (de prueba) en la página Configuración del diseñador de proyectos. A continuación, utilizará el Diseñador de Windows Forms para enlazar un cuadro de texto a una configuración web. Finalmente, volverá a guardar el valor modificado en el servidor.

  • Implementar el cierre de sesión. Agregará una opción de cierre de sesión al formulario y llamará a un método de cierre de sesión.

  • Habilitar el modo sin conexión. Proporcionará una casilla para que los usuarios puedan especificar su estado de conexión. A continuación, utilizará este valor para especificar si los proveedores de servicios de aplicaciones cliente utilizarán los datos almacenados en caché localmente en lugar de tener acceso a sus servicios Web. Finalmente, volverá a autenticar al usuario actual cuando la aplicación regrese al modo en línea.

Requisitos previos

Necesita el siguiente componente para completar este tutorial:

  • Visual Studio 2008.

Crear la aplicación cliente.

La primera cosa que hará es crear un proyecto de formularios Windows Forms. Este tutorial utiliza formularios Windows Forms porque muchas personas están familiarizadas con ellos, pero el proceso es similar para los proyectos de Windows Presentation Foundation (WPF).

Para crear una aplicación cliente y habilitar sus servicios

  1. En Visual Studio, seleccione la opción de menú Archivo | Nuevo | Proyecto.

  2. En el cuadro de diálogo Nuevo proyecto, en el panel Tipos de proyecto, expanda el nodo Visual Basic o Visual C# y seleccione el tipo de proyecto de Windows.

  3. Asegúrese de que está seleccionado .NET Framework 3.5 y, a continuación, elija la plantilla Aplicación de Windows Forms.

  4. Cambie el Nombre del proyecto a ClientAppServicesDemo y, a continuación, haga clic en Aceptar.

    Se abrirá un nuevo proyecto de formularios Windows Forms en Visual Studio.

  5. En el menú Proyecto, seleccione Propiedades de ClientAppServicesDemo.

    Aparecerá el diseñador de proyectos.

  6. En la ficha Servicios, seleccione Habilitar servicios de aplicación cliente.

  7. Asegúrese de que está seleccionado Usar autenticación de formularios y, a continuación, establezca Ubicación del servicio de autenticación, Ubicación del servicio de funciones y Ubicación del servicio de configuración web en https://localhost:55555/AppServices.

  8. Para Visual Basic, en la ficha Aplicación, establezca Modo de autenticación en Definido para la aplicación.

El diseñador almacena los valores especificados en el archivo app.config de la aplicación.

En este punto, la aplicación está configurada para tener acceso a los tres servicios del mismo host. En la siguiente sección, creará el host como una aplicación de servicio Web simple, lo cual le permite probar la configuración del cliente.

Crear el host de servicios de aplicación

En esta sección, creará una aplicación de servicio Web simple que tenga acceso a los datos del usuario desde un archivo de base de datos de SQL Server Compact 3.5. A continuación, rellenará la base de datos mediante la Herramienta Administración de sitios Web ASP.NET. Esta sencilla configuración permite probar rápidamente la aplicación cliente. Como alternativa, puede configurar el host del servicio Web para tener acceso a los datos de usuario desde una base de datos SQL Server completa o a través de clases MembershipProvider y RoleProvider personalizadas. Para obtener más información, vea Crear y configurar la base de datos de servicios de la aplicación para SQL Server.

En el procedimiento siguiente, creará y configurará el servicio Web AppServices.

Para crear y configurar el host de servicios de aplicación

  1. En el Explorador de soluciones, seleccione la solución ClientAppServicesDemo y, a continuación, en el menú Archivo, seleccione Agregar | Nuevo proyecto.

  2. En el cuadro de diálogo Agregar nuevo proyecto, en el panel Tipos de proyecto, expanda el nodo Visual Basic o Visual C# y seleccione el tipo de proyecto Web.

  3. Asegúrese de que está seleccionado .NET Framework 3.5 y, a continuación, elija la plantilla Aplicación de servicio Web de ASP.NET.

  4. Cambie el Nombre del proyecto a AppServices y, a continuación, haga clic en Aceptar.

    Un nuevo proyecto de aplicación de servicio Web ASP.NET se agrega a la solución y el archivo Service1.asmx.vb o Service1.asmx.cs aparece en el editor.

    Nota

    El archivo Service1.asmx.vb o Service1.asmx.cs no se utiliza en este ejemplo. Si desea mantener el entorno de trabajo organizado, puede cerrarlo y eliminarlo desde el Explorador de soluciones.

  5. En el Explorador de soluciones, seleccione el proyecto AppServices y, a continuación, en el menú Proyecto elija Propiedades de AppServices.

    Aparecerá el diseñador de proyectos.

  6. En la ficha Web, asegúrese de que Usar servidor de desarrollo de Visual Studio está seleccionado.

  7. Seleccione Puerto específico, especifique un valor de 55555 y, a continuación, establezca Ruta de acceso virtual en /AppServices.

  8. Guarde todos los archivos.

  9. En el Explorador de soluciones, abra el archivo Web.config y busque la etiqueta de apertura <system.web>.

  10. Agregue el siguiente marcado antes de la etiqueta <system.web>.

    Los elementos authenticationService, profileService y roleService de este marcado habilitan y configuran los servicios de aplicación. Para evaluación, el atributo requireSSL del elemento authenticationService está establecido en "false". Los atributos writeAccessProperties y readAccessProperties del elemento profileService indican que la propiedad WebSettingsTestText es de lectura y escritura.

    Nota

    En código de producción, siempre debería tener acceso al servicio de autenticación a través de la Capa de sockets seguros (SSL), utilizando el protocolo HTTPS. Para obtener información sobre cómo configurar SSL, vea Configuring Secure Sockets Layer (IIS 6.0 Operations Guide).

    <system.web.extensions>
      <scripting>
        <webServices>
          <authenticationService enabled="true" requireSSL = "false"/>
          <profileService enabled="true"
            readAccessProperties="WebSettingsTestText"
            writeAccessProperties="WebSettingsTestText" />
          <roleService enabled="true"/>
        </webServices>
      </scripting>
    </system.web.extensions>
    
  11. Agregue el marcado siguiente después de la etiqueta de apertura <system.web> para que quede incluida en el elemento <system.web>.

    El elemento profile configura un valor web único denominado WebSettingsTestText.

    <profile enabled="true" >
      <properties>
        <add name="WebSettingsTestText" type="string" 
          readOnly="false" defaultValue="DefaultText" 
          serializeAs="String" allowAnonymous="false" />
      </properties>
    </profile>
    

En el siguiente procedimiento, utiliza la herramienta Administración de sitios Web de ASP.NET para completar la configuración del servicio y rellenar el archivo de base de datos local. Agregará dos usuarios con los nombres employee y manager que pertenecen a dos funciones con los mismos nombres. Las contraseñas de usuario son employee! y manager!, respectivamente.

Para configurar la pertenencia y las funciones

  1. En el Explorador de soluciones, seleccione el proyecto AppServices y, a continuación, en el menú Proyecto, elija Configuración de ASP.NET.

    Aparece la Herramienta Administración de sitios Web de ASP.NET.

  2. En la ficha Seguridad, haga clic en Utilice el Asistente para la configuración de seguridad para configurar la seguridad paso a paso.

    Aparece el Asistente para la configuración de seguridad, que muestra el paso Pantalla de bienvenida.

  3. Haga clic en Siguiente.

    Aparece el paso Seleccionar método de acceso.

  4. Seleccione Desde Internet. De esta forma configura el servicio para utilizar la autenticación mediante formularios en lugar de la autenticación de Windows.

  5. Haga clic en Siguiente dos veces.

    Aparece el paso Definir funciones.

  6. Seleccione Habilite las funciones para este sitio Web.

  7. Haga clic en Siguiente. Aparece el formulario Crear nueva función.

  8. En el cuadro de texto Nombre nuevo de función, escriba manager y, a continuación, haga clic en Agregar función.

    Aparece la tabla Funciones existentes con el valor especificado.

  9. En el cuadro de texto Nombre nuevo de función, reemplace manager por employee y, a continuación, haga clic en Agregar función.

    El nuevo valor aparece en la tabla Funciones existentes.

  10. Haga clic en Siguiente.

    Aparece el paso Agregar nuevos usuarios.

  11. En el formulario Crear usuario, especifique los valores siguientes.

    Nombre de usuario

    manager

    Contraseña

    manager!

    Confirmar contraseña

    manager!

    Correo electrónico

    manager@contoso.com

    Pregunta de seguridad

    manager

    Respuesta de seguridad

    manager

  12. Haga clic en Crear usuario.

    Aparece un mensaje de aprobación.

    Nota

    El formulario requiere los valores Correo electrónico, Pregunta de seguridad y Respuesta de seguridad, pero no se utilizan en este ejemplo.

  13. Haga clic en Continuar.

    Vuelve a aparecer el formulario Crear usuario.

  14. En el formulario Crear usuario, especifique los valores siguientes.

    Nombre de usuario

    employee

    Contraseña

    employee!

    Confirmar contraseña

    employee!

    Correo electrónico

    employee@contoso.com

    Pregunta de seguridad

    Employee

    Respuesta de seguridad

    employee

  15. Haga clic en Crear usuario.

    Aparece un mensaje de aprobación.

  16. Haga clic en Finalizar.

    Vuelve a aparecer la Herramienta Administración de sitios Web.

  17. Haga clic en Administrar usuarios.

    Aparece la lista de usuarios.

  18. Haga clic en Editar funciones en el usuario employee y, a continuación, seleccione la función employee.

  19. Haga clic en Editar funciones en el usuario manager y, a continuación, seleccione la función manager.

  20. Cierre la ventana del explorador que hospeda la Herramienta Administración de sitios Web.

  21. Si aparece un cuadro de mensaje que pregunta si desea volver a cargar el archivo Web.config modificado, haga clic en .

Esto completa la configuración del servicio Web. En este punto, puede presionar F5 para ejecutar la aplicación cliente, y el Servidor de desarrollo de ASP.NET se iniciará automáticamente junto con la aplicación cliente. El servidor continuará ejecutándose después de salir de la aplicación, pero se reiniciará al reiniciar la aplicación. Esto permite detectar cualquier cambio realizado en Web.config.

Para detener el servidor manualmente, haga clic con el botón secundario del mouse en el icono del Servidor de desarrollo de ASP.NET en el área de notificación de la barra de tareas y, a continuación, haga clic en Detener. Esto resulta útil en ocasiones para asegurarse de que se produce un reinicio limpio.

Agregar autenticación mediante formularios

En el siguiente procedimiento, va a agregar código al formulario principal que intenta validar al usuario y deniega el acceso si el usuario proporciona credenciales no válidas. Utilizará un nombre de usuario y una contraseña codificados de forma rígida para probar el servicio.

Para validar al usuario en el código de aplicación

  1. En el Explorador de soluciones, en el proyecto ClientAppServicesDemo, agregue una referencia al ensamblado System.Web.

  2. Seleccione el archivo Form1 y, a continuación, elija Ver | Código en el menú principal de Visual Studio.

  3. En el editor de código, agregue las siguientes instrucciones en la parte superior del archivo Form1.

    Imports System.Net
    Imports System.Threading
    Imports System.Web.ClientServices
    Imports System.Web.ClientServices.Providers
    Imports System.Web.Security
    
    using System.Net;
    using System.Threading;
    using System.Web.ClientServices;
    using System.Web.ClientServices.Providers;
    using System.Web.Security;
    
  4. En el Explorador de soluciones, haga doble clic en Form1 para mostrar el diseñador.

  5. En el diseñador, haga doble clic en la superficie del formulario para generar un controlador de eventos Form.Load denominado Form1_Load.

    Aparecerá el editor de código con el cursor en el método Form1_Load.

  6. Agregue el código siguiente al método Form1_Load.

    Este código deniega el acceso a los usuarios no autenticados saliendo de la aplicación. Como alternativa, podría permitir el acceso de los usuarios no autenticados al formulario, pero denegar el acceso a una funcionalidad específica. Normalmente, no asignará el nombre de usuario y la contraseña de este modo, pero resulta útil para evaluación. En la siguiente sección, reemplazará este código por un código más robusto que muestre un cuadro de diálogo de inicio de sesión e incluya control de excepciones.

    Tenga en cuenta que el método static Membership.ValidateUser pertenece a .NET Framework versión 2.0. Este método delega su trabajo al proveedor de autenticación configurado y devuelve true si la autenticación se realiza correctamente. La aplicación no requiere una referencia directa al proveedor de autenticación del cliente.

    If Not Membership.ValidateUser("manager", "manager!") Then
    
        MessageBox.Show("Unable to authenticate.", "Not logged in", _
            MessageBoxButtons.OK, MessageBoxIcon.Error)
        Application.Exit()
    
    End If
    
    if (!Membership.ValidateUser("manager", "manager!"))
    {
        MessageBox.Show("Unable to authenticate.", "Not logged in",
            MessageBoxButtons.OK, MessageBoxIcon.Error);
        Application.Exit();
    }
    

Ahora puede presionar F5 para ejecutar la aplicación y, como proporciona un nombre de usuario y contraseña correctos, verá el formulario.

Nota

Si no puede ejecutar la aplicación, pruebe a detener el Servidor de desarrollo de ASP.NET. Cuando se reinicia el servidor, compruebe que el puerto está establecido en 55555.

Para ver el mensaje de error en su lugar, cambie los parámetros ValidateUser. Por ejemplo, reemplace el segundo parámetro "manager!" por una contraseña incorrecta como "MANAGER".

Agregar un formulario de inicio de sesión como un proveedor de credenciales

Puede adquirir las credenciales de usuario del código de aplicación y pasarlas al método ValidateUser. Sin embargo, a menudo resulta útil mantener el código adquirido de las credenciales independiente del código de aplicación, en caso de que desee cambiarlo posteriormente.

En el procedimiento siguiente, va a configurar la aplicación para que use un proveedor de credenciales y, a continuación, va a cambiar la llamada al método ValidateUser para pasar Empty para ambos parámetros. Las cadenas vacías señalan al método ValidateUser para que llame al método GetCredentials del proveedor de credenciales configurado.

Para configurar la aplicación de modo que use un proveedor de credenciales

  1. En el Explorador de soluciones, seleccione el proyecto ClientAppServicesDemo y, a continuación, en el menú Proyecto, elija Propiedades de ClientAppServicesDemo.

    Aparecerá el diseñador de proyectos.

  2. En la ficha Servicios, establezca Opcional: Proveedor de credenciales en el siguiente valor. Este valor indica el nombre de tipo calificado con el nombre de ensamblado.

    ClientAppServicesDemo.Login, ClientAppServicesDemo
    
  3. En el archivo de código Form1, reemplace el código del método Form1_Load por el código siguiente.

    Este código muestra un mensaje de bienvenida y, a continuación, llama al método ValidateUsingCredentialsProvider que agregará en el paso siguiente. Si no se autentica el usuario, el método ValidateUsingCredentialsProvider devuelve false y el método devuelve Form1_Load. Esto evita que se ejecute código adicional antes de salir de la aplicación. El mensaje de bienvenida es útil para indicar cuándo se reinicia la aplicación. Agregará código para reiniciar la aplicación al implementar el cierre de sesión más adelante en este tutorial.

    MessageBox.Show("Welcome to the Client Application Services Demo.", _
        "Welcome!")
    
    If Not ValidateUsingCredentialsProvider() Then Return
    
    MessageBox.Show("Welcome to the Client Application Services Demo.",
        "Welcome!");
    
    if (!ValidateUsingCredentialsProvider()) return;
    
  4. Agregue el siguiente método después del método Form1_Load.

    Este método pasa cadenas vacías al método static Membership.ValidateUser, que hace que aparezca el cuadro de diálogo Inicio de sesión. Si el servicio de autenticación no está disponible, el método ValidateUser iniciará una excepción WebException. En este caso, el método ValidateUsingCredentialsProvider muestra un mensaje de advertencia y pregunta al usuario si desea intentarlo de nuevo en el modo sin conexión. Esta funcionalidad requiere la característica Guardar hash de contraseña para permitir el inicio de sesión sin conexión descrita en Cómo: Configurar servicios de aplicaciones cliente. Esta característica está habilitada de forma predeterminada para los nuevos proyectos.

    Si no se valida el usuario, el método ValidateUsingCredentialsProvider muestra un mensaje de error y cierra la aplicación. Finalmente, este método devuelve el resultado del intento de autenticación.

    Private Function ValidateUsingCredentialsProvider() As Boolean
    
        Dim isAuthorized As Boolean = False
    
        Try
    
            ' Call ValidateUser with empty strings in order to display the 
            ' login dialog box configured as a credentials provider.
            isAuthorized = Membership.ValidateUser( _
                String.Empty, String.Empty)
    
        Catch ex As System.Net.WebException
    
            If DialogResult.OK = MessageBox.Show( _
                "Unable to access the authentication service." & _
                Environment.NewLine & "Attempt login in offline mode?", _
                "Warning", MessageBoxButtons.OKCancel, _
                MessageBoxIcon.Warning) Then
    
                ConnectivityStatus.IsOffline = True
                isAuthorized = Membership.ValidateUser( _
                    String.Empty, String.Empty)
    
            End If
    
        End Try
    
        If Not isAuthorized Then
    
            MessageBox.Show("Unable to authenticate.", "Not logged in", _
                MessageBoxButtons.OK, MessageBoxIcon.Error)
            Application.Exit()
    
        End If
    
        Return isAuthorized
    
    End Function
    
    private bool ValidateUsingCredentialsProvider()
    {
        bool isAuthorized = false;
        try
        {
            // Call ValidateUser with empty strings in order to display the 
            // login dialog box configured as a credentials provider.
            isAuthorized = Membership.ValidateUser(
                String.Empty, String.Empty);
        }
        catch (System.Net.WebException)
        {
            if (DialogResult.OK == MessageBox.Show(
                "Unable to access the authentication service." +
                Environment.NewLine + "Attempt login in offline mode?",
                "Warning", MessageBoxButtons.OKCancel, 
                MessageBoxIcon.Warning))
            {
                ConnectivityStatus.IsOffline = true;
                isAuthorized = Membership.ValidateUser(
                    String.Empty, String.Empty);
            }
        }
    
        if (!isAuthorized)
        {
            MessageBox.Show("Unable to authenticate.", "Not logged in",
                MessageBoxButtons.OK, MessageBoxIcon.Error);
            Application.Exit();
        }
        return isAuthorized;
    }
    

Crear un formulario de inicio de sesión

Un proveedor de credenciales es una clase que implementa la interfaz IClientFormsAuthenticationCredentialsProvider. Esta interfaz tiene un método único denominado GetCredentials que devuelve un objeto ClientFormsAuthenticationCredentials. Los siguientes procedimientos describen cómo crear un cuadro de diálogo de inicio de sesión que implementa GetCredentials para mostrarse a sí mismo y devolver las credenciales especificadas por el usuario.

Se proporcionan procedimientos independientes para Visual Basic y C# porque Visual Basic dispone de una plantilla Formulario de inicio de sesión. Esto ahorra algo de tiempo y esfuerzos de codificación.

Para crear un cuadro de diálogo de inicio de sesión como un proveedor de credenciales en Visual Basic

  1. En el Explorador de soluciones, seleccione el proyecto ClientAppServicesDemo y, a continuación, en el menú Proyecto, elija Agregar nuevo elemento.

  2. En el cuadro de diálogo Agregar nuevo elemento, seleccione la plantilla Formulario de inicio de sesión, cambie el elemento Nombre a Login.vb y, a continuación, haga clic en Agregar.

    Aparecerá el cuadro de diálogo de inicio de sesión en el Diseñador de Windows Forms.

  3. En el diseñador, seleccione el botón Aceptar y, a continuación, en la ventana Propiedades, establezca DialogResult en OK.

  4. En el diseñador, agregue un control CheckBox al formulario bajo el cuadro de texto Contraseña.

  5. En la ventana Propiedades, especifique un valor (Nombre) de rememberMeCheckBox y un valor Texto de &Remember me.

  6. Seleccione Ver | Código en el menú principal de Visual Studio.

  7. En el editor de código, agregue el siguiente código a la parte superior del archivo.

    Imports System.Web.ClientServices.Providers
    
  8. Modifique la firma de clase para que ésta implemente la interfaz IClientFormsAuthenticationCredentialsProvider.

    Public Class Login
        Implements IClientFormsAuthenticationCredentialsProvider
    
  9. Asegúrese de que el cursor se encuentra después de IClientformsAuthenticationCredentialsProvider, y, a continuación, presione ENTRAR para generar el método GetCredentials.

  10. Busque la implementación GetCredentials y, a continuación, reemplácela por el código siguiente.

    Public Function GetCredentials() As  _
        ClientFormsAuthenticationCredentials Implements _
        IClientFormsAuthenticationCredentialsProvider.GetCredentials
    
        If Me.ShowDialog() = DialogResult.OK Then
            Return New ClientFormsAuthenticationCredentials( _
                UsernameTextBox.Text, PasswordTextBox.Text, _
                rememberMeCheckBox.Checked)
        Else
            Return Nothing
        End If
    
    End Function
    

El siguiente procedimiento de C# proporciona la lista de código completa de un cuadro de diálogo de inicio de sesión simple. El diseño de este cuadro de diálogo es un poco tosco, pero lo importante es la implementación de GetCredentials.

Para crear un cuadro de diálogo de inicio de sesión como un proveedor de credenciales en C#

  1. En el Explorador de soluciones, seleccione el proyecto ClientAppServicesDemo y, a continuación, en el menú Proyecto, elija Agregar clase.

  2. En el cuadro de diálogo Agregar nuevo elemento, cambie el Nombre a Login.cs y, a continuación, haga clic en Agregar.

    El archivo Login.cs se abrirá en el editor de código.

  3. Reemplace el código predeterminado por el siguiente código.

    using System.Windows.Forms;
    using System.Web.ClientServices.Providers;
    
    namespace ClientAppServicesDemo
    {
        class Login : Form,
            IClientFormsAuthenticationCredentialsProvider
        {
            private TextBox usernameTextBox;
            private TextBox passwordTextBox;
            private CheckBox rememberMeCheckBox;
            private Button OK;
            private Button cancel;
            private Label label1;
            private Label label2;
    
            public ClientFormsAuthenticationCredentials GetCredentials()
            {
                if (this.ShowDialog() == DialogResult.OK)
                {
                    return new ClientFormsAuthenticationCredentials(
                        usernameTextBox.Text, passwordTextBox.Text,
                        rememberMeCheckBox.Checked);
                }
                else
                {
                    return null;
                }
            }
    
            public Login()
            {
                InitializeComponent();
            }
    
            private void CloseForm(object sender, System.EventArgs e)
            {
                this.Close();
            }
    
            private void InitializeComponent()
            {
                this.label1 = new System.Windows.Forms.Label();
                this.usernameTextBox = new System.Windows.Forms.TextBox();
                this.label2 = new System.Windows.Forms.Label();
                this.passwordTextBox = new System.Windows.Forms.TextBox();
                this.rememberMeCheckBox = new System.Windows.Forms.CheckBox();
                this.OK = new System.Windows.Forms.Button();
                this.cancel = new System.Windows.Forms.Button();
                this.SuspendLayout();
                // 
                // label1
                // 
                this.label1.AutoSize = true;
                this.label1.Location = new System.Drawing.Point(13, 13);
                this.label1.Name = "label1";
                this.label1.Size = new System.Drawing.Size(58, 13);
                this.label1.TabIndex = 0;
                this.label1.Text = "&User name";
                // 
                // usernameTextBox
                // 
                this.usernameTextBox.Location = new System.Drawing.Point(13, 30);
                this.usernameTextBox.Name = "usernameTextBox";
                this.usernameTextBox.Size = new System.Drawing.Size(157, 20);
                this.usernameTextBox.TabIndex = 1;
                // 
                // label2
                // 
                this.label2.AutoSize = true;
                this.label2.Location = new System.Drawing.Point(13, 57);
                this.label2.Name = "label2";
                this.label2.Size = new System.Drawing.Size(53, 13);
                this.label2.TabIndex = 2;
                this.label2.Text = "&Password";
                // 
                // passwordTextBox
                // 
                this.passwordTextBox.Location = new System.Drawing.Point(13, 74);
                this.passwordTextBox.Name = "passwordTextBox";
                this.passwordTextBox.PasswordChar = '*';
                this.passwordTextBox.Size = new System.Drawing.Size(157, 20);
                this.passwordTextBox.TabIndex = 3;
                // 
                // rememberMeCheckBox
                // 
                this.rememberMeCheckBox.AutoSize = true;
                this.rememberMeCheckBox.Location = new System.Drawing.Point(13, 101);
                this.rememberMeCheckBox.Name = "rememberMeCheckBox";
                this.rememberMeCheckBox.Size = new System.Drawing.Size(94, 17);
                this.rememberMeCheckBox.TabIndex = 4;
                this.rememberMeCheckBox.Text = "&Remember me";
                this.rememberMeCheckBox.UseVisualStyleBackColor = true;
                // 
                // OK
                // 
                this.OK.DialogResult = System.Windows.Forms.DialogResult.OK;
                this.OK.Location = new System.Drawing.Point(13, 125);
                this.OK.Name = "OK";
                this.OK.Size = new System.Drawing.Size(75, 23);
                this.OK.TabIndex = 5;
                this.OK.Text = "&OK";
                this.OK.UseVisualStyleBackColor = true;
                // 
                // cancel
                // 
                this.cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
                this.cancel.Location = new System.Drawing.Point(95, 125);
                this.cancel.Name = "cancel";
                this.cancel.Size = new System.Drawing.Size(75, 23);
                this.cancel.TabIndex = 6;
                this.cancel.Text = "&Cancel";
                this.cancel.UseVisualStyleBackColor = true;
                // 
                // Login
                // 
                this.AcceptButton = this.OK;
                this.CancelButton = this.cancel;
                this.ClientSize = new System.Drawing.Size(187, 168);
                this.Controls.Add(this.cancel);
                this.Controls.Add(this.OK);
                this.Controls.Add(this.rememberMeCheckBox);
                this.Controls.Add(this.passwordTextBox);
                this.Controls.Add(this.label2);
                this.Controls.Add(this.usernameTextBox);
                this.Controls.Add(this.label1);
                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
                this.MaximizeBox = false;
                this.MinimizeBox = false;
                this.Name = "Login";
                this.Text = "Login";
                this.ResumeLayout(false);
                this.PerformLayout();
    
            }
        }
    
    }
    

Ahora puede ejecutar la aplicación y ver el cuadro de diálogo de inicio de sesión que aparece. Para probar este código, ensaye con credenciales diferentes, válidas y no válidas, y confirme que sólo puede tener acceso al formulario con las credenciales válidas. Los nombres de usuario válidos son employee y manager con las contraseñas employee! y manager!, respectivamente.

Nota

No seleccione Recordar cuenta en este punto o no podrá iniciar sesión como otro usuario hasta que implemente el cierre de sesión más adelante en este tutorial.

Agregar funcionalidad basada en la función

En el siguiente procedimiento, agregará un botón al formulario y lo mostrará sólo a los usuarios que tengan la función de administrador.

Para cambiar la interfaz de usuario basada en la función del usuario

  1. En el Explorador de soluciones, en el proyecto ClientAppServicesDemo, seleccione Form1 y, a continuación, elija Vista | Diseñador en el menú principal de Visual Studio.

  2. En el diseñador, agregue un control Button al formulario desde el Cuadro de herramientas.

  3. En la ventana Propiedades, establezca las siguientes propiedades para el botón.

    Propiedad

    Valor

    (Name)

    managerOnlyButton

    Text

    &Administrador de tareas

    Visible

    False

  4. En el editor de código de Form1, agregue el siguiente código al final del método Form1_Load.

    Este código llama al método DisplayButtonForManagerRole que agregará en el paso siguiente.

    DisplayButtonForManagerRole()
    
    DisplayButtonForManagerRole();
    
  5. Agregue el siguiente método al final de la clase Form1.

    Este método llama al método IsInRole del objeto IPrincipal devuelto por la propiedad static Thread.CurrentPrincipal. Para las aplicaciones configuradas para utilizar servicios de aplicaciones cliente, esta propiedad devuelve ClientRolePrincipal. Dado que esta clase implementa la interfaz IPrincipal, no necesita hacer referencia a ella explícitamente.

    Si el usuario tiene la función de "administrador", el método DisplayButtonForManagerRole establece la propiedad Visible de managerOnlyButton en true. Este método también muestra un mensaje de error si se inicia una excepción WebException, que indica que el servicio de funciones no está disponible.

    Nota

    El método IsInRole siempre devolverá false si el inicio de sesión de usuario ha expirado. Esto no ocurrirá si la aplicación llama al método IsInRole poco después de que se realice la autenticación, como se muestra en el código de ejemplo de este tutorial. Si la aplicación debe recuperar las funciones de usuario en otras ocasiones, conviene agregar el código para volver a validar a los usuarios cuyo inicio de sesión haya expirado. Si todos los usuarios válidos están asignados a funciones, puede determinar si el inicio de sesión ha expirado llamando al método ClientRoleProvider.GetRolesForUser. Si no se devuelve ninguna función, significa que el inicio de sesión ha expirado. Para obtener un ejemplo de esta funcionalidad, vea el método GetRolesForUser. Esta funcionalidad sólo es necesaria si ha seleccionado Exigir que los usuarios vuelvan a iniciar sesión cuando expire la cookie del servidor en la configuración de la aplicación. Para obtener más información, vea Cómo: Configurar servicios de aplicaciones cliente.

    Private Sub DisplayButtonForManagerRole()
    
        Try
    
            If Thread.CurrentPrincipal.IsInRole("manager") Then
    
                managerOnlyButton.Visible = True
    
            End If
    
        Catch ex As System.Net.WebException
    
            MessageBox.Show("Unable to access the roles service.", _
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    
        End Try
    
    End Sub
    
    private void DisplayButtonForManagerRole()
    {
        try
        {
            if (Thread.CurrentPrincipal.IsInRole("manager"))
            {
                managerOnlyButton.Visible = true;
            }
        }
        catch (System.Net.WebException)
        {
            MessageBox.Show("Unable to access the role service.",
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
    

Si la autenticación se realizó correctamente, el proveedor de autenticación del cliente establece la propiedad Thread.CurrentPrincipal en una instancia de la clase ClientRolePrincipal. Esta clase implementa el método IsInRole para que el trabajo se delegue al proveedor de funciones configurado. Como anteriormente, el código de aplicación no requiere una referencia directa al proveedor de servicios.

Ahora puede ejecutar la aplicación e iniciar sesión como empleado para comprobar que el botón no aparece y, a continuación, iniciar sesión como administrador para ver el botón.

Tener acceso a la configuración web

En el procedimiento siguiente, va a agregar un cuadro de texto al formulario y a enlazarlo a una configuración web. Al igual que el código anterior que utilizaba autenticación y funciones, el código de configuración no tiene acceso al proveedor de la configuración directamente. En su lugar, utiliza clase Settings con establecimiento inflexible de tipos (a la que se obtiene acceso como Properties.Settings.Default en C# y My.Settings en Visual Basic) generada para el proyecto por Visual Studio.

Para utilizar la configuración web en la interfaz de usuario

  1. Asegúrese de que el Servidor de desarrollo web de ASP.NET todavía está en ejecución comprobando el área de notificación de la barra de tareas. Si ha detenido el servidor, reinicie la aplicación (lo cual inicia el servidor automáticamente) y, a continuación, cierre el cuadro de diálogo de inicio de sesión.

  2. En el Explorador de soluciones, seleccione el proyecto ClientAppServicesDemo y, a continuación, en el menú Proyecto, elija Propiedades de ClientAppServicesDemo.

    Aparecerá el diseñador de proyectos.

  3. En la ficha Configuración, haga clic en Cargar configuración web.

    Aparecerá un cuadro de diálogo Inicio de sesión.

  4. Especifique las credenciales de empleado o administrador y haga clic en Iniciar sesión. La configuración web que usará está establecida para que sólo tengan acceso los usuarios autenticados, de modo que si hace clic en Omitir inicio de sesión no cargará la configuración.

    La configuración WebSettingsTestText aparece en el diseñador con el valor predeterminado de DefaultText. Además, para el proyecto se genera una clase Settings que contiene una propiedad WebSettingsTestText.

  5. En el Explorador de soluciones, en el proyecto ClientAppServicesDemo, seleccione Form1 y, a continuación, elija Vista | Diseñador en el menú principal de Visual Studio.

  6. En el diseñador, agregue un control TextBox al formulario.

  7. En la ventana Propiedades, especifique un valor (Nombre) de webSettingsTestTextBox.

  8. En el editor de código, agregue el siguiente código al final del método Form1_Load.

    Este código llama al método BindWebSettingsTestTextBox que agregará en el paso siguiente.

    BindWebSettingsTestTextBox()
    
    BindWebSettingsTestTextBox();
    
  9. Agregue el siguiente método al final de la clase Form1.

    Este método enlaza la propiedad Text del objeto webSettingsTestTextBox a la propiedad WebSettingsTestText de la clase Settings generada anteriormente en este procedimiento. Este método también muestra un mensaje de error si se inicia una excepción WebException, que indica que el servicio de configuración web no está disponible.

    Private Sub BindWebSettingsTestTextBox()
    
        Try
    
            Me.webSettingsTestTextBox.DataBindings.Add("Text", _
                My.Settings, "WebSettingsTestText")
    
        Catch ex As WebException
    
            MessageBox.Show("Unable to access the Web settings service.", _
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    
        End Try
    
    End Sub
    
    private void BindWebSettingsTestTextBox()
    {
        try
        {
            this.webSettingsTestTextBox.DataBindings.Add("Text",
                Properties.Settings.Default, "WebSettingsTestText");
        }
        catch (WebException)
        {
            MessageBox.Show("Unable to access the Web settings service.",
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
    

    Nota

    Normalmente, utilizará el enlace de datos para habilitar la comunicación bidireccional automática entre un control y una configuración web. Sin embargo, también puede tener acceso directamente a la configuración web como se muestra en el ejemplo siguiente:

    webSettingsTestTextBox.Text = My.Settings.WebSettingsTestText
    
    webSettingsTestTextBox.Text =
        Properties.Settings.Default.WebSettingsTestText;
    
  10. En el diseñador, seleccione el formulario y, a continuación, en la ventana Propiedades, haga clic en el botón Eventos.

  11. Seleccione el evento FormClosing y, a continuación, presione ENTRAR para generar un controlador de eventos.

  12. Reemplace el método generado por el siguiente código.

    El controlador de eventos FormClosing llama al método SaveSettings, que también lo utiliza la funcionalidad de cierre de sesión que se agregará en la sección siguiente. El método SaveSettings confirma primero que el usuario no ha cerrado la sesión. Esto se hace comprobando la propiedad AuthenticationType de IIdentity que devuelve la entidad de seguridad actual. La entidad de seguridad actual se obtiene a través de la propiedad static CurrentPrincipal. Si el usuario se ha autenticado para los servicios de aplicaciones cliente, el tipo de autenticación será "ClientForms". El método SaveSettings no puede comprobar solamente la propiedad IIdentity.IsAuthenticated porque el usuario podría tener una identidad de Windows válida después del cierre de sesión.

    Si el usuario no ha cerrado la sesión, el método SaveSettings llamará al método Save de la clase Settings generada anteriormente en este procedimiento. Este método puede iniciar una excepción WebException si la cookie de autenticación ha expirado. Esto sólo se produce si ha seleccionado Exigir que los usuarios vuelvan a iniciar sesión cuando expire la cookie del servidor en la configuración de la aplicación. Para obtener más información, vea Cómo: Configurar servicios de aplicaciones cliente. El método SaveSettings administra la expiración de la cookie llamando a ValidateUser para mostrar el cuadro de diálogo de inicio de sesión. Si el usuario inicia sesión correctamente, el método SaveSettings intenta guardar la configuración de nuevo llamándose a sí mismo.

    Como en el código anterior, el método SaveSettings muestra un mensaje de error si el servicio remoto no está disponible. Si el proveedor de configuración no puede tener acceso al servicio remoto, la configuración aún se guardará en la caché local todavía y se volverá a cargar cuando se reinicie la aplicación.

    Private Sub Form1_FormClosing(ByVal sender As Object, _
        ByVal e As FormClosingEventArgs) Handles Me.FormClosing
    
        SaveSettings()
    
    End Sub
    
    Private Sub SaveSettings()
    
        ' Return without saving if the authentication type is not
        ' "ClientForms". This indicates that the user is logged out.
        If Not Thread.CurrentPrincipal.Identity.AuthenticationType _
            .Equals("ClientForms") Then Return
    
        Try
    
            My.Settings.Save()
    
        Catch ex As WebException
    
            If ex.Message.Contains("You must log on to call this method.") Then
    
                MessageBox.Show( _
                    "Your login has expired. Please log in again to save " & _
                    "your settings.", "Attempting to save settings...")
    
                Dim isAuthorized As Boolean = False
    
                Try
    
                    ' Call ValidateUser with empty strings in order to 
                    ' display the login dialog box configured as a 
                    ' credentials provider.
                    If Not Membership.ValidateUser( _
                        String.Empty, String.Empty) Then
    
                        MessageBox.Show("Unable to authenticate. " & _
                            "Settings were not saved on the remote service.", _
                            "Not logged in", MessageBoxButtons.OK, _
                            MessageBoxIcon.Error)
    
                    Else
    
                        ' Try again.
                        SaveSettings()
    
                    End If
    
                Catch ex2 As System.Net.WebException
    
                    MessageBox.Show( _
                        "Unable to access the authentication service. " & _
                        "Settings were not saved on the remote service.", _
                        "Not logged in", MessageBoxButtons.OK, _
                        MessageBoxIcon.Warning)
    
                End Try
    
            Else
    
                MessageBox.Show("Unable to access the Web settings service. " & _
                    "Settings were not saved on the remote service.", _
                    "Not logged in", MessageBoxButtons.OK, _
                    MessageBoxIcon.Warning)
    
            End If
    
        End Try
    
    End Sub
    
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        SaveSettings();
    }
    
    private void SaveSettings()
    {
        // Return without saving if the authentication type is not
        // "ClientForms". This indicates that the user is logged out.
        if (!Thread.CurrentPrincipal.Identity.AuthenticationType
          .Equals("ClientForms")) return;
    
        try
        {
            Properties.Settings.Default.Save();
        }
        catch (WebException ex)
        {
            if (ex.Message.Contains("You must log on to call this method."))
            {
                MessageBox.Show(
                    "Your login has expired. Please log in again to save " +
                    "your settings.", "Attempting to save settings...");
    
                try
                {
                    // Call ValidateUser with empty strings in order to 
                    // display the login dialog box configured as a 
                    // credentials provider.
                    if (!Membership.ValidateUser(String.Empty, String.Empty))
                    {
                        MessageBox.Show("Unable to authenticate. " +
                            "Settings were not saved on the remote service.",
                            "Not logged in", MessageBoxButtons.OK, 
                            MessageBoxIcon.Error);
                    }
                    else
                    {
                        // Try again.
                        SaveSettings();
                    }
                }
                catch (System.Net.WebException)
                {
                    MessageBox.Show(
                        "Unable to access the authentication service. " +
                        "Settings were not saved on the remote service.",
                        "Not logged in", MessageBoxButtons.OK, 
                        MessageBoxIcon.Warning);
                }
            }
            else
            {
                MessageBox.Show("Unable to access the Web settings service. " +
                    "Settings were not saved on the remote service.", 
                    "Not logged in", MessageBoxButtons.OK, 
                    MessageBoxIcon.Warning);
            }
        }
    }
    
  13. Agregue el siguiente método al final de la clase Form1.

    Este código administra el evento ClientSettingsProvider.SettingsSaved y muestra una advertencia si no se pudo guardar alguno de los valores de configuración. El evento SettingsSaved no se produce si el servicio de configuración no está disponible o si la cookie de autenticación ha expirado. Un ejemplo de cuándo se producirá el evento SettingsSaved es si el usuario ya ha cerrado la sesión. Puede probar este controlador de eventos agregando código de cierre de sesión directamente al método SaveSettings antes de la llamada al método Save. El código de cierre de sesión que puede utilizar se describe en la siguiente sección.

    Private WithEvents settingsProvider As ClientSettingsProvider = My.Settings _
        .Providers("System.Web.ClientServices.Providers.ClientSettingsProvider")
    
    Private Sub Form1_SettingsSaved(ByVal sender As Object, _
        ByVal e As SettingsSavedEventArgs) _
        Handles settingsProvider.SettingsSaved
    
        ' If any settings were not saved, display a list of them.
        If e.FailedSettingsList.Count > 0 Then
    
            Dim failedSettings As String = String.Join( _
                Environment.NewLine, e.FailedSettingsList.ToArray())
    
            Dim message As String = String.Format("{0}{1}{1}{2}", _
                "The following setting(s) were not saved:", _
                Environment.NewLine, failedSettings)
    
            MessageBox.Show(message, "Unable to save settings", _
                MessageBoxButtons.OK, MessageBoxIcon.Warning)
    
        End If
    
    End Sub
    
    private void Form1_SettingsSaved(object sender,
        SettingsSavedEventArgs e)
    {
        // If any settings were not saved, display a list of them.
        if (e.FailedSettingsList.Count > 0)
        {
            String failedSettings = String.Join(
                Environment.NewLine,
                e.FailedSettingsList.ToArray());
    
            String message = String.Format("{0}{1}{1}{2}",
                "The following setting(s) were not saved:",
                Environment.NewLine, failedSettings);
    
            MessageBox.Show(message, "Unable to save settings",
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
    
  14. Para C#, agregue el siguiente código al final del método Form1_Load. Este código asocia el método agregado en el último paso al evento SettingsSaved.

    ((ClientSettingsProvider)Properties.Settings.Default.Providers
        ["System.Web.ClientServices.Providers.ClientSettingsProvider"])
        .SettingsSaved += 
        new EventHandler<SettingsSavedEventArgs>(Form1_SettingsSaved);
    

Para probar la aplicación en este punto, ejecútela varias veces como empleado y administrador, y escriba los diferentes valores en el cuadro de texto. Los valores se conservarán en las sesiones de cada usuario.

Implementar el cierre de sesión

Cuando el usuario activa la casilla Recordar cuenta al iniciar sesión, la aplicación autenticará automáticamente al usuario en las ejecuciones subsiguientes. A continuación, continuará la autenticación automática mientras la aplicación está en el modo sin conexión o hasta que expire la cookie de autenticación. Sin embargo, a veces varios usuarios puede que necesiten acceso a la aplicación o, en ocasiones, un único usuario podría iniciar sesión con credenciales diferentes. Para habilitar este escenario, debe implementar la funcionalidad de cierre de sesión, como se describe en el procedimiento siguiente.

Para implementar la funcionalidad de cierre de sesión

  1. En el diseñador Form1, agregue un control Button al formulario desde el Cuadro de herramientas.

  2. En la ventana Propiedades, especifique para (Nombre) el valor logoutButton y para Texto el valor &Cerrar sesión.

  3. Haga doble clic en logoutButton para generar un controlador de eventos Click.

    Aparecerá el editor de código con el cursor en el método logoutButton_Click.

  4. Reemplace el método logoutButton_Click generado por el siguiente código.

    Este controlador de eventos llama primero al método SaveSettings agregado en la sección anterior. A continuación, el controlador de eventos llama al método ClientFormsAuthenticationMembershipProvider.Logout. Si el servicio de autenticación no está disponible, el método Logout iniciará una excepción WebException. En este caso, el método logoutButton_Click muestra un mensaje de advertencia y pasa temporalmente al modo sin conexión para cerrar la sesión del usuario. El modo sin conexión se describe en la siguiente sección.

    El cierre de sesión elimina la cookie de autenticación local para que sea necesario el inicio de sesión cuando se reinicie la aplicación. Después del cierre de sesión, el controlador de eventos reinicia la aplicación. Cuando se reinicia la aplicación, muestra el mensaje de bienvenida seguido por el cuadro de diálogo de inicio de sesión. El mensaje de bienvenida indica claramente que la aplicación se ha reiniciado. Esto evita una posible confusión si el usuario debe iniciar sesión para guardar la configuración y, a continuación, debe iniciar sesión de nuevo porque se ha reiniciado la aplicación.

    Private Sub logoutButton_Click(ByVal sender As Object, _
        ByVal e As EventArgs) Handles logoutButton.Click
    
        SaveSettings()
    
        Dim authProvider As ClientFormsAuthenticationMembershipProvider = _
            CType(System.Web.Security.Membership.Provider,  _
            ClientFormsAuthenticationMembershipProvider)
    
        Try
    
            authProvider.Logout()
    
        Catch ex As WebException
    
            MessageBox.Show("Unable to access the authentication service." & _
                Environment.NewLine & "Logging off locally only.", _
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            ConnectivityStatus.IsOffline = True
            authProvider.Logout()
            ConnectivityStatus.IsOffline = False
    
        End Try
    
        Application.Restart()
    
    End Sub
    
    private void logoutButton_Click(object sender, EventArgs e)
    {
        SaveSettings();
    
        ClientFormsAuthenticationMembershipProvider authProvider =
            (ClientFormsAuthenticationMembershipProvider)
            System.Web.Security.Membership.Provider;
    
        try
        {
            authProvider.Logout();
        }
        catch (WebException ex)
        {
            MessageBox.Show("Unable to access the authentication service." +
                Environment.NewLine + "Logging off locally only.",
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            ConnectivityStatus.IsOffline = true;
            authProvider.Logout();
            ConnectivityStatus.IsOffline = false;
        }
    
        Application.Restart();
    }
    

Para probar la funcionalidad de cierre de sesión, ejecute la aplicación y seleccione Recordar cuenta en el cuadro de diálogo Inicio de sesión. A continuación, cierre y reinicie la aplicación para confirmar que ya no tiene que iniciar sesión. Por último, reinicie la aplicación haciendo clic en Cerrar sesión.

Habilitar el modo sin conexión

En el procedimiento siguiente, va a agregar una casilla al formulario para permitir al usuario que entre en el modo sin conexión. La aplicación indica el modo sin conexión estableciendo la propiedad static ConnectivityStatus.IsOffline en true. El estado sin conexión se almacena en el disco duro local en la ubicación indicada por la propiedad Application.UserAppDataPath. Esto significa que el estado sin conexión se almacena para cada usuario y aplicación.

En el modo sin conexión, todas las solicitudes de servicios de aplicaciones cliente recuperan datos de la caché local en lugar de intentar tener acceso a los servicios. En la configuración predeterminada, los datos locales incluyen un formulario cifrado de la contraseña del usuario. Esto permite al usuario iniciar sesión mientras la aplicación está en el modo sin conexión. Para obtener más información, vea Cómo: Configurar servicios de aplicaciones cliente.

Para habilitar el modo sin conexión en la aplicación

  1. En el Explorador de soluciones, en el proyecto ClientAppServicesDemo, seleccione Form1 y, a continuación, elija Vista | Diseñador en el menú principal de Visual Studio.

  2. En el diseñador, agregue un control CheckBox al formulario.

  3. En la ventana Propiedades, especifique para (Nombre) el valor workOfflineCheckBox y para Texto el valor &Trabajar sin conexión.

  4. En la ventana Propiedades, haga clic en el botón Eventos.

  5. Seleccione el evento CheckedChanged y, a continuación, presione ENTRAR para generar un controlador de eventos.

  6. Reemplace el método generado por el siguiente código.

    Este código actualiza el valor IsOffline y vuelve a validar al usuario silenciosamente cuando regresa al modo en línea. El método ClientFormsIdentity.RevalidateUser utiliza las credenciales almacenadas en memoria caché para que el usuario no tenga que iniciar sesión explícitamente. Si el servicio de autenticación no está disponible, aparece un mensaje de advertencia y la aplicación se queda sin conexión.

    Nota

    El método RevalidateUser se proporciona sólo por comodidad. Dado que no devuelve un valor, no puede indicar si se ha producido un error al volver a validar. Por ejemplo, se puede producir un error al volver a validar si las credenciales del usuario han cambiado en el servidor. En este caso, debería incluir código que valide a los usuarios explícitamente después de un error de la llamada al servicio. Para obtener más información, consulte la sección Tener acceso a la configuración web previa de este tutorial.

    Después de volver a validar, este código guarda cualquier cambio de la configuración web local llamando al método SaveSettings agregado previamente. A continuación, recupera los nuevos valores del servidor llamando al método Reload de la clase Settings del proyecto (a la que se obtiene acceso como Properties.Settings.Default en C# y My.Settings en Visual Basic).

    Private Sub workOfflineCheckBox_CheckedChanged( _
        ByVal sender As Object, ByVal e As EventArgs) _
        Handles workOfflineCheckBox.CheckedChanged
    
        ConnectivityStatus.IsOffline = workOfflineCheckBox.Checked
    
        If Not ConnectivityStatus.IsOffline Then
    
            Try
    
                ' Silently re-validate the user.
                CType(System.Threading.Thread.CurrentPrincipal.Identity,  _
                    ClientFormsIdentity).RevalidateUser()
    
                ' If any settings have been changed locally, save the new
                ' new values to the Web settings service.
                SaveSettings()
    
                ' If any settings have not been changed locally, check 
                ' the Web settings service for updates. 
                My.Settings.Reload()
    
            Catch ex As WebException
    
                MessageBox.Show( _
                    "Unable to access the authentication service. " & _
                    Environment.NewLine + "Staying in offline mode.", _
                    "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
                workOfflineCheckBox.Checked = True
    
            End Try
    
        End If
    
    End Sub
    
    private void workOfflineCheckBox_CheckedChanged(
        object sender, EventArgs e)
    {
        ConnectivityStatus.IsOffline = workOfflineCheckBox.Checked;
        if (!ConnectivityStatus.IsOffline)
        {
            try
            {
                // Silently re-validate the user.
                ((ClientFormsIdentity)
                    System.Threading.Thread.CurrentPrincipal.Identity)
                    .RevalidateUser();
    
                // If any settings have been changed locally, save the new
                // new values to the Web settings service.
                SaveSettings();
    
                // If any settings have not been changed locally, check 
                // the Web settings service for updates. 
                Properties.Settings.Default.Reload();
            }
            catch (WebException)
            {
                MessageBox.Show(
                    "Unable to access the authentication service. " +
                    Environment.NewLine + "Staying in offline mode.",
                    "Warning", MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
                workOfflineCheckBox.Checked = true;
            }
        }
    }
    
  7. Agregue el código siguiente al final del método Form1_Load para asegurarse de que la casilla muestra el estado de conexión actual.

    workOfflineCheckBox.Checked = ConnectivityStatus.IsOffline
    
    workOfflineCheckBox.Checked = ConnectivityStatus.IsOffline;
    

Esto completa la aplicación de ejemplo. Para probar la función sin conexión, ejecute la aplicación, inicie sesión como empleado o administrador y, a continuación, seleccione Trabajar sin conexión. Modifique el valor del cuadro de texto y, a continuación, cierre la aplicación. Reinicie la aplicación. Antes de iniciar sesión, haga clic con el botón secundario del mouse en el icono del Servidor de desarrollo de ASP.NET en el área de notificación de la barra de tareas y, a continuación, haga clic en Detener. A continuación, inicie sesión como lo haría normalmente. Podrá iniciar sesión incluso si el servidor no se está ejecutando. Modifique el valor del cuadro de texto, cierre la aplicación y reiníciela para ver el valor modificado.

Resumen

En este tutorial, obtuvo información sobre cómo habilitar y usar servicios de aplicaciones cliente en una aplicación de formularios Windows Forms. Después de configurar un servidor de prueba, agregó código a la aplicación para autenticar usuarios y recuperar funciones de usuario y la configuración de la aplicación del servidor. También obtuvo información sobre cómo habilitar el modo sin conexión para que la aplicación utilice una caché de datos local en lugar de los servicios remotos cuando la conectividad no esté disponible.

Pasos siguientes

En una aplicación real, tendrá acceso a datos de muchos usuarios desde un servidor remoto que es posible que no siempre esté disponible, o puede que se cierre sin previo aviso. Para hacer la aplicación más robusta, debe responder apropiadamente a situaciones en las que el servicio no está disponible. Este tutorial incluye bloques Try-Catch para detectar una excepción WebException y mostrar un mensaje de error cuando el servicio no esté disponible. En código de producción, puede administrar este caso pasando al modo sin conexión, saliendo de la aplicación o denegando el acceso a la funcionalidad concreta.

Para aumentar la seguridad de la aplicación, asegúrese de prueba completamente la aplicación y el servidor antes de la implementación.

Vea también

Tareas

Cómo: Configurar servicios de aplicaciones cliente

Tutorial: Usar servicios de aplicación ASP.NET

Conceptos

Información general sobre los servicios de aplicaciones cliente

Otros recursos

Servicios de aplicación cliente

Herramienta Administración de sitios Web ASP.NET

Crear y configurar la base de datos de servicios de la aplicación para SQL Server