开发者

Send JSON to WCF 3.5 using Ajax

I'm having issues passing JSON to the Weight method. I keep getting HTTP/1.1 415 Cannot process the message because the content type 'application/x-www-form-urlencoded; charset=UTF-8' was not the expected type 'text/xml; charset=utf-8'.

I think I have a problem with either my contract or web.config. All my research turns up empty. I'll be calling this service from a Web Part using jQuery's $.ajax.

Interface:

namespace XXX.SharePoint.WebServices
{
    [ServiceContract]
    public interface ICalculators
    {

        [OperationContract]
        [WebInvoke(Method = "POST",
                   BodyStyle = WebMessageBodyStyle.WrappedRequest,
                   RequestFormat = WebMessageFormat.Json,
                   ResponseFormat = WebMessageFormat.Json
        )]
        Single Weight(Single Width, Single Diameter, Single Size, Single Factor);
    }
}

web.config:

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="XXX.SharePoint.WebServices.CustomServiceBehaviour"
        name="XXX.SharePoint.WebServices.Calculators">
        <endpoint address=""
                  binding="basicHttpBinding"
                  contract="XXX.SharePoint.WebServices.ICalculators" >
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://moss2010/"></add>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
     开发者_如何学JAVA <serviceBehaviors>
        <behavior name="XXX.SharePoint.WebServices.CustomServiceBehaviour">
          <!-- 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>
  </system.serviceModel>
</configuration>

As always, thanks in advance!


Here's a full working example of a WCF service hosted in IIS:

[ServiceContract]
public interface ICalculators
{
    [OperationContract]
    [WebInvoke(Method = "POST",
               BodyStyle = WebMessageBodyStyle.Wrapped,
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json
    )]
    float Weight(float width, float diameter, float size, float factor);
}

public class Calculators : ICalculators
{
    public float Weight(float width, float diameter, float size, float factor)
    {
        return 10f;
    }
}

calculators.svc:

<%@ 
    ServiceHost 
    Language="C#" 
    Debug="true" 
    Service="XXX.SharePoint.WebServices.Calculators" 
    Factory="System.ServiceModel.Activation.WebServiceHostFactory"
    CodeBehind="Calculators.svc.cs" 
%>

web.config:

<system.serviceModel>
    <services>
        <service 
            behaviorConfiguration="XXX.SharePoint.WebServices.CustomServiceBehaviour"
            name="XXX.SharePoint.WebServices.Calculators">
                <endpoint 
                    address=""
                    binding="webHttpBinding"
                    contract="XXX.SharePoint.WebServices.ICalculators"
                />
                <endpoint 
                    address="mex" 
                    binding="mexHttpBinding" 
                    contract="IMetadataExchange" 
                />
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="XXX.SharePoint.WebServices.CustomServiceBehaviour">
                <serviceMetadata httpGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>  

Consumption using jQuery in the same ASP.NET application:

$.ajax({
    url: '/calculators.svc/Weight',
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify({ Width: 1.2, Diameter: 2.3, Size: 3.4, Factor: 4.5 }),
    success: function (result) {
        alert(result.WeightResult);
    }
});

Notice the usage of webHttpBinding instead of basicHttpBinding (SOAP) in web.config as well as the special WebServiceHostFactory used in the .svc file.


You're sending a request which uses the forms/url-encoded content type (the default for jQuery.ajax when the value of the data member is an object), which is not supported by default by WCF. You can either change it to send JSON as suggested by Darin Dimitrov, change your service operation to take a Stream as a parameter and parse the input yourself, or extend WCF to support forms/url-encoded data. I've posted a sample in another question (at RESTful WCF web service POST problem) which does the latter.

Also, the preview for "jQuery support" from http://wcf.codeplex.com has some code which supports that content type as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜