The remote server returned an error: (405) Method not allowed. WCF REST Service

This question has already been asked elsewhere, but this is not a solution to my problem.

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 in the last line:

The remote server returned an error: (405) Method not allowed. I don’t know why this is happening. I tried changing the host from VS Server to IIS, but did not change the result. Let me know if you need more information.

+6
source share
5 answers

First of all, you need to know the exact URL of your REST service. Since you specified http://localhost:2517/Service1/Create , just try opening the same URL from IE, and you should get a method that is not allowed, since your Create method is specific to WebInvoke and IE is executing WebGet.

Now, make sure you have a SampleItem in your client application defined in the same namespace on your server, or make sure that the xml string you are building has an appropriate namespace for the service to identify that the xml string of the sample object can deserialize back to the object on the server.

I have a SampleItem defined on my server as shown below:

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

The xml line corresponding to my SampleItem looks like this:

 <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 method below to do a POST for the REST service:

 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 a SampleItem object defined on the client side. If you want to build an xml string on the client and pass, you can use the method below:

 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 will be as 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 your URL is correct

+6
source

Are you starting a WCF application for the first time?

run the command below to register wcf.

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

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 "When I study further ..." here https://sites.google.com/site / wcfpandu / useful-links

The generated Reference.cs web service client code file does not associate GET methods with [WebGet()] , therefore, POST tries to use them instead, therefore the InvalidProtocol, 405 method is not allowed. The problem is that this file is restored when you update the service link, and you also need the dll link to System.ServiceModel.Web for the WebGet attribute.

So, I decided to manually edit the Reference.cs file and save a copy. The next time I update it, I combined my WebGet()s again.

As I see it, this is an error with svcutil.exe, which does not recognize that some of the methods of the GET service, and not just POST , even if the WSDL and HELP published by the WCF IIS web service, understand which POST and GET methods ?? ? I registered this problem with Microsoft Connect.

+1
source

When this happened to me, I just added the word post to the function name, and it solved my problem. perhaps this will help some of you too.

0
source

In the case when I came across, there was another reason: the base code was trying to make WebDAV PUT. (This particular application was configured to enable this feature, if necessary, this feature was turned on without my knowledge, but the required web server environment was not configured.

Hope this can help someone else.

0
source

Source: https://habr.com/ru/post/913100/


All Articles