2012-04-13 21 views
6

Questa domanda è già stata posta altrove, ma quelle cose non sono le soluzioni per il mio problema.Il server remoto ha restituito un errore: (405) Metodo non consentito. Servizio WCF REST

Questo è il mio servizio

[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(); 
} 

Ho questo codice per chiamare il servizio di cui sopra

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(); 

ottengo un'eccezione durante l'ultima riga:

Il server remoto ha restituito un errore : (405) Metodo non consentito. Non so perché questo sta accadendo ho provato a cambiare l'host da VS Server a IIS, ma nessun cambiamento nel risultato. Fammi sapere se hai bisogno di ulteriori informazioni

+0

cosa fare.. assomiglia ai tuoi percorsi? –

+0

Aggiungi qualsiasi configurazione di configurazione/codice di binding che stai utilizzando. –

+0

Stai impostando contenttype su "application/x-www-form-urlencoded", ma stai inviando dati xml. Puoi impostare il tipo di contenuto su " application/xml " – Chandermani

risposta

2

Stai eseguendo l'applicazione WCF per la prima volta?

eseguire sotto il comando per registrare wcf.

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

Per prima cosa è necessario conoscere l'URL esatto del servizio REST. Dato che hai specificato http://localhost:2517/Service1/Create ora prova ad aprire lo stesso URL da IE e dovresti ottenere il metodo non consentito poiché il tuo metodo Create è definito per WebInvoke e IE esegue un WebGet.

Ora assicurati di avere SampleItem nell'app client definita nello stesso spazio dei nomi sul tuo server o assicurati che la stringa xml che stai creando abbia lo spazio dei nomi appropriato per il servizio per identificare la stringa xml dell'oggetto campione può essere deserializzato di nuovo all'oggetto sul server.

ho la SampleItem definito sul mio server come illustrato di seguito:

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

la stringa XML che corrisponde al mio SampleItem è come qui sotto:

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

ora uso il metodo seguente per eseguire una POST al servizio 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; 
     } 

Ora chiamo il metodo precedente come mostrato:

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

ho l'oggetto SampleItem definito nel lato client. Se si vuole costruire la stringa XML sul client e passare quindi è possibile utilizzare il seguente metodo:

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

E la chiamata al metodo di cui sopra sarebbe come illustrato di seguito:

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

NOTA: Assicurati che il tuo URL sia corretto

+0

I get get Il server remoto ha restituito un errore: (405) Metodo non consentito – Praneeth

+0

Come viene ospitato il servizio? Avete una voce nel global.a sax. Controlla anche se hai la pagina di aiuto abilitata e provi a cercare l'url per il metodo che stai cercando di pubblicare e vedi che l'url è corretto. – Rajesh

+0

aiuto sta funzionando posso vedere i servizi nel browser e ottenere sta funzionando nel browser. Il servizio è ospitato tramite VS Server e ho percorsi registrati nella global.asax – Praneeth

1

Dopo aver trascorso 2 giorni su questo, utilizzando VS 2010 .NET 4.0, IIS 7.5 WCF e REST con JSON ResponseWrapped, ho finalmente risolto il problema leggendo da "Quando si investiga ulteriormente ..." qui https://sites.google.com/site/wcfpandu/useful-links

Il file generato dal codice client del servizio Web Riferimento.cs non attribuisce i metodi GET con [WebGet()], quindi tenta di sostituirli con POST, quindi il metodo InvalidProtocol, 405 Metodo non consentito. Il problema è che, questo file viene rigenerato ogni volta che si aggiorna il riferimento al servizio e occorre anche un riferimento a dll a System.ServiceModel.Web, per l'attributo WebGet.

Quindi ho deciso di modificare manualmente il file Reference.cs e di conservarne una copia. La prossima volta che aggiornarlo, io unire la mia WebGet()s indietro nel.

Il mio modo di vedere, si tratta di un bug con non svcutil.exe riconoscendo che alcuni dei metodi di servizio sono GET e non solo POST, anche se il WSDL e HELP che pubblica il servizio Web IIS di WCF, quali sono i metodi disponibili POST e GET ??? Ho registrato questo problema con Microsoft Connect.

0

Quando è successo a me, ho semplicemente aggiunto la parola post al nome della funzione, e ha risolto il mio problema. forse aiuterà anche alcuni di voi.

0

Nel caso in cui mi sono imbattuto, c'era un'altra causa: il codice sottostante stava tentando di fare un PUT WebDAV. (Questa particolare applicazione è configurabile per attivare questa funzione, se necessario, la funzione era, a mia insaputa, ha permesso, ma l'ambiente web server necessario non è stato istituito

Speriamo che questo possa aiutare qualcun altro

Problemi correlati