2016-07-18 3 views
3

일부 사용자 지정 토큰을 기반으로 일부 인증을 수행하는 OWIN 미들웨어 클래스가 있습니다. 모두 잘 작동합니다. 그러나 유용한 오류 응답을 클라이언트에 반환하고 싶습니다. 내 추론은 클라이언트가 'application/json'응답을 요청하고 serialize 객체를 기대할 경우 401 상태 코드 인 경우에도 가져와야한다는 것입니다. 내 미들웨어의 호출 섹션 여기OWIN 미들웨어에서 예외 반환

입니다 :

public override async Task Invoke(IOwinContext context) 
    { 
     try 
     { 
      this.DoAuthorization(context); 
      await this.Next.Invoke(context); 
     } 
     catch (UnauthorizedAccessException ex) 
     { 
      this.GenerateErrorResult(context, HttpStatusCode.Unauthorized, this.ExceptionToString(ex)); 
     } 
     catch (Exception ex) 
     { 
      this.GenerateErrorResult(context, HttpStatusCode.InternalServerError, this.ExceptionToString(ex)); 
     } 
    } 

    private void GenerateErrorResult(IOwinContext context, HttpStatusCode code, string errorMessage) 
    { 
     var result = new Result { Status = Result.EStatus.Error, ErrorText = errorMessage }; 

     context.Response.StatusCode = (int)code; 
     context.Response.ContentType = "application/json"; 
     context.Response.Write(JsonConvert.SerializeObject(result)); 
    } 

이 모두 잘하지만 작동합니다

  • 이가 '올바른'방법은? 클라이언트가 분명히 웹 API는

을 지원하는 꽤 할 수있는 '응용 프로그램/XML'을 요구하는 경우 (제 경우 '결과') 사용자 정의 응답 객체를 반환 할 수있는 더 나은 방법이 있나요 어떤

  • 그 클라이언트가 기대하는대로 직렬화됩니까?

  • +0

    이 답변이 도움이 될 수 있습니다 http://stackoverflow.com/questions/30918649/unhandled-exception-global-handler-for -owin-katana –

    +0

    유용한 트릭처럼 보입니다. 그러나 IOwinContext를 사용하여 자동으로 응답 객체를 직렬화하는 방법을 알지 못합니다 (JsonConvert 등으로 수동 직렬 변환을 수행하지 않고도). 컨트롤러는 프레임 워크가 json 또는 xml로 직렬화 할 객체를 반환하면됩니다. 왜 미들웨어는 이것을 할 수 없습니까? – Paul

    +0

    나는 owin middleware가 webapi 범위를 벗어 났기 때문에 직접 serialize해야한다고 생각한다. –

    답변

    2

    음이 추가 OwinMiddleware 먼저 삽입하여, 작동하는 것 같다하기 :

    public override async Task Invoke(IOwinContext context) 
        { 
         try 
         { 
          await Next.Invoke(context); 
         } 
         catch (UnauthorizedAccessException ex) 
         { 
          var result = new Result { Status = Result.EStatus.Error, ErrorText = ExceptionToString(ex) }; 
    
          this.ReturnFormattedResult(result, HttpStatusCode.Unauthorized, context); 
         } 
         catch (Exception ex) 
         { 
          var result = new Result { Status = Result.EStatus.Error, ErrorText = ExceptionToString(ex) }; 
    
          this.ReturnFormattedResult(result, HttpStatusCode.InternalServerError, context); 
         } 
        } 
    
        private void ReturnFormattedResult(Result result, HttpStatusCode code, IOwinContext context) 
        { 
         // what should our response be? 
         var mediaType = context.Request.MediaType ?? context.Request.ContentType; 
    
         // use the accept header (unless it is empty or '*/*' in which case use the content-type 
         if (!string.IsNullOrEmpty(context.Request.Accept) && !context.Request.Accept.Contains("*/*")) 
         { 
          mediaType = context.Request.Accept; 
         } 
    
         // find a formatter for this media type, if no match then use the first one 
         var formatter = this.config.Formatters.FindWriter(typeof(Result), new MediaTypeHeaderValue(mediaType)); 
         if (formatter == null) 
         { 
          formatter = this.config.Formatters.First(); 
          mediaType = formatter.SupportedMediaTypes.First().MediaType; 
         } 
    
         context.Response.StatusCode = (int)code; 
         context.Response.ContentType = mediaType; 
         formatter.WriteToStreamAsync(typeof(Result), result, context.Response.Body, null, null).Wait(); 
        }