So stellen Sie fest, ob eine Ausnahme von einem bestimmten Typ ist


81

Ich habe einen Versuchscode:

try 
{
    ...
}
catch(Exception ex) 
{
    ModelState.AddModelError(
        "duplicateInvoiceNumberOrganisation", "The combination of organisation and invoice number must be unique");
}

Für diesen Code versuche ich, einen Datensatz in eine Datenbank einzufügen: Die Datenbank hat ihn so eingerichtet, dass die Datenbank nach Duplikaten sucht und einen Fehler zurückgibt, wenn Duplikate vorhanden sind. Wie Sie sehen, füge ich dem Modell derzeit denselben Fehler hinzu, unabhängig davon, welcher Fehler aufgetreten ist. Ich möchte, dass es geändert wird, damit dieser Fehler nur dann zum Modell hinzugefügt wird, wenn er durch den von der dba eingerichteten doppelten Fehler verursacht wurde.

Unten ist der Fehler, den ich abfangen möchte. Beachten Sie, dass es sich um die innere Ausnahme handelt. Kann mir jemand sagen, wie ich diesen gezielt fangen soll?

Geben Sie hier die Bildbeschreibung ein


1
Siehe Davides Antwort. Im Allgemeinen ist das Fangen Exceptionkeine bewährte Methode. Sie sollten so spezifisch wie möglich sein und alles, was Sie nicht handhaben können, an den Benutzer / das Framework weitergeben.
Ryan

1
Überprüfen Sie heraus diese Antwort: stackoverflow.com/questions/3967140/…
Rob Packwood

Antworten:


141

Fügen Sie vor Ihrem aktuellen Fang Folgendes hinzu:

catch(DbUpdateException ex)
{
  if(ex.InnerException is UpdateException)
  {
    // do what you want with ex.InnerException...
  }
}

Ab C # 6 können Sie Folgendes tun:

catch(DbUpdateException ex) when (ex.InnerException is UpdateException)
{
    // do what you want with ex.InnerException...
}

3
Gibt es eine Catch-Syntax "wenn nicht"?
Conterio

4
@conteriocatch(DbUpdateException ex) when (!(ex.InnerException is UpdateException))
Tom

15

Durch System.Threading.ThreadAbortExceptionIhre Ausnahme ersetzen .

try
{
    //assume ThreadAbortException occurs here
}
catch (Exception ex)
{
    if (ex.GetType().IsAssignableFrom(typeof(System.Threading.ThreadAbortException)))
    {
         //what you want to do when ThreadAbortException occurs         
    }
    else
    {
         //do when other exceptions occur
    }
}

3

Um den Namen der Ausnahme zu erhalten, können Sie verwenden

    catch (Exception exc){
       if (exc.GetType().FullName == "Your_Exception") 
       {
          // The same can be user for InnerExceptions
          // exc.InnerException.GetType().FullName
       }
   }

2
Der Vergleich des Ausnahmetyps nach Zeichenfolge ist gefährlich. Ein unglücklicher Rechtschreibfehler macht die Ausnahmebehandlung zu einem Albtraum!
Tejas Pendse

Einverstanden. Vergleichen Sie den Typ mit einem Typ. exc.GetType () == typeof (YourException)
Lee Oades

2

Nicht genug Vertreter, um einen Kommentar abzugeben. Als Antwort auf die Frage @conterio (in der Antwort von @Davide Piras):

Gibt es eine Catch-Syntax "wenn nicht"?

Es gibt.

catch (Exception e) when (!(e is ArgumentException)) { }

-3

Sie können sich die SQLException-Klasse ansehen und nach dem Inhalt der Ausnahmemeldung suchen, wenn sie das enthält, was Sie jetzt in Ihrer inneren Ausnahme sehen. So etwas:

try
{
    //your code here
}
catch (SQLException ex)
{
    if (ex.Message.Contains("Cannot insert duplicate key in obj...."))
    {
        //your code here
    }
}

1
Ich bezweifle, dass SqlException direkt ausgelöst wird, aber nur als innere Ausnahme. Außerdem ist es wahrscheinlich besser, die Fehlernummer zu überprüfen, als sie mit dem Nachrichtentext zu vergleichen.
John Saunders

Ja, Sie können auch die Fehlernummer überprüfen. Danke für den Kommentar.
Ann BG

Wie prüft man gegen die Fehlernummer? Ich bin mir nicht mal sicher, wie die Nummer lautet, da es sich um einen wirklich spezifischen Fehler handelt.
AnonyMouse
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.