2017-07-12 3 views
2
で無効にModelBinder

HeyGuys.NetCore

私はクライアントからの要求を受信して​​、直接アクセスのために開いていない他のサービスにこれらの要求をリダイレクトWEBAPIプロジェクトに取り組んでいます。

デフォルトでは、.NetはJsonリクエストパラメータを自動的にシリアル化および逆シリアル化するため、適切なサービスを呼び出す前に再シリアル化する必要があります。同じ問題は、サービス応答を受信するときに発生します。私はそれをユーザーに返信する前に逆シリアル化する必要があります。さもなければ.Netフレームワークはそれをもう一度シリアル化し、 "Json of Json"という応答を返します。

私はthis answerを見つけましたが、.NetCoreでは動作しません。そこで、Jsonオブジェクトを読み込んで返すだけの独自のModelBinderを作成しようとしました。

class JsonUnformatterBinderProvider : Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinderProvider 
    { 
    public IModelBinder GetBinder(ModelBinderProviderContext context) 
    {  
     return new JsonUnformatterBinder(new SimpleTypeModelBinder(context.Metadata.ModelType));  
    } 
    } 

class JsonUnformatterBinder : IModelBinder 
{ 
    private readonly IModelBinder _fallbackBinder; 

    public JsonUnformatterBinder(IModelBinder fallbackBinder) 
    { 
     _fallbackBinder = fallbackBinder; 
    } 

    public Task BindModelAsync(ModelBindingContext bindingContext) 
    { 
     string currMethod = bindingContext.ActionContext.HttpContext.Request.Method; 

     if ("POST".Equals(currMethod) || "PUT".Equals(currMethod)) 
     { 
     string strData = new StreamReader(bindingContext.ActionContext.HttpContext.Request.Body).ReadToEnd(); 
     bindingContext.Result = ModelBindingResult.Success(strData); 
     return Task.CompletedTask; 
     } 

     return _fallbackBinder.BindModelAsync(bindingContext); 
    } 
} 

このコードは、それが私の最初の試みであり、それは私の目的のためによく働いていた、非常に簡単です。しかし、私はまだ2番目のサービスの回答を取ってユーザーに返すときに "Json of Json"という問題が発生します。

私は基本的にこれを克服するために何ができるのかわからないので、ここで何らかの回避策を歓迎します。

答えて

0

変更を加えずにリクエストをリダイレクトするだけであれば、入力ストリームから直接読み込んでインナーサービスに送信することができます。このようなアプローチを使用して、内部サービスからの応答を読み取ることもできます。

//1. Set empty parameter list in action then neither serializator nor model binder are not invoked. 
public async Task<ContentResult> ProxyAction(/*empty parameter list*/) 
{ 
    var newUrl = @"https://stackoverflow.com"; 
    var data = this.Request.Body; 

    using (var client = new HttpClient()) 
    { 
     //2. Read request body from input stream. 
     var reader = new StreamReader(data); 
     var json = reader.ReadToEnd(); 

     using (var content = new StringContent(json)) 
     { 
      //3. Set correct content type 
      content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(this.Request.ContentType); 

      //4. Post request to inner service 
      var response = await client.PostAsync(newUrl, content); 

      //5. Read response without deserialization 
      var innerResponse = await response.Content.ReadAsStringAsync(); 
      var contentType = response.Content.Headers.ContentType.ToString(); 
      var statusCode = response.StatusCode; 

      //6. Return inner response without serialization 
      var outerResponse = this.Content(innerResponse, contentType); 
      outerResponse.StatusCode = (int)statusCode; 
      return outerResponse; 
     } 
    } 
} 
関連する問題