クライアントでのエラー処理
ここでは、クライアントからデータを取得または変更する際に発生したエラーに応じて、一般的にエラーを処理して特定の手順を実行する方法について説明します。WCF RIA サービス では、データ操作のコールバック メソッドを指定し、そのコールバック メソッドでエラーをチェックすることで、エラーを処理します。エラーを処理する際には、コールバック メソッドを使用する必要があります。これは、データ操作の呼び出しが非同期であるため、例外は非同期的にスローされるからです。既定では、ドメイン操作のエラーに対して例外がスローされます。RIA Services には、エラーを処理し、フレームワークが例外をスローしないように指定する手段が用意されています。
データ読み込み時のエラー処理
クエリ メソッドからデータを読み込む場合、エラーを処理することも、エラーを無視することもできます。具体的には、次のオプションから選択できます。
コールバック メソッドのパラメーターを持つ Load メソッドを使用します。このコールバック メソッドでは、エラーを処理し、例外がスローされていないことを示す MarkErrorAsHandled メソッドを呼び出します。
throwOnError という名前の boolean パラメーターを持つ Load メソッドを使用します。クエリ エラーに対して例外をスローしないことを示すために Load メソッドを呼び出す場合は、throwOnError を false に設定します。
コールバック メソッドのパラメーターまたは 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;
}