2015-05-19 57 views
15

我有以下API一個RESTful WCF的Web服務:WebGet不帶參數或UriTemplate失敗

[WebGet(ResponseFormat = WebMessageFormat.Json)] 
MyResponseContract GetFileInfo(); 

當試圖打端點(使用SOAPUI)我看到了以下錯誤消息:

服務器在處理請求時遇到錯誤。請參閱 服務幫助頁面,以便爲服務構建有效的請求。

我有SOAPUI設置爲使用GET方法調用它。當我將它切換到沒有正文的POST時,它會失敗並顯示以下消息:

方法不允許。

這是非常有意義的:無法通過POST命中GET。所以我更新了我的代碼,如下所示:

[WebInvoke(ResponseFormat = WebMessageFormat.Json)] 
MyResponseContract GetFileInfo(); 

現在我使用POST方法從SOAPUI調用它,並且它可以工作。好奇。所以我現在改變我的代碼如下:

[WebInvoke(ResponseFormat = WebMessageFormat.Json, Method = "GET")] 
MyResponseContract GetFileInfo(); 

我見過幾個職位,這基本上等同於一個WebGet屬性。這也是行不通的。

所以我的問題是:爲什麼不作爲WebGet工作,即使我不接受參數或使用自定義UriTemplate?

我試圖用打它(它在IIS本地託管)的網址是:

http://localhost/Utilities/API/GetFileInfo

更新 給出下面的意見和給定的答案,我仍然面臨着這個問題。一些額外的細節。

我的網絡層的web.config

<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    <customErrors mode="Off" /> 
    </system.web> 
    <system.serviceModel> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
    <standardEndpoints> 
     <webHttpEndpoint> 
     <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" maxReceivedMessageSize="10000000" /> 
     </webHttpEndpoint> 
    </standardEndpoints> 
    <behaviors> 
     <endpointBehaviors> 
     <behavior name="exampleBehavior"> 
      <callbackDebug includeExceptionDetailInFaults="true" /> 
      <enableWebScript /> 
      <webHttp helpEnabled="true" /> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <bindings> 
     <webHttpBinding> 
     <binding name="WebHttpBinding" maxReceivedMessageSize="10000000" /> 
     </webHttpBinding> 
    </bindings> 
    <client>  
     <endpoint address="http://LOCALHOST/Utilities.AppService/API" 
       binding="webHttpBinding" bindingConfiguration="WebHttpBinding" 
       contract="Utilities.Common.API.IMyApi" 
       behaviorConfiguration="exampleBehavior" /> 
    </client> 
    </system.serviceModel> 
</configuration> 

我的應用程序層的web.config:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    <customErrors mode="Off" /> 
    </system.web> 
    <system.serviceModel> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
    <standardEndpoints> 
     <webHttpEndpoint> 
     <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" maxReceivedMessageSize="10000000" /> 
     </webHttpEndpoint> 
    </standardEndpoints> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true" /> 
    <handlers> 
     <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
     <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" /> 
    </handlers> 
    </system.webServer> 
</configuration> 

我的服務接口

[ServiceContract(Namespace = "API")] 
public interface IMyApi 
{  
    [WebGet] 
    MyResponseContract GetFileInfo(); 
} 

我的網絡層實現

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class MyApiWebService : ClientBase<IMyApi>, IMyApi 
{ 
    public MyResponseContract GetFileInfo() 
    { 
     return Channel.GetFileInfo(); 
    } 
} 

我的應用層實現

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class MyApiAppService : IMyApi 
{ 
    public MyResponseContract GetFileInfo() 
    { 
     return new MyResponseContract(); 
    } 
} 

我的網絡層的Global.asax:

protected void Application_Start(object sender, EventArgs e) 
    { 
     RouteTable.Routes.Add(new ServiceRoute("API", new WebServiceHostFactory(), typeof(MyApiWebService))); 
    } 

我的應用程序層的全局。asax:

protected void Application_Start(object sender, EventArgs e) 
    { 
     RouteTable.Routes.Add(new ServiceRoute("API", new WebServiceHostFactory(), typeof(MyApiAppService))); 
    } 

我不確定我可以提供多少更多的細節。正如你所看到的,鑑於提供的解決方案,我已經實施了一切建議無濟於事。無論我試圖通過在瀏覽器中放置Web圖層服務url還是使用SOAPUI來嘗試實現WebGet方法,或者嘗試使用服務客戶端通過C#單元測試進行擊打,我都無法使用WebGet。再次感謝您的幫助。

有趣的是,應用層URL的工作原理。但是網頁層沒有。所以:

localhost/Utilities.AppService/API/GetFileInfo

作品,而

localhost/Utilities.WebService/API/GetFileInfo

沒有。

+0

你是如何訪問它 - 就像一個URI樣?而要清楚的是最後一個也沒有工作? –

+0

更新了要求的詳細信息。 –

+0

你使用的是WebHttpBinding嗎? –

回答

5

所以這可能不是很明顯,直到最近,我更新,但我有一個相互溝通,但生活在不同的域中的兩個RESTful服務。 Web層服務是第一個聯繫人,而App-Layer服務是實際的工作人員。在這種情況下,我能夠進一步調試,發現從Web到App層的實際異常是405(方法不允許)。經過多次挖掘,我發現this link解決了我的問題。

當使用ClientBase<>爲你提供的服務之間進行通信的方法,你基本上是需要重新建立呼叫之間的操作環境。否則,所有東西都變成一個POST,因此只有POST可以工作。

我希望這可以幫助別人,我非常感謝大家的調試這個幫助。

爲了證明這是什麼樣子,下面是我的更新,工作Web服務實現的樣子:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class MyApiWebService : ClientBase<IMyApi>, IMyApi 
{ 
    public MyResponseContract GetFileInfo() 
    { 
     MyResponseContract output = null; 

     using(var context = new OperationContext(Channel as IContextChannel)) 
     { 
      output = Channel.GetFileInfo(); 
     } 

     return output; 
    } 
} 
4

.NET WCF Web服務默認設置爲發送文本編碼的SOAP消息。這意味着HTTP方法是POST,並且需要頭文件來告訴服務調用什麼方法。

我創建使用您的服務端點一個簡單的例子,這裏是從小提琴手產生的交談端點的請求。

POST http://localhost/Utilities/API/GetFileInfo/Service1.svc HTTP/1.1 
Content-Type: text/xml; charset=utf-8 
SOAPAction: "http://tempuri.org/IService1/GetFileInfo" 
Host: localhost:8888 
Content-Length: 136 
Expect: 100-continue 
Connection: Keep-Alive 

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><GetFileInfo xmlns="http://tempuri.org/"/></s:Body></s:Envelope> 

回到家鄉,我想在你的了SoapUI的東西是不正確的

HTTP/1.1 200 OK 
Cache-Control: private 
Content-Length: 398 
Content-Type: text/xml; charset=utf-8 
Server: Microsoft-IIS/8.0 
X-AspNet-Version: 4.0.30319 
X-SourceFiles: =?UTF-8?B?QzpcV29ya1xFSVAgV29ya1xRdWVzdGlvbnNcV0NGR2V0VGVzdFxTZXJ2aWNlMS5zdmM=?= 
X-Powered-By: ASP.NET 
Date: Thu, 21 May 2015 19:47:49 GMT 

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><GetFileInfoResponse xmlns="http://tempuri.org/"><GetFileInfoResult xmlns:a="http://schemas.datacontract.org/2004/07/WCFGetTest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><a:BoolValue>true</a:BoolValue><a:StringValue>MyResponseContract </a:StringValue></GetFileInfoResult></GetFileInfoResponse></s:Body></s:Envelope> 

對你的迴應。發佈數據或標題。

+0

但是,當我簡單地將網址在瀏覽器返回相同的迴應。 –

+0

如果您想公開一個返回JSON的get方法,您必須更改綁定來執行此操作。看看http:// stackoverflow。COM /問題/ 186631 /休息皁的端點-FOR-A-WCF服務/ 186695#186695 –