Results 1 to 3 of 3

Thread: Using Ajax with WCF and CORS enabled.

  1. #1

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,684

    Using Ajax with WCF and CORS enabled.

    Had a lot of trouble configuring this so I am writing it out in case anyone wants to do the same.
    This is a WCF - POST-GET enabled WCF service app that will be called through Ajax - Json. This requires to have CORS enabled , so this is the "simplest" example , without having to overload CustomHeaderMessageInspector and EnableCrossOriginResourceSharingBehavior. I am not sure if this will work in another domain as I have only tested locally on Local IIS and Cassini. Should work but then again...WCF...

    So here is the service:
    Global.asax:
    Code:
    Imports System.Web.SessionState
    
    Public Class Global_asax
        Inherits System.Web.HttpApplication
    
        Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
            ' Fires when the application is started
        End Sub
    
        Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
            ' Fires when the session is started
        End Sub
    
        Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*")
            If HttpContext.Current.Request.HttpMethod = "OPTIONS" Then
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE")
    
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept")
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000")
                HttpContext.Current.Response.End()
            End If
            ' Fires at the beginning of each request
        End Sub
    
        Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
            ' Fires upon attempting to authenticate the use
        End Sub
    
        Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
            ' Fires when an error occurs
        End Sub
    
        Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
            ' Fires when the session ends
        End Sub
    
        Sub Application_End(ByVal sender As Object, ByVal e As EventArgs)
            ' Fires when the application ends
        End Sub
    
    End Class
    web.config:
    Code:
    <?xml version="1.0"?>
    <configuration>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
        <services>
          <service behaviorConfiguration="Default" name="WcfService1.Service1">
            <endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" contract="WcfService1.IService1" />
            <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
          </service>
        </services>
        <behaviors>
    
          <endpointBehaviors>
            <behavior name="webBehavior">
              <webHttp helpEnabled="true" />
            </behavior>
          </endpointBehaviors>
    
          <serviceBehaviors>
            <behavior name="Default">
              <serviceMetadata httpGetEnabled="true" />
            </behavior>
            <behavior name="">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>      
          </serviceBehaviors>
        </behaviors>
     
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>   
      </system.webServer>
    
    </configuration>
    Iservice1:
    Code:
    ' NOTE: You can use the "Rename" command on the context menu to change the interface name "IService1" in both code and config file together.
    <System.Web.Script.Services.ScriptService()> _
    <ServiceContract()>
    Public Interface IService1
    
    
        ' TODO: Add your service operations here
        <OperationContract()>
        Function GetMedicalHistory() As String
    
    End Interface
    
    ' Use a data contract as illustrated in the sample below to add composite types to service operations.
    Service1.vb
    Code:
    Imports System.ServiceModel.Activation
    
    ' NOTE: You can use the "Rename" command on the context menu to change the class name "Service1" in code, svc and config file together.
    <AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)> _
    Public Class Service1
        Implements IService1
    
        ' Public Sub New()
        ' End Sub
    
    
    
        <WebInvoke(Method:="POST", RequestFormat:=WebMessageFormat.Json, ResponseFormat:=WebMessageFormat.Json, UriTemplate:="/GetMedicalHistory")>
        Function GetMedicalHistory() As String Implements IService1.GetMedicalHistory      
            Return "x"
        End Function
    End Class
    ....
    Create a asp.net project and change the localhost in whatever is correct.

    Code:
    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <script src="javascript/jquery-1.11.2.min.js" type="text/javascript"></script>
         <script type="text/javascript">
             $(document).ready(function () {
                 getMedicalHistory();
             });
    
             function getMedicalHistory() {          
    
                 $.ajax({
                     url: 'http://localhost:45156/Service1.svc/GetMedicalHistory',
                     // of 'http://localhost/WcfService1/service1.svc/GetMedicalHistory' // for Local IIS
                     type: 'POST',
                     data: '{}',
                     dataType: 'json',
                     contentType: "application/json; charset=utf-8",
                     success: function (res) {
                         alert('d');
                         console.log("Success");
                         console.log(res);
                         $('#result').html(res.d);
                     },
                     error: function (res) {
                         alert(res);
                         console.log("Error! " + res.statusText);
                     }
                 });
             }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        
        </div>
        </form>
    </body>
    </html>
    Note this is a simple Ajax call just to see that your WCF breakpoint is hit and running and an alert to see that actually goes to function success, you won't get any data, you need to set up your Ajax and WCF service properly afterwards.
    Last edited by sapator; Apr 29th, 2015 at 03:27 AM.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  2. #2

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,684

    Re: Using Ajax with WCF and CORS enabled.

    Note that i use HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*") , "*" should be the server domain that will be allowed but since I had trouble configure this, I used "*" so it can work. So change accordingly if you can fix that.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  3. #3

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,684

    Re: Using Ajax with WCF and CORS enabled.

    Seems that this is also true for simple asp.net web services and not only WCF.
    Careful as the global.asax is in a "<script"> tag environment but basically it's the same code.
    I had to enable the post and get commands in web.config but that can be found in the server event viewer when you get something as a "URL cannot be resolved" error, the domain issue will not be written to event viewer as I can observe.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width