2016-07-18 18 views
3

OWINミドルウェアクラスを使用して、カスタムトークンに基づいていくつかの認証を行うことができます。すべて正常に動作します。しかし、私はクライアントに有用なエラー応答を返したいと思います。私の推論は、クライアントが 'application/json'レスポンスを要求していて、シリアライズするオブジェクトを期待している場合、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ミドルウェアがwebapiスコープ外にあるので、自分でシリアル化する必要があると思います。 –

    答えて

    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(); 
        } 
    
    関連する問題