C# 远程服务器返回错误:(405) Method Not Allowed。WCF REST 服务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10134632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
The remote server returned an error: (405) Method Not Allowed. WCF REST Service
提问by Praneeth
This question is already asked elsewhere but those things are not the solutions for my issue.
这个问题已经在别处问过了,但这些东西不是我的问题的解决方案。
This is my service
这是我的服务
[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();
}
I have this code to call the above service
我有这个代码来调用上述服务
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();
I get an exception at the last line:
我在最后一行出现异常:
The remote server returned an error: (405) Method Not Allowed. Not sure why this is happening i tried changing the host from VS Server to IIS also but no change in result. Let me know if u need more information
远程服务器返回错误:(405) Method Not Allowed。不知道为什么会发生这种情况我也尝试将主机从 VS Server 更改为 IIS,但结果没有变化。如果您需要更多信息,请告诉我
回答by user1312242
Are you running WCF application for the first time?
您是第一次运行 WCF 应用程序吗?
run below command to register wcf.
运行下面的命令来注册 wcf。
"%WINDIR%\Microsoft.Net\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe" -r
回答by Rajesh
First thing is to know the exact URL for your REST Service. Since you have specified http://localhost:2517/Service1/Createnow just try to open the same URL from IE and you should get method not allowed as your CreateMethod is defined for WebInvoke and IE does a WebGet.
第一件事是知道您的 REST 服务的确切 URL。由于您http://localhost:2517/Service1/Create现在已指定,只需尝试从 IE 打开相同的 URL,您应该获取不允许的Create方法,因为您的方法是为 WebInvoke 定义的,而 IE 会执行 WebGet。
Now make sure that you have the SampleItem in your client app defined in the same namespace on your server or make sure that the xml string you are building has the appropriate namespace for the service to identify that the xml string of sample object can be deserialized back to the object on server.
现在确保您的客户端应用程序中的 SampleItem 定义在服务器上的相同命名空间中,或者确保您正在构建的 xml 字符串具有适合服务的命名空间,以识别示例对象的 xml 字符串可以反序列化回来到服务器上的对象。
I have the SampleItem defined on my server as shown below:
我在我的服务器上定义了 SampleItem,如下所示:
namespace SampleApp
{
public class SampleItem
{
public int Id { get; set; }
public string StringValue { get; set; }
}
}
The xml string corresponding to my SampleItem is as below:
我的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>
Now i use the below method to perform a POST to the REST service :
现在我使用以下方法对 REST 服务执行 POST:
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;
}
Now i call the above method as shown:
现在我调用上面的方法,如下所示:
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);
I have the SampleItem object defined in the client side as well. If you want to build the xml string on the client and pass then you can use the below method:
我也在客户端定义了 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;
}
And the call to the above method would be as shown below:
对上述方法的调用如下所示:
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);
NOTE: Just make sure that your URL is correct
注意:只需确保您的 URL 正确
回答by Deano
After spending 2 days on this, using VS 2010 .NET 4.0, IIS 7.5 WCF and REST with JSON ResponseWrapped, I finally cracked it by reading from "When investigating further..." here https://sites.google.com/site/wcfpandu/useful-links
在花了 2 天的时间之后,使用 VS 2010 .NET 4.0、IIS 7.5 WCF 和 REST with JSON ResponseWrapped,我终于通过阅读“进一步调查时...”来破解它 https://sites.google.com/site /wcfpandu/有用的链接
The Web Service Client code generated file Reference.cs doesn't attribute the GETmethods with [WebGet()], so attempts to POSTthem instead, hence the InvalidProtocol, 405 Method Not Allowed.Problem is though, this file is regenerated when ever you refresh the service reference, and you also need a dll reference to System.ServiceModel.Web, for the WebGet attribute.
Web 服务客户端代码生成的文件 Reference.cs 没有将GET方法归因于[WebGet()],因此尝试使用POST它们,因此是InvalidProtocol, 405 Method Not Allowed。但问题是,每当您刷新服务引用时都会重新生成此文件,并且您还需要一个对 的 dll 引用System.ServiceModel.Web,用于 WebGet 属性。
So I've decided to manually edit the Reference.cs file, and keep a copy. Next time I refresh it, I'll merge my WebGet()sback in.
所以我决定手动编辑 Reference.cs 文件,并保留一份副本。下次我刷新它时,我会合并WebGet()s回来。
The way I see it, it's a bug with svcutil.exe not recognising that some of the service methods are GETand not just POST, even though the WSDL and HELP that the WCF IIS web service publishes, does understand which methods are POSTand GET??? I've logged this issue with Microsoft Connect.
在我看来,这是 svcutil.exe 的一个错误,它无法识别某些服务方法是GET,而不仅仅是POST,即使 WCF IIS Web 服务发布的 WSDL 和 HELP 确实了解哪些方法是POST和GET??? 我已经用 Microsoft Connect 记录了这个问题。
回答by ParPar
When it happened to me, I just simply added the word postto the function name, and it solved my problem. maybe it will help some of you too.
当它发生在我身上时,我只是简单地将这个词添加 post到函数名称中,它就解决了我的问题。也许它也会帮助你们中的一些人。
回答by Reg Edit
In the case I came up against, there was yet another cause: the underlying code was attempting to do a WebDAVPUT. (This particular application was configurable to enable this feature if required; the feature was, unbeknownst to me, enabled, but the necessary web server environment was not set up.
在我遇到的情况下,还有另一个原因:底层代码试图执行WebDAVPUT。(此特定应用程序可配置为在需要时启用此功能;我不知道该功能已启用,但未设置必要的 Web 服务器环境。
Hopefully this may help someone else.
希望这可以帮助别人。
回答by user10244822
The issue I have fixed, because your service is secured by login credential with user name and password, try set up the user name and password on the request, it will be working. Good luck!
我已解决的问题,因为您的服务是通过用户名和密码登录凭据保护的,请尝试根据请求设置用户名和密码,它将起作用。祝你好运!

