JSONデータの送信問題JQueryからWCF RESTメソッドへ
-
28-10-2019 - |
質問
jQueryにJSONデータをWCFサービスにRESTメソッドに投稿させるのに苦労しています。
WCF側には、操作契約が次のとおりです。
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "PostSomething")]
MyResult PostSomething(MyRequest request);
両方 MyResult
と MyRequest
必要なすべてでマークされています DataContract
と DataMember
属性とサービスは、WebHTTPエンドポイントを公開しています。
jquery側には、私の関数呼び出しがあります:
var jsonStr = JSON.stringify(reqObj);
$.ajax({
type: "POST",
dataType: "json",
url: "http://localhost/MyService/PostSomething",
contentType: "application/json; charset=utf-8",
data: jsonStr,
success: function (html) {
alert(html);
}
});
このリクエストは私の方法に到達することはありません(私は毎回許可されていない405メソッドを取得します)、チャールズを見ると、リクエストは次のようになります。
OPTIONS /MyService/PostSomething HTTP/1.1
Host: localhost
Cache-Control: max-age=0
Access-Control-Request-Method: POST
Origin: null
Access-Control-Request-Headers: Content-Type, Accept
Accept: */*
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
これについて奇妙なことのいくつかのこと:
- メソッドはオプションではありません
- コンテンツタイプ(別のタブ)が表示されます
text/html; charset=UTF-8
JSONの代わりに - JSONデータはどこにも見られるものではありません
ただし、チャールズのリクエストを変更して、ヘッダーがソリューションに似ているようにすると ここ, 、その後、すべてが機能します:
POST /MyService/PostSomething HTTP/1.1
Content-Type: application/json; charset=utf-8
Host: localhost
Content-Length: 152
{"Id":"", "Name":"testspot","Description":"test" }
ここでチュートリアルやその他の質問を見ると、他の人はjQueryにこのようなWCF休憩方法に投稿することができました。
ああ、いくつかのコンテキストを置くために、これはWCF 4サービスであり、JQuery 1.4.4を使用しています。
ありがとう、
アップデート:
もう少し読んで、クロスドメインの仕様に向かって私を向けてくれたDarrelに感謝した後、サービスインターフェイスでサービスに小さな変更を加えることで、もう少しさらに進むことができました。
[OperationContract]
[WebInvoke(Method = "*",
BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "PostSomething")]
MyResult PostSomething(MyRequest request);
実装では、着信リクエストがオプションのものであるかどうかを確認する必要があります。その場合、意図した作業を行うのではなく、ヘッダーを返します。
if (WebOperationContext.Current.IncomingRequest.Method == "OPTIONS")
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept");
return null;
}
その後、メソッドは2回呼び出されます。サーバーが最初にNULLを返しますが、クライアントにヘッダーを追加すると、実際の要求がメソッドとしてPOSTで作成され、サーバーが先に進み、通常はリクエストを扱います。
解決
これは、クロスドメイン呼び出しを避けるためのFirefoxのもののようです。見る http://www.petefreitag.com/item/703.cfm
これの仕様はこちらです http://www.w3.org/tr/cors/ また、非常に簡単な読み取りの後、クロスドメインコールを行っているため、サービスはオプションメソッドを実装し、POSTメソッドを送信できるヘッダーを返すことが期待されているようです。
他のヒント
提案されたソリューションを含む質問の更新にはいくつかの問題があります - 問題は、入力がPOSTメソッドをサポートしていない場合、オプション要求が実際に正しい許可ヘッダーを返していないことです。 WCFエンドポイントで実際に許可されている方法を実際に検討していません。クライアントがオプションリクエストを実行するときに、アプリケーションのすべてのエンドポイントに対して「投稿」が許可されているという人工的に「投稿」が許可されています(実際にはクライアントがサポートされているものを尋ねます)。
これはおそらく大丈夫です。オプション方法の情報に頼っていない場合は、有効なメソッドリストを返すことができます(一部のCORSリクエストの場合のように) - しかし、もしそうなら、あなたは次のようなことをする必要がありますこの質問に関する解決策:WCF自己ホストでajax jQuery Postリクエストを処理する方法
基本的に、各エンドポイントを実装する必要があります。
Webinvoke(Method="OPTIONS", UriTemplate="")
適切なヘッダーを応答にロードする適切な方法(そのエンドポイントの適切な「アクセスコントロール - アロウメソッド」リストを含む)を発信者に呼び出します。 WCFエンドポイントをホストしたのは、自動的にこれを行わないのは一種の吸うですが、これはエンドポイントをより細かく制御できる回避策です。そのソリューションでは、適切な応答ヘッダーがエンドポイントの実装でロードされます。
public void GetOptions()
{
// The data loaded in these headers should match whatever it is you support on the endpoint
// for your application.
// For Origin: The "*" should really be a list of valid cross site domains for better security
// For Methods: The list should be the list of support methods for the endpoint
// For Allowed Headers: The list should be the supported header for your application
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization");
}
それに加えて、バインディングエンドポイントのweb.configの「CrossDomainScriptAccesSevaded」フラグを設定するか、エンドポイントを構成するときにWebHTTPBindingのコードを設定する必要があります。それ以外の場合は、「アクセスコントロールアローオリジン」は「*」(またはURLのリスト)と言うと、再びヘッダーの応答に横たわっています。
アップデート:
URLが読み取られるように、myServiceの後に.svcを入れてみてください
http://localhost/MyService.svc/PostSomething
先日、私はこれに取り組んでいて、リック・ストラールのブログの投稿に出会いました。
http://www.west-wind.com/weblog/posts/324917.aspx
これは私にとって完璧に機能するので、試してみてください!
それが役立つことを願っています! :)
あなたのweb.configでwebhttpbindingを使用しましたか?
webhttpbindingのみがJSONをサポートしています。
他の答えがそうではなかったので、私が助けてくれた短い答えを投稿するだけです。
- シナリオ:WCFサービスへのAJAXコール。
- エラー原因:POSTリクエストを送信する前に、AJAXからの自動オプションリクエスト。最初のリクエストは私のサービスによって処理できませんでした。
- 解決策:オプション要求を許可し、応答します。
するべきこと:
これをweb.configに追加します:
<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> </customHeaders> </httpProtocol>
これをglobal.asax.csに追加します(ソリューションにこのファイルがない場合は、次のように作成します。新しいアイテムを追加=> Visual C#=> Global Applicationクラス(デフォルト名は「Global.Asax」です)):
protected void Application_BeginRequest(object sender, EventArgs e) { if (HttpContext.Current.Request.HttpMethod == "OPTIONS") HttpContext.Current.Response.End(); }