2012-12-26 18 views
15

Sto tentando di consentire le richieste POST dalla mia app javascript ospitata su localhost: 80 a un servizio REStful WCF ospitato su una porta diversa, ma in qualche modo non funziona. Ho provato ad aggiungere proprietà personalizzate all'intestazione, nonché ad aggiungerlo in modo programmatico al metodo JSONData del mio servizio, ma nella mia risposta sto ancora ottenendo "Metodo 405 non consentito". Qual è l'approccio corretto qui?Come aggiungere il supporto del dominio incrociato al servizio WCF

Questa è la mia interfaccia:

namespace RestService 
{ 
    public class RestServiceImpl : IRestServiceImpl 
    { 
     #region IRestServiceImpl Members 

     public string JSONData() 
     { 
      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
      return "Your POST request"; 
     } 

     #endregion 
    } 
} 

e il codice di servizio:

using System.ServiceModel; 
using System.ServiceModel.Web; 
using System.Web.Script.Services; 

namespace RestService 
{ 

    [ServiceContract] 
    public interface IRestServiceImpl 
    { 
     [OperationContract] 
     [ScriptMethod] 
     [WebInvoke(Method = "POST", 
      ResponseFormat = WebMessageFormat.Json, 
      BodyStyle = WebMessageBodyStyle.Bare, 
      UriTemplate = "export")] 
     string JSONData(); 
    } 
} 

E infine la configurazione:

<?xml version="1.0"?> 
<configuration> 

    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
    <services> 
     <service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour"> 
     <endpoint address ="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web"> 
     </endpoint> 
     </service> 
    </services> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior name="ServiceBehaviour"> 
      <serviceMetadata httpGetEnabled="true"/> 
      <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="web"> 
      <webHttp/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    <httpProtocol> 
     <customHeaders> 
     <add name="Access-Control-Allow-Origin" value="*" /> 
     </customHeaders> 
</httpProtocol> 
    </system.webServer> 

</configuration> 
+0

Sarebbe una buona domanda se si descriva cosa significa "ma in qualche modo non funziona". –

+0

Ho aggiornato la descrizione. –

risposta

17

Questo ha funzionato meglio per me rispetto alla versione web.config:

Crea una Global.asax

Aggiungere questo codice a t egli Global.asax.cs:

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("Access-Control-Allow-Methods", "GET, POST"); 
     HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
     HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); 
     HttpContext.Current.Response.End(); 
    } 
} 

http://www.dotnet-tricks.com/Tutorial/wcf/X8QN260412-Calling-Cross-Domain-WCF-Service-using-Jquery.html

+0

Cool, grazie per essere ancora qui amico! –

+0

Grazie mille! finalmente ho trovato la soluzione esatta, dopo aver cercato molto. – Vikrant

+0

Ottimo questo finalmente ha funzionato dopo un paio d'ore di ricerche. Grazie bru! –

7

Abilitazione CORS per non richieste GET richiede più di semplicemente impostando l'intestazione Access-Control-Allow-Origin - deve anche occuparsi di preflight richieste, che sono richieste OPTIONS che richiedono al server se è possibile eseguire operazioni che potenzialmente possono modificare dati (ad esempio, POST, PUT, DELETE) prima che venga inviata la richiesta effettiva.

Ho scritto un post sul blog sull'aggiunta del supporto CORS per WCF. Non è la più semplice delle implementazioni, ma si spera che il codice nel post possa essere semplicemente copiato/incollato nel progetto. Il post può essere trovato a http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx.

+0

Questo è quasi quello di cui ho bisogno. Ma ho notato che non funziona se si inviano i dati come un json. La tua pagina exabple invia un singolo valore di stringa con la richiesta POST. O forse perché ExtJS gestisce i dati della richiesta in modo diverso da jQuery:/ –

+0

L'esempio invia i dati come JSON - gli input per i metodi POST/PUT sono * stringhe JSON * (si noti che l'input è racchiuso tra '' ''s) Funziona anche per gli oggetti, è solo che nell'esempio l'operazione prende una stringa come parametro. – carlosfigueira

+0

Ho modificato i dati nella pagina di test a 'var data = { foo:" bar " };' e ottengo 400 richieste non valide. Ho controllato i registri ma non ci sono stati utili. Quindi dovrei apportare modifiche anche alla WCF stessa per supportarla? –

4

UPDATE:

Aggiungi questi nodi al vostro web.config:

<configuration> 
    <system.webServer> 
    <httpProtocol> 
     <customHeaders> 
     <add name="Access-Control-Allow-Origin" value="*"/> 
     <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" /> 
     <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" /> 
     <add name="Access-Control-Max-Age" value="1728000" /> 
     </customHeaders> 
    </httpProtocol> 
    </system.webServer> 
</configuration> 

http://theagilecoder.wordpress.com/2014/07/07/wcf-and-cors-no-access-control-allow-origin-header-is-present-on-the-requested-resource/

+0

ha funzionato perfetto per me! – FranP

0

Il seguente codice .NET (global.asax) ha un importante differenza che al posto di *, può essere meglio per riprendere indietro il dominio di origine, perché questo consente l'autenticazione su CORS (es NTLM/Kerberos) nonché Preflight.

void Application_BeginRequest(object sender, EventArgs e) 
{ 
    if (Request.HttpMethod == "OPTIONS") 
    { 
     Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); 
     Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
     Response.AddHeader("Access-Control-Max-Age", "1728000"); 
     Response.End(); 
    } 
    else 
    { 
     Response.AddHeader("Access-Control-Allow-Credentials", "true"); 

     if (Request.Headers["Origin"] != null) 
      Response.AddHeader("Access-Control-Allow-Origin" , Request.Headers["Origin"]); 
     else 
      Response.AddHeader("Access-Control-Allow-Origin" , "*"); 
    } 
} 
Problemi correlati