JQueryを使用してajax呼び出しからWCFサービスを呼び出そうとしています。私はなんとかSOAP-UIとExcel/VBAからWCFを呼び出すことができます。私の問題は、送信されたOPTIONSリクエストに起因し、POSTは続きません:
http://mywcf/service.svc
に設定すると、OPTIONSが送信され、400 Bad Request
ステータスが取得され、POSTリクエストは送信されません。この場合、ヘッダーにHTTP/1.1
がありません(SOAP-UIヘッダーと比較して)。http://mywcf/service.svc HTTP/1.1
に設定すると、OPTIONSが送信され、200 OK
ステータスが表示されますが、POSTリクエストは送信されません。この場合、HTTP/1.1
はファイル名として解釈されるようです。誰かがjavascriptからWCFでPOSTアクションを呼び出し、サービスURLを破損せずにHTTP/1.1
ヘッダーを追加する方法を教えてもらえますか?
これが私のajax呼び出しからの抜粋です:
var soapData = ''
+'<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:mic="http://Microsoft.wcf.documentation">'
+' <soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsrm="http://docs.oasis-open.org/ws-rx/wsrm/200702">'
+' <wsrm:Sequence>'
+' <wsrm:Identifier>s:Sender a:ActionNotSupported</wsrm:Identifier>'
+' <wsrm:MessageNumber>1</wsrm:MessageNumber>'
+' </wsrm:Sequence>'
+' <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</wsa:Action>'
+' <wsa:ReplyTo>'
+' <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>'
+' </wsa:ReplyTo>'
+' <wsa:MessageID>uuid:'+ MsgUid +'</wsa:MessageID>'
+' <wsa:To>'+ Url +'</wsa:To>'
+' </soap:Header>'
+' <soap:Body xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">'
+' <wsrm:CreateSequence>'
+' <wsrm:AcksTo xmlns:wsa="http://www.w3.org/2005/08/addressing">'
+' <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>'
+' </wsrm:AcksTo>'
+' <wsrm:Offer>'
+' <wsrm:Identifier>urn:soapui:'+ SeqUid +'</wsrm:Identifier>'
+' </wsrm:Offer>'
+' </wsrm:CreateSequence>'
+' </soap:Body>'
+'</soap:Envelope>';
$.ajax({
type: 'POST',
url: 'http://mywcf/service.svc', // with or without +' HTTP/1.1'
data: soapData,
contentType: 'application/soap+xml;charset=UTF-8',
dataType: 'xml'
});
私のWCFの値web.config
:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
JQueryを使用してWebサービスを利用するには、つまりWCFサービスを呼び出すには、jQuery.ajax()またはjQuery.getJSON()を使用します。この記事では、jQuery.ajax()メソッドを使用しました。
リクエストを設定するには、最初に変数を定義します。これは、複数のメソッドを呼び出し、WCFサービスを呼び出すために別のjsファイルを作成する場合に役立ちます。
<script type="text/javascript">
var Type;
var Url;
var Data;
var ContentType;
var DataType;
var ProcessData;
次の関数は、サービスを呼び出すために上記で定義された変数を初期化します。
function WCFJSON() {
var userid = "1";
Type = "POST";
Url = "Service.svc/GetUser";
Data = '{"Id": "' + userid + '"}';
ContentType = "application/json; charset=utf-8";
DataType = "json"; varProcessData = true;
CallService();
}
CallService関数は、$。ajaxにデータを設定することにより、サービスにリクエストを送信します。
// Function to call WCF Service
function CallService() {
$.ajax({
type: Type, //GET or POST or PUT or DELETE verb
url: Url, // Location of the service
data: Data, //Data sent to server
contentType: ContentType, // content type sent to server
dataType: DataType, //Expected data format from server
processdata: ProcessData, //True or False
success: function(msg) {//On Successfull service call
ServiceSucceeded(msg);
},
error: ServiceFailed// When Service call fails
});
}
function ServiceFailed(result) {
alert('Service call failed: ' + result.status + '' + result.statusText);
Type = null;
varUrl = null;
Data = null;
ContentType = null;
DataType = null;
ProcessData = null;
}
注:次のコードはresult.GetUserResultステートメントをチェックするため、結果オブジェクトはサービスメソッド名+ Resultのプロパティを取得します。そうしないと、Javascriptにないオブジェクトのようなエラーが発生します。
function ServiceSucceeded(result) {
if (DataType == "json") {
resultObject = result.GetUserResult;
for (i = 0; i < resultObject.length; i++) {
alert(resultObject[i]);
}
}
}
function ServiceFailed(xhr) {
alert(xhr.responseText);
if (xhr.responseText) {
var err = xhr.responseText;
if (err)
error(err);
else
error({ Message: "Unknown server error." })
}
return;
}
$(document).ready(
function() {
WCFJSON();
}
);
</script>
WebHttpBindingエンドポイントを追加します
<services>
<service name="Contract">
<endpoint address="json" binding="webHttpBinding" contract="IContract" bindingConfiguration="ActionsHttpBinding" behaviorConfiguration="ActionrestfulBehavior"/>
</service>
次に、ajaxからエンドポイントをpostまたはgetとして呼び出します。以下の例を参照してください。
var data = JSON.stringify({
param1: val1,
param2: val2
});
$.ajax({
url: "http://mywcf/service.svc/json/FunctionName",
type: "POST",
data: data,
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: true
}).then(function (rsutlt) {
}).fail(function (fail) {
});
以下のコードをglobal.asax.csに追加し、Web構成からcustomHeadersを削除します。
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
//These headers are handling the "pre-flight" OPTIONS call sent by the browser
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
また、corsを有効にするにはOPTIONSVerbHandlerを削除する必要があります。
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>