远程服务器返回错误:(405)方法不允许。 WCF REST服务

问题描述:

此问题已在其他地方提出,但这些问题不是我的问题的解决方案。远程服务器返回错误:(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

您是否第一次运行WCF应用程序?

运行下面的命令来注册wcf。

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

首先要了解您的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

在此花费了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记录了这个问题。

当它发生在我身上时,我只是简单地将post 添加到函数名称中,它解决了我的问题。也许它会帮助你们中的一些人。

在我碰到了的情况下,还有另外一个原因:底层代码试图做一个WebDAV PUT。 (如果需要这种特殊的应用是可配置的启用此功能,该功能是,瞒着我,启用,但没有设置必要的Web服务器环境

希望这可以帮助别人