10

私はMVCをかなり新しくしていますので、私の問題の解決策があることを願っています。 MVC Web APIと通信するために第三者のハードウェアを使用しています。ハードウェアはJSON形式でリクエストを送信しますが、これを完全に細かく抽出できます。しかし、私は競合のために、これらの要求のパラメータをバインディングモデルオブジェクトに変更する処理中です。MVC POSTリクエストのコンテンツヘッダーをオーバーライドします。

E.G.

 Public Function POSTRequest(Action As String, Stamp As String) As HttpResponseMessage 
      ... 
     End Function 

     Public Function POSTRequest(Action As String, OpStamp As String) As HttpResponseMessage 
      ... 
     End Function 

したがって、これらの2つの方法は同じコーリングカードを共有するため、両方が同じコントローラに存在することはできません。

このため、これらのパラメータを格納するモデルバインディングオブジェクトを作成しました。問題は、私がこれを行うと、Web APIは "Content-Type"が定義されていないという要求について苦情を言います。それを見ると、サードパーティのハードウェアは要求に応じてコンテンツタイプを送信しません。ネットを見ると、ブラウザでコンテンツタイプ「アプリケーション/オクテットストリーム」として処理されることがわかりました。これは、これをパラメータとして定義されたバインディングオブジェクトに変換することはできません。

私たちはサードパーティのハードウェアを制御できないため、これらの要求のコンテンツタイプを定義することはできません。だから、私の質問は、これらの要求を傍受し、コンテンツタイプを追加する方法があるかどうかです。またはこれを回避する別の方法ですか?

答えて

5

私はあなたがActionFilterAttributeを使用できると思います。ドキュメント:Creating Custom Action Filtersを参照してください。

あなたのケースでは、私のVBスキルが古くなっているので、次のサンプルを使用することができます。これは、任意の要求Content-Typeヘッダーを、アプリケーション/ json値で上書きします。 HttpContentのすべての種類をサポートするために、この機能を強化する必要がある場合があります(たとえば、これをMultiPart要求に使用する必要はありません)。

public class UpdateRequestAttribute: ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     actionContext.Request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); 
     base.OnActionExecuting(actionContext); 
    } 
} 

は、その後、例えば、あなたのコントローラクラスにこの属性を追加します。

[UpdateRequest] 
public class HomeController : ApiController 
{ 
    //[...] 
} 

この場合、ホームコントローラへのすべての要求が彼らのContent-Typeをオーバーライドしています。


また、あなたはまた、非常に早い段階パイプラインで呼ばれ、特定のコントローラに限定されるものではないカスタムHTTP Message Handlersを書くことができます。要求がサーバーによってどのように処理されるかを理解するには、次の図を参照してください。例えば

ASP.net Server Side handlers

それが現在空の場合、このメッセージハンドラはアプリケーション/ JSONに要求Content-Typeを設定します。

public class CustomMessageHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     if (request.Content.Headers.ContentType == null) 
     { 
      request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); 
     } 
     return base.SendAsync(request, cancellationToken); 
    } 
} 

最後に、ここではパイプラインにあなたのメッセージハンドラを追加するためにWebApiConfigを更新する方法である:

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     config.MessageHandlers.Add(new CustomMessageHandler()); 

     // Other configuration not shown... 

    } 
} 
1

あなたはルートattribute.Thisを定義することにより、同じコントローラでこれらのメソッドの両方を持つことができますModel Bindingの属性を避けることができます。

[Route("Request1")] 
Public Function POSTRequest(Action As String, Stamp As String) As HttpResponseMessage 
      ... 
     End Function 
     [Route("Request2")] 
     Public Function POSTRequest(Action As String, OpStamp As String) As HttpResponseMessage 
      ... 
     End Function 

あなたwebapiconfig.vbファイルに

Public Module WebApiConfig 
    Public Sub Register(ByVal config As HttpConfiguration) 
     ' Web API configuration and services 

     ' Web API routes 
     config.MapHttpAttributeRoutes() 

     config.Routes.MapHttpRoute(
      name:="DefaultApi", 
      routeTemplate:="api/{controller}/{id}", 
      defaults:=New With {.id = RouteParameter.Optional} 
     ) 
    End Sub 
End Module 
をMapHttpAttributeRoutesを追加することにより、ルーティング属性を有効にすることを忘れないでください。
関連する問題