16

既存のWeb API 2サービスがあり、カスタムオブジェクトを別のパラメータとして使用する方法の1つを変更する必要があります。 URLから来る文字列。カスタムオブジェクトをパラメータとして追加した後、.NETウィンドウアプリケーションからサービスを呼び出すときに415のサポートされていないメディアタイプのエラーが表示されるようになりました。興味深いことに、私は正常にjavascriptとjquery ajaxメソッドを使用してこのメ​​ソッドを呼び出すことができます。Web API 2エンドポイントを呼び出すときにHTTP 415がサポートされていないメディアタイプのエラーが発生しました

ウェブAPI 2サービスメソッドは次のようになります。

<HttpPost> 
<HttpGet> 
<Route("{view}")> 
Public Function GetResultsWithView(view As String, pPaging As Paging) As HttpResponseMessage 
    Dim resp As New HttpResponseMessage 
    Dim lstrFetchXml As String = String.Empty 
    Dim lstrResults As String = String.Empty 

    Try 
     '... do some work here to generate xml string for the response 
     '// write xml results to response 
     resp.Content = New StringContent(lstrResults) 
     resp.Content.Headers.ContentType.MediaType = "text/xml" 
     resp.Headers.Add("Status-Message", "Query executed successfully") 
     resp.StatusCode = HttpStatusCode.OK 
    Catch ex As Exception 
     resp.StatusCode = HttpStatusCode.InternalServerError 
     resp.Headers.Add("Status-Message", String.Format("Error while retrieving results from view {0}: {1}", view, ex.Message)) 
    End Try 
    Return resp 
End Function 

Pagingオブジェクトはオプションであるため、この方法はPOSTGETの両方を可能にします。 GETリクエストでこのメソッドを呼び出すと、それは機能します。

そしてサービスを呼び出す簡単な.NETクライアントコードは次のようになります。

Dim uri As String = BASE_URI + "fetch/someview" 
Dim resp As HttpWebResponse 
Dim sr As StreamReader 
Dim lstrResponse As String 
Dim reqStream As Stream 
Dim bytData As Byte() 
Dim req As HttpWebRequest = WebRequest.Create(uri) 
Dim lstrPagingJSON As String 
Dim lPaging As New Paging 
Try 
    lPaging.Page = 1 
    lPaging.Count = 100 
    lPaging.PagingCookie = "" 
    req.Method = "POST" 
    lstrPagingJSON = JsonSerializer(Of Paging)(lPaging) 
    bytData = Encoding.UTF8.GetBytes(lstrPagingJSON) 
    req.ContentLength = bytData.Length 
    reqStream = req.GetRequestStream() 
    reqStream.Write(bytData, 0, bytData.Length) 
    reqStream.Close() 
    req.ContentType = "application/json" 

    resp = req.GetResponse() 

    sr = New StreamReader(resp.GetResponseStream, Encoding.UTF8) 
    lstrResponse = sr.ReadToEnd 
    '// do something with the response here 
Catch exweb As WebException 
    txtOutput.AppendText("Error during request: " + exweb.Message) 
Catch ex As Exception 
    txtOutput.AppendText(String.Format("General error during request to {0}: {1}", uri, ex.Message)) 
End Try 

.NETクライアントが4.5フレームワーク上で実行され、サービスが4.5.2フレームワーク上にあります。エラーはresp = req.GetResponse()行でスローされます。私はすでに試したいくつかの点:

  • をクライアントには、serviceメソッドに "アプリケーション/ XML" へreq.Accept値または "text/xmlで"
  • を設定し、ライン `resp.Contentを削除しました。 Headers.ContentType.MediaType =「text/xmlで」
  • いくつかの静的なJSONとXMLレスポンスのコンテンツを置き換える、リクエストにJSONに送信し、応答に戻ってXMLを取得してすべての問題を排除しようとした

これまでのところ、私は何を試しても同じ415エラー応答。私はジャバスクリプトから呼び出されたときに、この作品に述べた

は、ここで働いている私のAJAX呼び出しです:サービス側で

$.ajax({ 
    headers: {}, 
    url: "api/fetch/someview", 
    type: "POST", 
    data: "{Count:100,Page:1,PagingCookie:\"\"}", 
    contentType: "application/json; charset=utf-8", 
    dataType: "xml", 
    success: function (data) { 
     alert("call succeeded"); 
    }, 
    failure: function (response) { 
     alert("call failed"); 
    } 
}); 

は、ルートの設定や他の何かで起こって派手なものは何もありません、それはかなりですすべてのすぐに使用できるWeb API 2.ルーティングが機能していること、コールがメソッドに正しくルーティングされていること、予期せぬうちに別の場所に移動していないことを知っています。どんな助けでも大歓迎です!

--- --- UPDATE
私は私のようにカスタムオブジェクトを受け取り、単一の方法でコントローラを作成し、既存のサービスとの任意の潜在的な問題を排除するために、完全に新しいWeb APIサービスを作成しようとしましたパラメータ。私はそれから.NETクライアントから呼び出してみましたが、同じエラーが発生しました。私もHttpWebRequestの代わりにWebClientを使ってみましたが、同じエラーが出ます。これは以前はWeb API(Web API 2以前)で私のために働いていたものです。

--- --- UPDATE
また、私はPOSTで私の複雑なオブジェクトのパラメータは、現在ヌルに来ていることを呼び出すときに、ウェブAPI 1を使用して、新しいWebアプリケーションを作成してみました。私はWeb API 1を実行している別のWebサービスを持っていて、複雑なオブジェクトでもそれを正常に呼び出すことができることを確認しました。私の問題が何であれ、それはJSONがクライアントとサーバーの間を通過する何かのようです。私はそれを有効にしてJSONをチェックし、オブジェクト定義もクライアントとサーバーの間で完全に一致しているので、JSONはサーバーによって解析できるはずです。

+0

どこも必要でなかった。 – kmarsh

答えて

35

はこの問題に数日のために壁に頭を強打した後
を解決し、それが問題のように探していたことは、クライアントとサーバーの間でコンテンツタイプのネゴシエーションとは何かを持っていました。

Fiddler capture of http request from client app

は何明らかに欠けていることにもかかわらず、Content-Typeヘッダがあります:シオマネキで撮影して、私はクライアントアプリケーションからの要求の詳細を確認するためにバイオリンを使用してその深く掘って、ここで生要求のスクリーンショットです私は元の投稿のコードサンプルに見られるように設定していました。 Content-Typeが設定されていたにもかかわらず決して来なかったことが奇妙だと思ったので、別のWeb APIサービスを呼び出す別の(作業中の)コードをもう一度見てみましたが、唯一の違いはreq.ContentTypeプロパティその場合はリクエスト本体に書き込む前に実行してください。私はこの新しいコードに変更を加えました。それが実現しました。Content-Typeが表示されていて、Webサービスから期待される成功応答が得られました。私の.NETクライアントからの新しいコードは次のようになります。それはすべてだったのです

req.Method = "POST" 
req.ContentType = "application/json" 
lstrPagingJSON = JsonSerializer(Of Paging)(lPaging) 
bytData = Encoding.UTF8.GetBytes(lstrPagingJSON) 
req.ContentLength = bytData.Length 
reqStream = req.GetRequestStream() 
reqStream.Write(bytData, 0, bytData.Length) 
reqStream.Close() 
'// Content-Type was being set here, causing the problem 
'req.ContentType = "application/json" 

ContentTypeプロパティはちょうど

が、私はこの動作があるためであると考えてリクエストボディに書き込む前に設定する必要がコンテンツが本体に書き込まれた後、呼び出されているサービスエンドポイントにストリーミングされ、その要求に関連するその他の属性をそれ以前に設定する必要があります。私が間違っている場合や詳細が必要な場合は、私を修正してください。

12

Webサービスエンドポイントを呼び出して解決したときにこの問題が発生しました。

私の場合、それはクライアントが本文のコンテンツをエンコードする方法の問題でした。私はエンコーディングやメディアの種類を指定していませんでした。それらを指定することでそれが解決されました。私はこれをやっていた

は(415エラー原因):

var content = new StringContent(postData); 
httpClient.PostAsync(uri, content); 

エンコードとメディアタイプを指定し、働いていた:DELETEを行うと、JSONペイロードを追加するとき、私はこの415エラーを得ている

var content = new StringContent(postData, Encoding.UTF8, "application/json"); 
httpClient.PostAsync(uri, content); 
+1

マジック文字列 '" application/json "は.NET Coreライブラリのどこでも定数として利用できますか? – CSJ

+1

@CSJ System.Net.Mime名前空間にはいくつかの名前があります(たとえば、System.Net.Mime.MediaTypeNames.Application.pdfには「application/pdf」と記載されています)が、リストは完全ではありません。 "application/json"もなく、コア/標準ライブラリの一部でもありません。 https://stackoverflow.com/questions/10362140/asp-mvc-are-there-any-constants-for-the-default-content-typesを参照してください。他の誰かがより完全な定数リストを作成しています。 – monty

関連する問題