2016-07-10 13 views
1

Ich schreibe Web API in C#, versuchen, REST-Konzepte folgen, d. H. Erfolgsantwort wird HttpStatus: 200, Validierungsfehler werden 433 und so weiter.Validierungsfehler von Web API werfen

Ich habe ExceptionFilter für die gesamte Anwendung in global.asax registriert.

Meine Frage hier ist, für Validierungsfehler wie während der Authentifizierung, wenn die Authentifizierung fehlgeschlagen ist, wie sollte die Nachricht zurück zum Client (es muss einen anderen Statuscode wie 433 oder 401 sein).

Ab jetzt werfe ich benutzerdefinierte Ausnahmen von der Business-Schicht. Ist es empfehlenswert, im Fehlerfall Ausnahmen auszulösen?

Es folgt der Code Beispiel:

Logger

public class ExceptionFilter : ExceptionFilterAttribute 
{ 
    public override void OnException(HttpActionExecutedContext context) 
    { 
     HttpResponseMessage response; 
     if (context.Exception is ExceptionBase) 
     { 
      response = context.Request.CreateResponse(HttpStatusCode.InternalServerError, 
       new ErrorDTO() { ErrorCode = (int)((ExceptionBase)context.Exception).ExceptionCode, Messages = ((ExceptionBase)context.Exception).Message }); 
     } 
     else { 
      response = context.Request.CreateResponse(HttpStatusCode.InternalServerError, 
       new ErrorDTO() { ErrorCode = (int)HttpStatusCode.InternalServerError, Messages = "Error occured at server." }); 
     } 
     context.Response = response; 
     base.OnException(context); 
     LogException(context); 
    } 

    private static void LogException(HttpActionExecutedContext context) 
    { 
     if (context.Exception != null) 
     { 
      Logger.Instance.LogError(context.ActionContext.ActionDescriptor.ActionName, context.Exception); 
     } 
    } 

    public override Task OnExceptionAsync(HttpActionExecutedContext context, CancellationToken cancellationToken) 
    { 
     return base.OnExceptionAsync(context, cancellationToken); 
    } 
} 

Geschäfts Schicht

public AuthorizationTokenDTO AuthenticateUser(UserDTO userDTO) 
{ 
    User userEntity = _userRepository.GetUserWithAssociatedRole(userDTO.UserName); 

    if (userEntity == null) 
     throw new BLException("User does not exists.", ExceptionCode.RestApiValidation); 

    ActiveDirectory activeDirectory = _activeDirectoryRepository.GetEntityById(ConfigurationSettings.GetConfigSetting<int>(ApplicationConstants.ActiveDirectoryId)); 

    if (activeDirectory == null) 
     throw new BLException("UserName or password is incorrect.", ExceptionCode.RestApiValidation); 

    using (var context = new PrincipalContext(ContextType.Domain)) 
    { 
     string password = EncryptionUtility.Decrypt(userDTO.Password, ConfigurationSettings.GetConfigSetting<string>(ApplicationConstants.PrivateKeyForRSAEncryption)); 

     if (!context.ValidateCredentials(userDTO.UserName, password)) 
      throw new BLException("UserName or password is incorrect.", ExceptionCode.RestApiValidation); 

     UserAccessTokenDTO accessToken = GenrateNewUserAccessToken(userEntity); 

     if (accessToken == null) 
      throw new BLException("Error occured while generating access token.", ExceptionCode.RestApiValidation); 

     return GetAuthorizationTokenDTO(userEntity, accessToken); 
    } 
} 

empfiehlt es Ausnahmen für solche Fälle zu werfen? Oder gibt es eine bessere Möglichkeit, Web-APIs zu schreiben?

Antwort

0

Der ExceptionFilter sollte sozusagen nur die "unbehandelten" Ausnahmen erfassen. Sie können diese Ausnahmen entweder in der BusinessLayer beibehalten und sie im Controller abfangen oder eine Art Objekt zurückgeben. Dann geben Sie diese Antworten mit dem entsprechenden HttpStatusCode vom Controler zurück.

Alternativ könnten Sie Ihre Antwort in etwas verpacken, das auch über HttpStatusCode (& Fehlermeldung) informiert.

+0

Vielen Dank für Ihre Antwort. Diese Dienste werden vom WPF-Client genutzt. und wenn ich ein Anfrage/Antwort-Modell verwende, um auf Rest-API zuzugreifen, dann wird Rest-API immer den http-Statuscode 200 zurückgeben, und wir werden am Ende viele if/else-Bedingungen innerhalb des Codes haben (Überprüfung, ob die Antwort Erfolg oder Misserfolg ist) . Wie ich das vorhabe, ist, diese http-Ausnahmen in WPF einzufangen und in der WPF-Anwendungsklasse diese Ausnahmen (http-Ausnahmen) zu erfassen und eine Nachricht an die aktive Ansicht (über Ereignisaggregator) zu senden, damit die Ansicht die Ausnahmen vom Rest behandelt api –

+0

Auf diese Weise schreiben wir nur Code für den Erfolg und Fehler, wo Code fehlschlagen muss, ohne den tatsächlichen Codefluss zu beeinträchtigen. d. h. Fehlerszenarien werden im Fehlerfluss behandelt, und echter Code ist nur um das gewünschte Geschäft besorgt. –