2017-06-21 10 views
0

従来のルーティングを使用している場合、DelegatingHandlerを使用してSendAsyncメソッドをオーバーライドしてレスポンスラッパーを作成できます。属性ルーティングのレスポンスラッパーの作成方法は?

 DelegatingHandler[] handler = new DelegatingHandler[] { 
      new ResponseWrapper() 
     }; 
     var routeHandler = HttpClientFactory.CreatePipeline(new HttpControllerDispatcher(config), handler); 

     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}", 
      defaults: null, 
      constraints: null, 
      handler: routeHandler 
     ); 

ただし、この方法は属性ルーティングに依存するメソッドでは機能しません。私の場合は、コンベンションベースのルーティングはすべてのシナリオで機能せず、routeHandlerは属性ベースのルートには適用されません。

すべての属性ベースのルート応答に応答ラッパーを適用するにはどうすればよいですか?

+1

すべてのシナリオでは、コンベンショナルベースのルーティングは機能しませんか?属性ルーティングがコンベンションベースのルーティング機能のサブセットであることは、どのように可能ですか? – NightOwl888

+1

あなたの場合、routeHandlerはコントローラアクションラッパーです。なぜ、同じではあるが、はるかに簡単で、どのルートメカニズムでも動作するActionFilterを使用しないでください。 –

+0

がUserController NightOwl888 @おそらく、私が操作 API /ユーザー API /ユーザー/ {userIdを} API /ユーザー/ {userIdを} /入学 API /ユーザー/ {userIdを} /入学/ {enrollmentId} をGET無知なだけです...上記の規則をベースにしたルーティングを使用して達成する方法はありますか?私は複数のコンベンションを作成しても構いませんが、各コントローラのためのコンベンションベースのルートが必要な場合は、属性ルーティングが望ましいと思われます。 – Zoop

答えて

0

すべてのリクエストに適用されるグローバルメッセージハンドラを追加できました。

config.MessageHandlers.Add(new ResponseWrapper()); 

私はswaggerを使用しているので、swaggerリクエストURIも無視しなければなりませんでした。 ResponseWrapperクラスのコードは、誰かを助けるイベントです。私はそれを取り戻す機会がありませんでしたので、いくつかの改善が確実となります。

public class ResponseWrapper : DelegatingHandler 
    { 
     protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
     { 
      var response = await base.SendAsync(request, cancellationToken); 

      if (request.RequestUri.ToString().Contains("swagger")) 
      { 
       return response; 
      } 

      return BuildApiResponse(request, response); 
     } 

     private static HttpResponseMessage BuildApiResponse(HttpRequestMessage request, HttpResponseMessage response) 
     { 
      object content = null; 
      string errorMessage = null; 
      response.TryGetContentValue(out content); 

      if (!response.IsSuccessStatusCode) 
      { 
       content = null; 
       var error = new HttpError(response.Content.ReadAsStringAsync().Result);    
       var data = (JObject)JsonConvert.DeserializeObject(error.Message); 
       errorMessage = data["message"].Value<string>(); 

       if (!string.IsNullOrEmpty(error.ExceptionMessage) && string.IsNullOrEmpty(errorMessage)) 
       { 
        errorMessage = error.ExceptionMessage; 
       } 
      } 

      var newResponse = request.CreateResponse(response.StatusCode, new ApiResponse(response.StatusCode, content, errorMessage)); 

      foreach (var header in response.Headers) 
      { 
       newResponse.Headers.Add(header.Key, header.Value); 
      } 

      return newResponse; 
     } 
    } 
関連する問題