2016-04-13 91 views
0

我創建了一個WCF服務,我試圖用於跨域調用(使用jQuery和JSONP)。我編寫了這個服務,當我在Visual Studio調試器中運行它並從本地PC上的測試頁調用它時,它工作正常。當我將服務部署到我們的服務器上的IIS7時,它不起作用。用小提琴看它,我發現有一個400錯誤回來了。調用WCF JSONP Web服務方法時出現錯誤400

這是我第一次嘗試創建WCF服務,也是我第一次嘗試JSONP,所以很有可能我錯過了一些簡單而重要的事情。

我對這個服務,一個很簡單的一個(稱爲的GetData),它只是需要一個字符串,並返回其2個方法 - 我創造了這個一個只是爲了測試基本的服務功能(即我可以把網址到瀏覽器,我得到一些JSON回來),它的工作正常。

另一個問題(稱爲GetMatter)需要一些參數,調用另一個(SOAP)Web服務來獲取一些數據並返回一個Stream,其中包含對我的回調函數的調用。然後插入顯示結果的調用頁面。

合同看起來是這樣的:

[ServiceContract] 
public interface IOracleService 
{ 

    [OperationContract] 
    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "getData/{value}")] 
    string GetData(string value); 

    [OperationContract] 
    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "getMatter/{matterId}/{callback}")] 
    Stream GetMatter(string matterId, string callback); 


} 

實施看起來是這樣的:

public class OracleService : IOracleService 
{ 
    public string GetData(string value) 
    { 
     return string.Format("You entered: {0}", value); 
    } 


    public Stream GetMatter(string matterId, string callback) 
    { 

     //call web service 
     var serviceResult = <call to web service goes here>; 

     //serialize data to json 
     JavaScriptSerializer js = new JavaScriptSerializer(); 
     string jsonResult = js.Serialize(serviceResult.data); 
     jsonResult = jsonResult.Substring(1, jsonResult.Length - 2); 

     string result = callback + "(" + jsonResult + ");"; 

     return new MemoryStream(Encoding.UTF8.GetBytes(result)); 

    } 

} 

我簡單的test.html頁面看起來像這樣(本次測試的目的,JS文件只存儲在我的本地Q:驅動器上):

<html> 

<head> 
    <script src="./jquery-2.2.2.min.js" type="text/javascript"></script> 
</head> 

<body> 

    <div id="output"></div> 
    <div id="output2"></div> 

    <script language="javascript"> 
    var url = "Q:\TestService.js"; 

    var script = document.createElement("script"); 
    script.setAttribute("src", url); 
    script.setAttribute("type", "text/javascript"); 
    document.body.appendChild(script); 
    </script> 


</body> 

</html> 

TestService.js如下所示(注意Ser vice.Legal是定義OracleService的名稱空間,MyServer是我已部署該服務的服務器的名稱。當在調試器中運行,MyServer的改變爲 「localhost:端口號」,這一工程確定,然後)

var url = "http://MyServer/Service.Legal.OracleWebService/OracleService.svc/GetData/1"; 

url += "?" + new Date().getTime().toString(); //append time to prevent caching 


var script = document.createElement("script"); 
script.setAttribute("src", url); 
script.setAttribute("type", "text/javascript"); 
document.body.appendChild(script); 


function ServiceCallback(data) { 
    console.log("got data: "); 
    console.dir(data); 

    var result = data; 
    var date = new Date(parseInt(result.INVOICE_DATE.substr(6))); 

    var output = "<ul>"; 
    output += "<li>INVOICE DATE: " + date + "</li>"; 
    output += "<li>TOTAL EXCL GST: " + result.TOTAL_EXCL_GST + "</li>"; 
    output += "<li>FEE ESTIMATE: " + result.FEE_ESTIMATE + "</li>"; 
    output += "</ul>"; 

    $("#output").html(output); 

} 

最後,在web.config的樣子:

<configuration> 
 

 
    <system.web> 
 
    <compilation debug="true" targetFramework="4.0" /> 
 
    <authentication mode="Windows" /> 
 
    </system.web> 
 
    <system.serviceModel> 
 
    <bindings> 
 
     <webHttpBinding> 
 
     <binding name="webHttpBinding" crossDomainScriptAccessEnabled="true"> 
 
      <security mode="Transport"> 
 
      <transport clientCredentialType="None" /> 
 
      </security> 
 
     </binding> 
 
     </webHttpBinding> 
 
    </bindings> 
 
    <client /> 
 
    <services> 
 
     <service name="Service.Legal.OracleWebService.OracleService"> 
 
     <endpoint address="" binding="webHttpBinding" contract="Service.Legal.OracleWebService.IOracleService" behaviorConfiguration="webBehaviour" /> 
 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
 
     <host> 
 
      <baseAddresses> 
 
      <add baseAddress="http://MyServer/Service.Legal.OracleWebService/" /> 
 
      </baseAddresses> 
 
     </host> 
 
     </service> 
 
    </services> 
 
    <behaviors> 
 
     <endpointBehaviors> 
 
     <behavior name="webBehaviour"> 
 
      <webHttp/> 
 
     </behavior> 
 
     </endpointBehaviors> 
 
     <serviceBehaviors> 
 
     <behavior> 
 
      <serviceMetadata httpGetEnabled="true" /> 
 
      <serviceDebug includeExceptionDetailInFaults="false" /> 
 
     </behavior> 
 
     </serviceBehaviors> 
 
    </behaviors> 
 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
 
    </system.serviceModel> 
 
    <system.webServer> 
 
    <httpProtocol> 
 
     <customHeaders> 
 
     <add name="Access-Control-Allow-Origin" value="*" /> 
 
     <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" /> 
 
     </customHeaders> 
 
    </httpProtocol> 
 
    <modules runAllManagedModulesForAllRequests="true" /> 
 
    <directoryBrowse enabled="true" /> 
 
    <httpErrors errorMode="Detailed" /> 
 
    <validation validateIntegratedModeConfiguration="false" /> 
 
    </system.webServer> 
 

 
</configuration>

正如我上面所說的,當我在Visual Studio調試器中運行這個服務時,我的html頁面在TestService.js中運行javascript,javascript調用我的服務(http://localhost:15021/OracleService.svc/GetMatter/matterId/ServiceCallback),最後我將顯示預期數據頁面。

當我改變服務URL在服務器(http://MyServer/Service.Legal.OracleWebService/OracleService.svc/GetMatter/matterId/ServiceCallback),以點帶面,我得到了一個空白頁面,並顯示提琴手請求直接給錯誤400

Web服務的基本測試瀏覽器

http://MyServer/Service.Legal.OracleWebService/OracleService.svc/getData/1 

確實會返回預期的json數據(儘管顯然IE只是詢問我是否想打開或保存「1.json」,它不會在瀏覽器中顯示任何東西),所以服務本身似乎是可訪問的並在IIS中正常工作。我的GetMatter函數或者我調用它阻止它在服務器上運行的方式似乎有些問題。

回答

0

嗯好的沒關係,我想我是在看錯誤的問題。

400(錯誤的請求)錯誤讓我覺得這個問題是與我的web服務的調用。但是,當我的Web服務嘗試調用其他Web服務時,似乎問題實際上是在服務器端發生的。當我把這個電話轉到其他網絡服務時,我的服務返回了200(成功)。我打算假設我所擁有的(如上所述)是可以的,並且這個問題與調用其他Web服務有關。也許防火牆問題阻止了從我的服務器到該服務器的呼叫,同時允許它從我的開發機器到同一臺服務器。

相關問題