Compartir a través de


Control de errores en el cliente

En este tema se describe cómo se suelen controlar errores y dar ciertos pasos en respuesta a los errores que se recuperan o modifican los datos de un cliente. Con WCF RIA Services, los errores se controlan proporcionando un método de devolución de llamada para las operaciones de datos y comprobando los errores en ese método de devolución de llamada. El uso de métodos de devolución de llamada es necesario porque las llamadas a las operaciones de datos son asincrónicas y, por lo tanto, las excepciones se producen de forma asincrónica. De forma predeterminada, se produce una excepción para los errores en operaciones de dominio. RIA Services proporciona fórmulas para controlar los errores y especificar que el marco no produzca una excepción.

Control de errores al cargar datos

Cuando se cargan datos de un método de consulta, se puede controlar el error o elegir que se omita el error. Concretamente, puede elegir entre las opciones siguientes:

  • Utilizar un método Load que tenga un parámetro para un método de devolución de llamada. En el método de devolución de llamada, controle el error y llame al método MarkErrorAsHandled para indicar que no se produzca la excepción.

  • Utilizar un método Load que tenga un parámetro boolean denominado throwOnError. Establezca throwOnError en false cuando llame al método Load para indicar que no desea que se produzca ninguna excepción para los errores de la consulta.

  • Utilizar el método Load sin un parámetro para un método de devolución de llamada o un parámetro boolean. Los errores que se produzcan al ejecutar la consulta darán lugar a una excepción no controlada.

En el ejemplo siguiente se muestra cómo cargar los datos de una consulta y especificar un método de devolución de llamada que compruebe los errores de la operación de carga.

Private _customerContext As New CustomerDomainContext

Public Sub New()
    InitializeComponent()

    Dim loadOp = Me._customerContext.Load(Me._customerContext.GetCustomersQuery(), AddressOf OnLoadCompleted, Nothing)
    CustomerGrid.ItemsSource = loadOp.Entities
End Sub

Private Sub OnLoadCompleted(ByVal lo As LoadOperation(Of Customer))
    If (lo.HasError) Then
        MessageBox.Show(String.Format("Retrieving data failed: {0}", lo.Error.Message))
        lo.MarkErrorAsHandled()
    End If
End Sub
private CustomerDomainContext _customerContext = new CustomerDomainContext();

public MainPage()
{
    InitializeComponent();

    LoadOperation<Customer> loadOp = this._customerContext.Load(this._customerContext.GetCustomersQuery(), OnLoadCompleted, null);
    CustomerGrid.ItemsSource = loadOp.Entities;
}

private void OnLoadCompleted(LoadOperation<Customer> lo)
{
    if (lo.HasError)
    {
        MessageBox.Show(string.Format("Retrieving data failed: {0}", lo.Error.Message));
        lo.MarkErrorAsHandled();
    }
}

Control de errores al enviar datos

Cuando se envían datos, no se puede elegir desactivar las excepciones; sí se puede con el método Load. Los errores que se produzcan al enviar los datos darán lugar a una excepción. Concretamente, puede elegir entre las opciones siguientes:

  • Utilizar el método SubmitChanges y proporcionar un método de devolución de llamada como parámetro. En el método de devolución de llamada, controle el error y llame al método MarkErrorAsHandled para indicar que no se produzca la excepción.

  • Utilizar el método SubmitChanges. Los errores que se produzcan al enviar los datos darán lugar a una excepción no controlada.

En el ejemplo siguiente se muestra cómo llamar al método SubmitChanges con un método de devolución de llamada para controlar los errores.

Private Sub SaveButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    _customerContext.SubmitChanges(AddressOf OnSubmitCompleted, Nothing)
End Sub

Private Sub RejectButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    _customerContext.RejectChanges()
    CheckChanges()
End Sub

Private Sub CustomerGrid_RowEditEnded(ByVal sender As System.Object, ByVal e As System.Windows.Controls.DataGridRowEditEndedEventArgs)
    CheckChanges()
End Sub

Private Sub CheckChanges()
    Dim changeSet = _customerContext.EntityContainer.GetChanges()
    ChangeText.Text = changeSet.ToString()

    Dim hasChanges = _customerContext.HasChanges
    SaveButton.IsEnabled = hasChanges
    RejectButton.IsEnabled = hasChanges
End Sub

Private Sub OnSubmitCompleted(ByVal so As SubmitOperation)
    If (so.HasError) Then
        MessageBox.Show(String.Format("Submit Failed: {0}", so.Error.Message))
        so.MarkErrorAsHandled()
    End If
    CheckChanges()
End Sub
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
    _customerContext.SubmitChanges(OnSubmitCompleted, null);
}

private void RejectButton_Click(object sender, RoutedEventArgs e)
{
    _customerContext.RejectChanges();
    CheckChanges();
}

private void CustomerGrid_RowEditEnded(object sender, DataGridRowEditEndedEventArgs e)
{
    CheckChanges();
}

private void CheckChanges()
{
    EntityChangeSet changeSet = _customerContext.EntityContainer.GetChanges();
    ChangeText.Text = changeSet.ToString();

    bool hasChanges = _customerContext.HasChanges;
    SaveButton.IsEnabled = hasChanges;
    RejectButton.IsEnabled = hasChanges;
}

private void OnSubmitCompleted(SubmitOperation so)
{
    if (so.HasError)
    {
        MessageBox.Show(string.Format("Submit Failed: {0}", so.Error.Message));
        so.MarkErrorAsHandled();
    }
    CheckChanges();
}

Control de errores con operaciones de invocación

Cuando se invoca una operación, se tienen las mismas opciones disponibles que cuando se envían datos. Concretamente, puede elegir entre las opciones siguientes:

  • Incluir un método de devolución de llamada al llamar a la operación de invocación. En el método de devolución de llamada, controle el error y llame al método MarkErrorAsHandled para indicar que no se produzca la excepción.

  • Llamar a la operación de invocación sin incluir un método de devolución de llamada. Los errores que se produzcan al invocar el método darán lugar a una excepción no controlada.

En el ejemplo siguiente se muestra una operación de invocación con un método de devolución de llamada.

Dim invokeOp As InvokeOperation(Of Integer)
invokeOp = customerContext.GetLocalTemperature(selectedPostalCode, AddressOf OnInvokeCompleted, Nothing)

Private Sub OnInvokeCompleted(ByVal invOp As InvokeOperation(Of Integer))
  If (invOp.HasError) Then
    MessageBox.Show(String.Format("Method Failed: {0}", invOp.Error.Message))
    invOp.MarkErrorAsHandled()
  Else
    result = invOp.Value
  End If
End Sub
InvokeOperation<int> invokeOp = customerContext.GetLocalTemperature(selectedPostalCode, OnInvokeCompleted, null);

private void OnInvokeCompleted(InvokeOperation<int> invOp)
{
  if (invOp.HasError)
  {
    MessageBox.Show(string.Format("Method Failed: {0}", invOp.Error.Message));
    invOp.MarkErrorAsHandled();
  }
  else
  {
    result = invokeOp.Value;
  }
}

Control de errores con servicio de autenticación

La clase AuthenticationService permite proporcionar un método de devolución de llamada cuando se llama a los métodos siguientes:

En el método de devolución de llamada, puede proporcionar código para controlar los errores desde el servicio de autenticación. En el ejemplo siguiente se muestra cómo llamar al método Login desde un controlador de eventos para obtener un botón de inicio de sesión. Se incluye un método de devolución de llamada para responder a los resultados de la operación de inicio de sesión.

Private Sub LoginButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim lp As LoginParameters = New LoginParameters(UserName.Text, Password.Password)
    WebContext.Current.Authentication.Login(lp, AddressOf Me.LoginOperation_Completed, Nothing)
    LoginButton.IsEnabled = False
    LoginResult.Text = ""
End Sub

Private Sub LoginOperation_Completed(ByVal lo As LoginOperation)
    If (lo.HasError) Then
        LoginResult.Text = lo.Error.Message
        LoginResult.Visibility = System.Windows.Visibility.Visible
        lo.MarkErrorAsHandled()
    ElseIf (lo.LoginSuccess = False) Then
        LoginResult.Text = "Login failed. Please check user name and password."
        LoginResult.Visibility = System.Windows.Visibility.Visible
    ElseIf (lo.LoginSuccess = True) Then
        SetControlVisibility(True)
    End If
    LoginButton.IsEnabled = True
End Sub
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
    LoginParameters lp = new LoginParameters(UserName.Text, Password.Password);
    WebContext.Current.Authentication.Login(lp, this.LoginOperation_Completed, null);
    LoginButton.IsEnabled = false;
    LoginResult.Text = "";
}

private void LoginOperation_Completed(LoginOperation lo)
{
    if (lo.HasError)
    {
        LoginResult.Text = lo.Error.Message;
        LoginResult.Visibility = System.Windows.Visibility.Visible;
        lo.MarkErrorAsHandled();
    }
    else if (lo.LoginSuccess == false)
    {
        LoginResult.Text = "Login failed. Please check user name and password.";
        LoginResult.Visibility = System.Windows.Visibility.Visible;
    }
    else if (lo.LoginSuccess == true)
    {
        SetControlVisibility(true);
    }
    LoginButton.IsEnabled = true;
}