Errore WCF: 405 Metodo non consentito

Andando matto con questo problema. Ho una soluzione con 2 progetti, uno di questi è un semplice html vecchio con jquery chiamata ajax mentre l’altro è un servizio WCF. La pagina html invierà una chiamata ajax al servizio WCF per ottenere una stringa JSON e usarla a scopo di visualizzazione.

Ora il problema è quando vengo eseguito in modalità di debug, sia la pagina html che il WCF verranno avviati con una porta diversa. E questo ha creato per me un problema di origine incrociata quando eseguo il test (ovvero ricevo un errore 405 Metodo non consentito con il tipo di chiamata = OPZIONI in Firefox). Vorrei triplicare il metodo di chiamata sul mio script ajax e il servizio WCF è lo stesso (GET).

Cerco Google ma ho scoperto che devo installare un’estensione o eseguire alcune configurazioni su IIS, che ho trovato ingombrante dal momento che quello che sto facendo è qualcosa di semplice. Seguendo un esempio, aggiungerei la seguente configurazione nel mio web.config ma non ha funzionato:

                                      

Qualcuno ha qualche idea per sbarazzarsi di questo fastidioso problema?

EDIT: Solo per aggiungere, sto eseguendo il debug con IIS Express che viene fornito con VS Studio 2012

Aggiungi nel codice WCF e aggiornato web.config

 [ServiceContract] public interface IMemberInfo { [WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json )] [OperationContract] string GetMemberInfoById(); // TODO: Add your service operations here } 

My Script:

 $(document).ready(function () { $.ajax("http://localhost:32972/SimpleMemberInfo.svc/GetMemberInfoById", { cache: false, beforeSend: function (xhr) { $.mobile.showPageLoadingMsg(); }, complete: function () { $.mobile.hidePageLoadingMsg(); }, contentType: 'application/json', dataType: 'json', type: 'GET', error: function () { alert('Something awful happened'); }, success: function (data) { var s = ""; s += "
  • " + data + "
  • "; $("#myList").html(s); } }); });

    È necessario utilizzare JSONP per una chiamata tra domini per aggirare le restrizioni del browser e per aggiornare il proprio web.config con crossDomainScriptAccessEnabled impostato su true per aggirare quelli del server. C’è un buon esempio nella risposta qui: come evitare la politica del dominio incrociato in jQuery ajax per il consumo del servizio wcf?

    Potresti anche avere un problema con le richieste GET. Prova le correzioni delineate qui: Realizzare un servizio Web WCF funziona con le richieste GET

    Nel complesso, si desidera un web.config simile a questo:

                            

    (Si noti che sia il servizio che l’endpoint hanno dei comportamenti collegati, consentendo rispettivamente le chiamate webHttp e httpGet e che l’associazione ha l’accesso crossDomain abilitato esplicitamente).

    … un metodo di servizio decorato in questo modo:

     [ServiceContract] public interface IMyService { [WebGet] // Required Attribute to allow GET [OperationContract] string MyMethod(string MyParam); } 

    … e una chiamata client usando JSONP:

      

    Comunque è un vecchio thread, ma vorrei aggiungere il mio commento sui problemi che ho affrontato e la soluzione che ho ottenuto per il lavoro di CORS. Sto sviluppando un servizio Web nel seguente ambiente:

    1. Servizio web WCF.
    2. .NET 3.5 framework.
    3. Aggiunto il servizio web WCF nel sito web asp.net esistente.
    4. Visual Studio 2008

    La maggior parte delle persone ha menzionato l’aggiunta dell’attributo crossDomainScriptAccessEnabled nel tag in in web.config. Non sono sicuro che funzioni o meno, ma non è disponibile nella versione 3.5, quindi non ho avuto scelta. Ho anche scoperto che l’aggiunta dei seguenti tag in web.config funzionerà …

    ma senza fortuna … continuava a ricevere il metodo 405 con errori non permessi

    Dopo aver faticato parecchio con queste opzioni ho trovato un’altra soluzione per aggiungere queste intestazioni nel file global.asax in modo dinamico come indicato di seguito …

     protected void Application_BeginRequest(object sender, EventArgs e) { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); if (HttpContext.Current.Request.HttpMethod == "OPTIONS") { HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization"); HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); HttpContext.Current.Response.End(); } } 

    E rimuovere il da web.config. Pubblica il sito web e continua con il lato client jquery / ajax … e otterrai i dati dalle chiamate API. In bocca al lupo!

    Volevo semplicemente aggiungere alcuni problemi con la rielaborazione di CORS in basso. Il problema è che se il tuo input non supporta il metodo GET e POST, la richiesta OPTIONS non restituisce effettivamente le intestazioni consentite corrette. In realtà non sta guardando quali metodi sono effettivamente consentiti sull’endpoint WCF – è solo artificialmente dicendo che “GET, POST” sono consentiti per ogni singolo endpoint nell’applicazione quando un client esegue una richiesta OPTIONS (che è in realtà il client che chiede cosa è supportato).

    Questo è probabilmente OK, se non stai facendo affidamento sulle informazioni nel metodo OPTIONS per restituirti un elenco valido di metodi (come nel caso di alcune richieste CORS) – ma se lo sei, dovrai fare qualcosa come la soluzione su questa domanda: come gestire la richiesta Ajax JQUERY POST con l’auto-host WCF

    Fondamentalmente, ciascun endpoint dovrebbe implementare:

    Webinvoke(Method="OPTIONS", UriTemplate="")

    e chiamare un metodo appropriato che carica le intestazioni corrette per la risposta (incluso l’elenco “Access-Control-Allow-Method” corretto per quell’endpoint) al chiamante. È una specie di succhiare che gli endpoint WCF ospitati non lo fanno automaticamente per noi, ma questa è una soluzione che consente un controllo più preciso sull’endpoint. In quella soluzione vengono caricate le intestazioni di risposta corrette all’implementazione dell’endpoint:

     public void GetOptions() { // The data loaded in these headers should match whatever it is you support on the endpoint // for your application. // For Origin: The "*" should really be a list of valid cross site domains for better security // For Methods: The list should be the list of support methods for the endpoint // For Allowed Headers: The list should be the supported header for your application WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*"); WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization"); } 

    prova ad usare. WebInvoke(Method = "POST") anziché WebInvoke(Method = "GET")