Note that there are some explanatory texts on larger screens.

plurals
  1. POHow Do I Configure a WCF Service to Be Called Via Cross-Domain AJAX
    primarykey
    data
    text
    <p>I'm having a little difficulty configuring my WCF service to allow consumption via cross-domain AJAX. </p> <p>I've successfully used this service on a client with no problems, but everytime I try to hit it using AJAX (via the $.ajax object in jQuery), I get a 400 error.</p> <p>Here is my web.config</p> <pre><code>&lt;?xml version="1.0"?&gt; &lt;configuration&gt; &lt;system.web&gt; &lt;compilation debug="true" strict="false" explicit="true" targetFramework="4.0" /&gt; &lt;/system.web&gt; &lt;system.serviceModel&gt; &lt;bindings&gt; &lt;basicHttpBinding&gt; &lt;binding name="basicHttpBinding" /&gt; &lt;/basicHttpBinding&gt; &lt;mexHttpBinding&gt; &lt;binding name="mexHttpBinding" /&gt; &lt;/mexHttpBinding&gt; &lt;webHttpBinding&gt; &lt;binding name="webHttpBinding" crossDomainScriptAccessEnabled="true"&gt; &lt;security mode="None" /&gt; &lt;/binding&gt; &lt;/webHttpBinding&gt; &lt;/bindings&gt; &lt;services&gt; &lt;service name="Services.WebAnalyticsService"&gt; &lt;clear /&gt; &lt;endpoint binding="basicHttpBinding" bindingConfiguration="basicHttpBinding" name="WebAnalyticsDotNetClientEndpoint" contract="Contracts.IWebAnalyticsService" listenUriMode="Explicit" /&gt; &lt;endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="mexHttpBinding" name="WebAnalyticsMetaDataEndpoint" contract="Contracts.IWebAnalyticsService" listenUriMode="Explicit" /&gt; &lt;endpoint address="script" behaviorConfiguration="aspNetAjaxBehavior" binding="webHttpBinding" bindingConfiguration="webHttpBinding" name="WebAnalyticsAjaxEndpoint" contract="Contracts.IWebAnalyticsService" /&gt; &lt;!--&lt;endpoint address="web" behaviorConfiguration="RESTBehavior" binding="webHttpBinding" bindingConfiguration="webHttpBinding" name="WebAnalyticsAjaxEndpoint" contract="Contracts.IWebAnalyticsServiceWeb" /&gt;--&gt; &lt;/service&gt; &lt;/services&gt; &lt;behaviors&gt; &lt;endpointBehaviors&gt; &lt;behavior name="aspNetAjaxBehavior"&gt; &lt;enableWebScript /&gt; &lt;/behavior&gt; &lt;!--&lt;behavior name="RESTBehavior"&gt; &lt;webHttp helpEnabled="true"/&gt; &lt;/behavior&gt;--&gt; &lt;/endpointBehaviors&gt; &lt;serviceBehaviors&gt; &lt;behavior&gt; &lt;serviceMetadata httpGetEnabled="true" /&gt; &lt;serviceDebug includeExceptionDetailInFaults="true" /&gt; &lt;/behavior&gt; &lt;/serviceBehaviors&gt; &lt;/behaviors&gt; &lt;serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/&gt; &lt;/system.serviceModel&gt; &lt;system.webServer&gt; &lt;modules runAllManagedModulesForAllRequests="true"/&gt; &lt;/system.webServer&gt; &lt;system.diagnostics&gt; &lt;sources&gt; &lt;source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true"&gt; &lt;listeners&gt; &lt;add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\log\Traces.svclog" /&gt; &lt;/listeners&gt; &lt;/source&gt; &lt;/sources&gt; &lt;/system.diagnostics&gt; &lt;/configuration&gt; </code></pre> <p>And this is my operation contract.</p> <pre><code>Namespace Contracts &lt;ServiceContract()&gt; Public Interface IWebAnalyticsService &lt;OperationContract(), WebGet(RequestFormat:=WebMessageFormat.Json)&gt; Sub SendWaEvent(ByVal eventID As Integer, ByVal eventValue As String, _ ByVal cookieVisitID As String, ByVal cookieVisitorSession As String, _ ByVal HTTPXForwardedServer As String, ByVal HTTPXRewriteURL As String, _ ByVal ScriptName As String, ByVal ServerName As String) End Interface End Namespace </code></pre> <p>My Ajax call is pretty straightforward, but here it is:</p> <pre><code>$.ajax({ type: 'POST', crossDomain: true, url: 'http://localhost:37490/services/webanalyticservice.svc/SendWaEvent', data: Data, //Data is a JSON wrapper I've previously constructed. contentType: 'application/javascript;charset=UTF-8' success: function(result) {DoSomething(result);}, error: HandleError }); </code></pre> <p>[<strong>UPDATES BELOW</strong>]</p> <p>It's always the things we overlook, isn't it? Anyhow, after being very dismissive of the "straightforward" AJAX call above, it ended up being the problem. To get this working, I had to change my AJAX call to this:</p> <pre><code> function SendAJAX() { $.ajax({ type: "GET", url: URL, data: Data, dataType: 'jsonp', jsonpCallback: 'MyCallBack', timeout: 10000, crossDomain: true, contentType: 'application/json; charset=UTF-8', success: function (data, textStatus, jqXHR) { WriteSuccess(data, textStatus, jqXHR) }, error: function (jqXHR, textStatus, errorThrown) { WriteError(jqXHR, textStatus, errorThrown) }, complete: function (jqXHR, textStatus) { } }); } </code></pre> <p>Also, please note that if you are going to be testing locally, you'll need to add the following to your web config or you'll receive a 500 error saying that cross-domain javascript isn't allowed in authenticated services. </p> <pre><code>&lt;system.web&gt; &lt;authentication mode="None" /&gt; &lt;/system.web&gt; </code></pre> <p>You can remove this attribute in your web.release.config using <code>xdt:transform</code>.</p> <p>Huge shout out to @Rajesh! Great job, man!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload