次の方法で共有


クライアントでのエラー処理

ここでは、クライアントからデータを取得または変更する際に発生したエラーに応じて、一般的にエラーを処理して特定の手順を実行する方法について説明します。WCF RIA サービス では、データ操作のコールバック メソッドを指定し、そのコールバック メソッドでエラーをチェックすることで、エラーを処理します。エラーを処理する際には、コールバック メソッドを使用する必要があります。これは、データ操作の呼び出しが非同期であるため、例外は非同期的にスローされるからです。既定では、ドメイン操作のエラーに対して例外がスローされます。RIA Services には、エラーを処理し、フレームワークが例外をスローしないように指定する手段が用意されています。

データ読み込み時のエラー処理

クエリ メソッドからデータを読み込む場合、エラーを処理することも、エラーを無視することもできます。具体的には、次のオプションから選択できます。

  • コールバック メソッドのパラメーターを持つ Load メソッドを使用します。このコールバック メソッドでは、エラーを処理し、例外がスローされていないことを示す MarkErrorAsHandled メソッドを呼び出します。

  • throwOnError という名前の boolean パラメーターを持つ Load メソッドを使用します。クエリ エラーに対して例外をスローしないことを示すために Load メソッドを呼び出す場合は、throwOnErrorfalse に設定します。

  • コールバック メソッドのパラメーターまたは boolean パラメーターを持たない Load メソッドを使用します。クエリの実行時に発生したエラーは、未処理の例外になります。

クエリからデータを読み込み、読み込み操作によるエラーがないかをチェックするコールバック メソッドを指定する方法を次の例に示します。

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

データ送信時のエラー処理

データを送信するときに、Load メソッドと同様に、例外を無効にすることはできません。データの送信時に発生したエラーは、例外になります。具体的には、次のオプションから選択できます。

  • SubmitChanges メソッドを使用して、コールバック メソッドをパラメーターとして指定します。このコールバック メソッドでは、エラーを処理し、例外がスローされていないことを示す MarkErrorAsHandled メソッドを呼び出します。

  • SubmitChanges メソッドを使用します。データの送信時に発生したエラーは、未処理の例外になります。

エラーを処理するためのコールバック メソッドで SubmitChanges メソッドを呼び出す方法を次の例に示します。

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

呼び出し操作によるエラー処理

操作を呼び出すときは、データの送信時と同じオプションを使用できます。具体的には、次のオプションから選択できます。

  • 呼び出し操作を呼び出すときにコールバック メソッドを含めます。このコールバック メソッドでは、エラーを処理し、例外がスローされていないことを示す MarkErrorAsHandled メソッドを呼び出します。

  • コールバック メソッドを含めずに呼び出し操作を呼び出します。メソッドの呼び出し時に発生したエラーは、未処理の例外になります。

コールバック メソッドを含む呼び出し操作の例を次に示します。

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

認証サービスによるエラー処理

AuthenticationService クラスを使用すると、次のメソッドを呼び出すときにコールバック メソッドを指定できます。

コールバック メソッドでは、認証サービスからエラーを処理するためのコードを指定できます。次の例は、ログイン ボタンのイベント ハンドラーから Login メソッドを呼び出す方法を示しています。ログイン操作の結果に応答するコールバック メソッドが含まれています。

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