wake-up-neo.com

So fügen Sie domänenübergreifende Unterstützung zum WCF-Dienst hinzu

Ich versuche, POST -Anfragen von meiner bei localhost gehosteten Javascript-App an einen WCF-REStful-Dienst zu erlauben, der an einem anderen Port gehostet wird, aber irgendwie funktioniert es nicht. Ich habe versucht, dem Header benutzerdefinierte Eigenschaften hinzuzufügen, und zwar programmgesteuert in die JSONData-Methode meines Services, aber in meiner Antwort wird immer noch die "405-Methode nicht zulässig" angezeigt. Was ist der richtige Ansatz hier? 

Das ist meine Schnittstelle:

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

und den Servicecode:

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

Und zum Schluss noch die config:

<?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>
18
mike_hornbeck

Das hat für mich besser funktioniert als die Web.config-Version:

Erstellen Sie einen Global.asax

Fügen Sie diese Methode dem Global.asax.cs hinzu:

using System.Web;

namespace StackOverflow
{
    public class Global : System.Web.HttpApplication
    {
        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();
            }
        }
    }
}

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

26
Akira Yamamoto

Fügen Sie diese Knoten zu Ihrer Web.config hinzu:

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

Ref: http://theagilecoder.wordpress.com/2014/07/07/wcf-und-cors-no-access-control-allow-Origin-header-ispresent-on-the-requested-resource/

11
Akira Yamamoto

Das Aktivieren von CORS für Nicht-GET-Anforderungen erfordert mehr als nur das Festlegen des Access-Control-Allow-Origin-Headers. Außerdem muss mit preflight -Anfragen gearbeitet werden. Hierbei handelt es sich um OPTIONS-Anforderungen, mit denen der Server gefragt wird, ob Operationen ausgeführt werden können, die möglicherweise Daten ändern können (z. B. POST, PUT, DELETE), bevor die aktuelle Anforderung gesendet wird.

Ich habe einen Blogbeitrag über das Hinzufügen von CORS-Unterstützung für WCF geschrieben. Dies ist nicht die einfachste der Implementierungen, aber hoffentlich kann der Code im Beitrag einfach in Ihr Projekt kopiert/eingefügt werden. Der Beitrag kann unter http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx - gefunden werden.

9
carlosfigueira

Der folgende .NET-Code (global.asax) hat den wichtigen Unterschied, dass es anstelle von * besser ist, die Ursprungsdomäne zurückzusetzen, da dies die Authentifizierung über CORS (z. B. NTLM/Kerberos) sowie das Preflight ermöglicht. 

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" , "*");
    }
}
0
QA Collective