简体   繁体   English

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

[英]The remote server returned an error: (405) Method Not Allowed. WCF REST Service

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. 远程服务器返回错误:(405)方法不允许。 Not sure why this is happening i tried changing the host from VS Server to IIS also but no change in result. 不知道为什么会发生这种情况我尝试将主机从VS Server更改为IIS,但结果没有变化。 Let me know if u need more information 如果您需要更多信息,请告诉我

First thing is to know the exact URL for your REST Service. 首先要知道REST服务的确切URL。 Since you have specified http://localhost:2517/Service1/Create now just try to open the same URL from IE and you should get method not allowed as your Create Method is defined for WebInvoke and IE does a WebGet. 由于您已经指定了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. 我也在客户端定义了SampleItem对象。 If you want to build the xml string on the client and pass then you can use the below method: 如果要在客户端上构建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 注意:只需确保您的网址正确无误

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

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 花了两天时间,使用VS 2010 .NET 4.0,IIS 7.5 WCF和带JSON ResponseWrap的REST,我终于通过阅读“当进一步调查时...”来解析它,这里https://sites.google.com/site / wcfpandu /有用的链接

The Web Service Client code generated file Reference.cs doesn't attribute the GET methods with [WebGet()] , so attempts to POST them instead, hence the InvalidProtocol, 405 Method Not Allowed. Web服务客户端代码生成的文件Reference.cs不将GET方法归因于[WebGet()] ,因此尝试POST它们,因此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. 但问题是,在刷新服务引用时会重新生成此文件,并且还需要对System.ServiceModel.Web的dll引用,以用于WebGet属性。

So I've decided to manually edit the Reference.cs file, and keep a copy. 所以我决定手动编辑Reference.cs文件,并保留一份副本。 Next time I refresh it, I'll merge my WebGet()s back in. 下次刷新它时,我会将我的WebGet()s重新合并。

The way I see it, it's a bug with svcutil.exe not recognising that some of the service methods are GET and not just POST , even though the WSDL and HELP that the WCF IIS web service publishes, does understand which methods are POST and GET ??? 我看到它的方式,这是一个错误,svcutil.exe无法识别某些服务方法是GET而不仅仅是POST ,即使WCF IIS Web服务发布的WSDL和HELP,也确实知道哪些方法是POSTGET ??? I've logged this issue with Microsoft Connect. 我已使用Microsoft Connect记录此问题。

When it happened to me, I just simply added the word post to the function name, and it solved my problem. 当它发生在我身上时,我只是简单地将单词post添加到函数名称中,它解决了我的问题。 maybe it will help some of you too. 也许它会帮助你们中的一些人。

In the case I came up against, there was yet another cause: the underlying code was attempting to do a WebDAV PUT. 在我遇到的情况下,还有另一个原因:底层代码试图做一个WebDAV PUT。 (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. (此特定应用程序可配置为在需要时启用此功能;启用了该功能,我不知道,但未设置必要的Web服务器环境。

Hopefully this may help someone else. 希望这可以帮助别人。

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! 祝好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 WebRequest POST返回“远程服务器返回错误:(405)不允许的方法。” - WebRequest POST returns “The remote server returned an error: (405) Method Not Allowed.” C# 如何解决 Web 客户端上传文件“远程服务器返回错误:(405)方法不允许。”? - C# How to solve Web Client Upload file “The remote server returned an error: (405) Method Not Allowed.”? Azure移动服务,远程服务器返回错误:(405)不允许的方法 - Azure mobile service, The remote server returned an error: (405) Method Not Allowed 远程服务器返回错误:(405)允许方法 - The remote server returned an error: (405) Method Allowed 远程服务器返回错误:(405)方法不允许 - The remote server returned an error: (405) Method Not Allowed 远程服务器返回错误:“(405) Method Not Allowed” - The remote server returned an error: "(405) Method Not Allowed" 为什么链接“@”在我的浏览器中工作,但C#HttpWebRequest给出404(远程服务器返回错误:(405)Method Not Allowed。) - Why does a link with “@” work in my browser but C# HttpWebRequest gives 404 (The remote server returned an error: (405) Method Not Allowed.) WCF-远程服务器返回了意外的响应:(405)不允许的方法 - WCF - The remote server returned an unexpected response: (405) Method Not Allowed 方法不允许(http错误405),wcf,休息服务,post方法 - Method not allowed (http error 405) , wcf , rest service , post method 交换Web服务错误-远程服务器返回不允许的错误405方法 - exchange web service error - the remote server returned an error 405 method not allowed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM