8

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

4

6 に答える 6

9

最初に、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>

以下のメソッドを使用して、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;
        }

次に、上記のメソッドを次のように呼び出します。

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;
            }

上記のメソッドの呼び出しは、次のようになります。

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 が正しいことを確認してください

于 2012-04-13T10:01:13.397 に答える
4

初めて WCF アプリケーションを実行していますか?

以下のコマンドを実行して wcf を登録します。

"%WINDIR%\Microsoft.Net\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe" -r
于 2012-04-13T04:06:32.767 に答える
2

これに 2 日間費やした後、VS 2010 .NET 4.0、IIS 7.5 WCF、JSON ResponseWrapped を使用した REST を使用して、最終的に「さらに調査する場合...」を読んで解読しました https://sites.google.com/site /wcfpandu/便利なリンク

Web サービス クライアント コードで生成されたファイル Reference.cs は、GETメソッドに属性を付けていないため、代わりにそれらを[WebGet()]試みます。そのため、 InvalidProtocol, 405 Method Not Allowed になります。ただし、問題は、サービス参照を更新するたびにこのファイルが再生成され、WebGet 属性の への dll 参照も必要なことです。POSTSystem.ServiceModel.Web

そこで、Reference.cs ファイルを手動で編集し、コピーを保存することにしました。次に更新するときは、WebGet()s背中をマージします。

私の見方では、WCF IIS Web サービスが発行する WSDL と HELP がどのメソッドが何であるかを理解しているにもかかわらず、いくつかのサービスメソッドがGET. Microsoft Connect でこの問題を記録しました。POSTPOSTGET

于 2012-07-10T05:46:21.183 に答える
0

私に起こったとき post 、関数名にその単語を追加するだけで、問題は解決しました。多分それはあなたの何人かにも役立つでしょう。

于 2012-10-30T15:54:42.693 に答える
0

私が遭遇したケースでは、さらに別の原因がありました: 基になるコードがWebDAV PUTを実行しようとしていたことです。(この特定のアプリケーションは、必要に応じてこの機能を有効にするように構成できました。この機能は、私が知らないうちに有効になっていましたが、必要な Web サーバー環境がセットアップされていませんでした。

うまくいけば、これは他の誰かを助けるかもしれません。

于 2014-05-15T16:28:03.353 に答える