2012-04-13 290 views
6

此問題已在其他地方提出,但這些問題不是我的問題的解決方案。遠程服務器返回錯誤:(405)方法不允許。 WCF REST服務

這是我的服務

[WebInvoke(UriTemplate = "", Method = "POST")] 
public SampleItem Create(SampleItem instance) 
{ 
    // TODO: Add the new instance of SampleItem to the collection 
    // throw new NotImplementedException(); 
    return new SampleItem(); 
} 

我有這樣的代碼來調用以上服務

XElement data = new XElement("SampleItem", 
          new XElement("Id", "2"), 
          new XElement("StringValue", "sdddsdssd") 
          ); 

System.IO.MemoryStream dataSream1 = new MemoryStream(); 
data.Save(dataSream1); 

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:2517/Service1/Create"); 
request.Method = "POST"; 
request.ContentType = "application/x-www-form-urlencoded"; 
// You need to know length and it has to be set before you access request stream 
request.ContentLength = dataSream1.Length; 

using (Stream requestStream = request.GetRequestStream()) 
{ 
    dataSream1.CopyTo(requestStream); 
    byte[] bytes = dataSream1.ToArray(); 
    requestStream.Write(bytes, 0, Convert.ToInt16(dataSream1.Length)); 
    requestStream.Close(); 
} 

WebResponse response = request.GetResponse(); 

我會在最後一行異常:

遠程服務器返回錯誤:(405)方法不允許。不知道爲什麼會發生這種情況,我嘗試將主機從VS Server更改爲IIS,但結果沒有變化。讓我知道您是否需要更多信息

+0

什麼。你的路線是什麼樣子? – 2012-04-13 03:40:15

+0

請添加您正在使用的任何綁定配置的config /代碼。 – 2012-04-13 04:16:05

+0

你設置的contentType爲「application/X WWW的形式,進行了urlencoded」,但您發送XML數據,你能內容類型設置爲「應用程序/ XML」 – Chandermani 2012-04-13 09:02:32

回答

2

您是否第一次運行WCF應用程序?

運行下面的命令來註冊wcf。

"%WINDIR%\Microsoft.Net\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe" -r 
6

首先要了解您的REST服務的確切URL。既然你已經指定了http://localhost:2517/Service1/Create現在只是嘗試從IE打開相同的URL,你應該得到的方法不允許,因爲你的Create方法是爲WebInvoke定義的,IE做了WebGet。

現在確保您的客戶端應用程序中的SampleItem在您的服務器上的相同名稱空間中定義,或確保您構建的xml字符串具有適當的服務名稱空間以標識示例對象的xml字符串可以被反序列化回服務器上的對象。

我有SampleItem我的服務器上定義的,如下所示:

namespace SampleApp 
{ 
    public class SampleItem 
    { 
     public int Id { get; set; } 
     public string StringValue { get; set; }    
    }  
} 

對應於我的SampleItem XML字符串是如下:

<SampleItem xmlns="http://schemas.datacontract.org/2004/07/SampleApp" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Id>6</Id><StringValue>from client testing</StringValue></SampleItem> 

現在我使用以下方法來執行POST到REST服務:

private string UseHttpWebApproach<T>(string serviceUrl, string resourceUrl, string method, T requestBody) 
     { 
      string responseMessage = null; 
      var request = WebRequest.Create(string.Concat(serviceUrl, resourceUrl)) as HttpWebRequest; 
      if (request != null) 
      { 
       request.ContentType = "application/xml"; 
       request.Method = method; 
      } 

      //var objContent = HttpContentExtensions.CreateDataContract(requestBody); 
      if(method == "POST" && requestBody != null) 
      { 
       byte[] requestBodyBytes = ToByteArrayUsingDataContractSer(requestBody); 
       request.ContentLength = requestBodyBytes.Length; 
       using (Stream postStream = request.GetRequestStream()) 
        postStream.Write(requestBodyBytes, 0, requestBodyBytes.Length);      
      } 

      if (request != null) 
      { 
       var response = request.GetResponse() as HttpWebResponse; 
       if(response.StatusCode == HttpStatusCode.OK) 
       { 
        Stream responseStream = response.GetResponseStream(); 
        if (responseStream != null) 
        { 
         var reader = new StreamReader(responseStream); 

         responseMessage = reader.ReadToEnd();       
        } 
       } 
       else 
       { 
        responseMessage = response.StatusDescription; 
       } 
      } 
      return responseMessage; 
     } 

private static byte[] ToByteArrayUsingDataContractSer<T>(T requestBody) 
     { 
      byte[] bytes = null; 
      var serializer1 = new DataContractSerializer(typeof(T));    
      var ms1 = new MemoryStream();    
      serializer1.WriteObject(ms1, requestBody); 
      ms1.Position = 0; 
      var reader = new StreamReader(ms1); 
      bytes = ms1.ToArray(); 
      return bytes; 
     } 

現在我打電話給上面的方法,如圖所示:

SampleItem objSample = new SampleItem(); 
objSample.Id = 7; 
objSample.StringValue = "from client testing"; 
string serviceBaseUrl = "http://localhost:2517/Service1"; 
string resourceUrl = "/Create"; 
string method="POST"; 

UseHttpWebApproach<SampleItem>(serviceBaseUrl, resourceUrl, method, objSample); 

我也在客戶端定義了SampleItem對象。如果你想建立客戶機上的XML字符串並通過,那麼你可以使用下面的方法:

private string UseHttpWebApproach(string serviceUrl, string resourceUrl, string method, string xmlRequestBody) 
      { 
       string responseMessage = null; 
       var request = WebRequest.Create(string.Concat(serviceUrl, resourceUrl)) as HttpWebRequest; 
       if (request != null) 
       { 
        request.ContentType = "application/xml"; 
        request.Method = method; 
       } 

       //var objContent = HttpContentExtensions.CreateDataContract(requestBody); 
       if(method == "POST" && requestBody != null) 
       { 
        byte[] requestBodyBytes = ASCIIEncoding.UTF8.GetBytes(xmlRequestBody.ToString()); 
        request.ContentLength = requestBodyBytes.Length; 
        using (Stream postStream = request.GetRequestStream()) 
         postStream.Write(requestBodyBytes, 0, requestBodyBytes.Length);      
       } 

       if (request != null) 
       { 
        var response = request.GetResponse() as HttpWebResponse; 
        if(response.StatusCode == HttpStatusCode.OK) 
        { 
         Stream responseStream = response.GetResponseStream(); 
         if (responseStream != null) 
         { 
          var reader = new StreamReader(responseStream); 

          responseMessage = reader.ReadToEnd();       
         } 
        } 
        else 
        { 
         responseMessage = response.StatusDescription; 
        } 
       } 
       return responseMessage; 
      } 

和呼叫上述方法將如圖6-8所示:

string sample = "<SampleItem xmlns=\"http://schemas.datacontract.org/2004/07/XmlRestService\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><Id>6</Id><StringValue>from client testing</StringValue></SampleItem>"; 
string serviceBaseUrl = "http://localhost:2517/Service1"; 
string resourceUrl = "/Create"; 
string method="POST";    
UseHttpWebApproach<string>(serviceBaseUrl, resourceUrl, method, sample); 

注意:只要確保你的URL是正確的

+0

我得到的遠程服務器返回錯誤:(405)不允許的方法 – Praneeth 2012-04-13 13:11:26

+0

您的服務如何託管你有在global.a的條目。?薩克斯。此外,請檢查是否已啓用幫助頁面,並嘗試查找您嘗試發佈的方法的url並查看該url是否正確 – Rajesh 2012-04-13 15:01:33

+0

幫助正在工作我可以在瀏覽器中看到服務並獲取正在瀏覽器。服務是通過VS服務器託管和我在Global.asax – Praneeth 2012-04-14 11:47:13

1

在此花費了2天后,使用VS 2010 .NET 4.0,IIS 7.5 WCF和REST與JSON ResponseWrapped,我終於通過閱讀「當進一步調查...」這裏https://sites.google.com/site/wcfpandu/useful-links

Web服務客戶端代碼生成的文件參考。CS沒有屬性GET方法與[WebGet()],所以嘗試POST他們,而不是,因此InvalidProtocol,405不允許的方法。問題是,當你刷新服務引用時,這個文件被重新生成,並且你還需要一個dll參考System.ServiceModel.Web,以獲得WebGet屬性。

所以我決定手動編輯Reference.cs文件,並保留一份副本。下一次,我刷新它,我將我的合併在WebGet()s回來。

我看到它的方式,它與svcutil.exe的不承認,一些服務方法GET並不僅僅是POST,即使錯誤WCF IIS Web服務發佈的WSDL和HELP確實瞭解哪些方法是POSTGET ???我用Microsoft Connect記錄了這個問題。

0

當它發生在我身上時,我只是簡單地將post 添加到函數名稱中,它解決了我的問題。也許它會幫助你們中的一些人。

0

在我碰到了的情況下,還有另外一個原因:底層代碼試圖做一個WebDAV PUT。 (如果需要這種特殊的應用是可配置的啓用此功能,該功能是,瞞着我,啓用,但沒有設置必要的Web服務器環境

希望這可以幫助別人

相關問題