Matthew
Matthew

Reputation: 4607

Calling WCF Service using jQuery AJAX

I have the following WCF service.

Interface Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;

namespace CalculatorWebService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "ICalculatorService" in both code and config file together.
    [ServiceContract]
    public interface ICalculatorService
    {
        [OperationContract]
        [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat= WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        int Addition(int firstNumber, int secondNumber);

        [OperationContract]
        [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        int Subtraction(int firstNumber, int secondNumber);
    }
}

SVC code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace CalculatorWebService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "CalculatorService" in code, svc and config file together.
    public class CalculatorService : ICalculatorService
    {
        public int Addition(int firstNumber, int secondNumber)
        {
            return firstNumber + secondNumber;
        }

        public int Subtraction(int firstNumber, int secondNumber)
        {
            return firstNumber - secondNumber;
        }
    }
}

Now, I have the following HTML page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HomePageWithAjax.aspx.cs" Inherits="CalculatorWebService.HomePageWithAjax" %>

<!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="http://localhost:12345/js/jquery-1.11.2.min.js" type="text/javascript"></script>
    <script src="http://localhost:12345/js/ajaxScript.js" type="text/javascript"></script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <label>Number 1:&nbsp;</label>
        <label ID="labelFirstNumber"></label>
        <br />

        <label>Number 2:&nbsp;</label>
        <label ID="labelSecondNumber"></label>
        <br />
        <br />

        <label>Addition:&nbsp;</label>
        <label ID="labelAddition"></label>
        <br />

        <label>Subtraction:&nbsp;</label>
        <label ID="labelSubtraction"></label>
        <br />
    </div>
    </form>
</body>
</html>

And this is the script which is making the call to the WCF service:

function generateRandomNumber()
{
    var number = Math.floor((Math.random() * 100) + 1);
    return number;
}

function getNumber(labelName) {
    return $(labelName).text();
}

function setNumber(labelName, number)
{
    $(labelName).text(number);
}

function addition() {
    var input = new Object();
    input.firstNumber = getNumber("#labelFirstNumber");
    input.secondNumber = getNumber("#labelSecondNumber");

    $.ajax({
        type: "POST",
        url: "/CalculatorService.svc/Addition",
        data: JSON.stringify(input),
        contentType: 'application/json; charset=utf-8',
        dataType: "json",
        success: function (result) {
            setNumber("#labelAddition", result);
        },
        error: function (response, status, error) {
            alert(response.statusText);
        }
    });
}

function subtraction() {
    var input = new Object();
    input.firstNumber = getNumber("#labelFirstNumber");
    input.secondNumber = getNumber("#labelSecondNumber");

    $.ajax({
        type: "POST",
        url: "/CalculatorService.svc/Subtraction",
        data: JSON.stringify(input),
        contentType: 'application/json; charset=utf-8',
        dataType: "json",
        success: function (result) {
            setNumber("#labelSubtraction", result);
        },
        error: function (response, status, error) {
            alert(response.statusText);
        }
    });
}

$(document).ready(function () {
    var firstNumber = generateRandomNumber();
    var secondNumber = generateRandomNumber();

    setNumber("#labelFirstNumber", firstNumber);
    setNumber("#labelSecondNumber", secondNumber);

    addition();
    subtraction();
});

This is the Web.config:

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

  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="CalculatorWebService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

 <applicationSettings>
  <CalculatorWebService.Properties.Settings>
   <setting name="CalculatorWebService_CalculatorServiceReference_CalculatorService"
    serializeAs="String">
    <value>http://localhost:12345/CalculatorService.svc</value>
   </setting>
  </CalculatorWebService.Properties.Settings>
 </applicationSettings>
</configuration>

Now, for some reason or another, both the call to the addition web service method and the subtraction web service method are returning the following error:

Unsupported Media Type

Why is it returning this error? I think that the web service should know that it is expecting JSON since:

  1. I specified the input as JSON (contentType field)
  2. I specified the output as JSON (dataType field)
  3. I specified request and response type as JSON in the web service interface

What am I missing please?

Thank you very much.

Note:

The WCF Service that I am using is NOT an AJAX-enabled WCF Service. Could this be the problem? Is it possible to make it AJAX-enabled by modifying the Web.config file for example?

Upvotes: 1

Views: 1602

Answers (1)

moarboilerplate
moarboilerplate

Reputation: 1643

You have to add the following attribute to your service to allow it to be called through the HTTP pipeline: [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

or in config under system.serviceModel:

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

Then you can either add a servicereference in your ScriptManager or call the proxy endpoint like you're doing.

If you can't change your service or you have problems with changing the service, you could always call a page method from your client by decorating a codebehind method with [WebMethod] and then do your service call in there too.

Upvotes: 1

Related Questions