Share via


用戶端上的錯誤處理

本主題將說明您通常要如何處理錯誤,並採取某些步驟來回應從用戶端擷取或修改資料的錯誤。透過 WCF RIA Services,您可以為資料作業提供回呼方法,並檢查該回呼方法中的錯誤,藉以處理錯誤。使用回呼方法是必要的,因為對資料作業的呼叫是非同步,因此系統會以非同步方式擲回任何例外狀況。根據預設,如果網域作業發生任何錯誤,就會擲回例外狀況。RIA Services 可讓您以數種方式處理錯誤並指定架構不擲回例外狀況。

載入資料時的錯誤處理

從查詢方法載入資料時,您可以處理錯誤或選擇忽略錯誤。特別是,您可以從下列選項中選擇:

  • 使用 Load 方法,它有回呼方法的參數。在回呼方法中,處理錯誤並呼叫 MarkErrorAsHandled 方法,表示不擲回例外狀況。

  • 使用 Load 方法,它有名為 throwOnErrorboolean 參數。呼叫 Load 方法時將 throwOnError 設為 false,表示不想針對查詢錯誤擲回例外狀況。

  • 使用 Load 方法,它沒有回呼方法的參數,也沒有 boolean 參數。執行查詢時發生任何錯誤會造成未處理的例外狀況。

下列範例示範如何從查詢載入資料並指定回呼方法檢查載入作業的錯誤。

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