Search code examples
c#ajaxwcfgetjson

How to consume WCF service methods by ajax getJSON?


It's a code that was created in Visual Studio 2013 by default wizard. In project properties I set it to use Local IIS. WCF Test Client test it successfully. In the same project I added html page, which trying to get method by getJSON, but I'm getting and error "Not Found" from .fail section What should I modify in order to consume it by getJSON? Note: I understand method GetTime is also "invisible" in browser ("400 Bad Request"), and I need to configure endpoints, I looked it up, but my attempts unsuccessful..

IService1.cs

using System.Runtime.Serialization;
using System.ServiceModel;
namespace WcfService1
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetTime();
    }
}

Service1.svc.cs

using System;
namespace WcfService1
{
    public class Service1 : IService1
    {
        public string GetTime()
        {
            return DateTime.Now.ToShortTimeString();
        }
    }
}

web.config

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

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

HTMLPage1.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
    <body>
        <div>
            <span id="jspan"></span>
        </div>
</html>

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
    $(document).ready(function () {
        var prom = $.getJSON("http://localhost/Service1.svc/GetTime");

        prom.done(function (data) {
            $("#jspan").text("data: " + data.d);
        })
            .fail(function (data) {
                $("#jspan").text("error: " + data.statusText);
            });

    });
</script>

Solution

  • In order to access web service method by ajax, I need to be able to access it by http (to see it in the browser). So first step is to configure web service behavior for this. I answered on it here: How to access WCF service methods from browser? Then we call our ajax method "as usual". Code attached below.

    IService1.cs

    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    namespace WcfService1
    {
        [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            [WebGet]
            string GetTime();
        }
    }
    

    web.config

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
      </appSettings>
      <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5"/>
      </system.web>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
    
          **<!--added behavior-->
          <endpointBehaviors>
            <behavior name="WcfService1.Service1AspNetAjaxBehavior">
              <enableWebScript />
            </behavior>
          </endpointBehaviors>**
    
        </behaviors>
        <protocolMapping>
            <add binding="basicHttpsBinding" scheme="https" />
        </protocolMapping>
    
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    
        **<!--added service behaviour configuration-->
        <services>
          <service name="WcfService1.Service1">
            <endpoint address="" behaviorConfiguration="WcfService1.Service1AspNetAjaxBehavior"
              binding="webHttpBinding" contract="WcfService1.IService1" />
          </service>
        </services>**
    
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <directoryBrowse enabled="true"/>
      </system.webServer>
    
    </configuration>
    

    HtmlPage1.html with java script

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
    </head>
        <body>
            <div>
                <span id="jspan"></span>
            </div>
        </body>
    </html>
    
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script>
        $(document).ready(function () {
            var prom = $.getJSON("http://localhost/WcfService1/Service1.svc/GetTime");
    
            prom.done(function (data) {
                $("#jspan").text("data: " + data.d);
            })
                .fail(function (data) {
                    $("#jspan").text("error: " + data.statusText);
                });
    
        });
    </script>
    

    result should look like this:

    Client app and method in the browser screen shot