Quantcast
Viewing all articles
Browse latest Browse all 28

A Complete Example of WCF,Ajax, SSL and None SSL

Here is a complete example of using wcf and ajax via JQuery, the configuration for wcf under ssl is also included.

Client : javascript code

<script type="text/javascript">

        $(document).ready(function () {

            var userid = {
                'id': 1
            };


            $.ajax({
                type: 'GET', //GET or POST or PUT or DELETE verb
                url: 'Service.svc/GetPerson', // Location of the service
                data: userid, //Data sent to server
                contentType: 'application/json; charset=utf-8', // content type sent to server
                dataType: 'json', //Expected data format from server
                processdata: true, //True or False
                success: function (data) {//On Successfull service call
                    alert(data.Name);
                },
                error: function (msg) {// When Service call fails
                    alert(msg);
                }
            });

            var user = {
                id: 2,
                name: 'John Smith'
            };



            $.ajax({
                type: 'POST', //GET or POST or PUT or DELETE verb
                url: 'Service.svc/SavePerson', // Location of the service
                data: JSON.stringify(user), //Data sent to server
                contentType: 'application/json; charset=utf-8', // content type sent to server
                dataType: 'json', //Expected data format from server
                processdata: true, //True or False
                success: function (data) {//On Successfull service call
                    alert(data);
                },
                error: function (msg) {// When Service call fails
                    alert(msg);
                }
            });


        });
    </script>

It is using JQuery.ajax, when using POST, it must be stringfied as JSON string, rather than javascript object, when it is sent as an object you will get error:

The server encountered an error processing the request. The exception message is ‘The formatter threw an exception while trying to deserialize the message: Error in deserializing body of request message for operation ‘xxxxx’. Encountered unexpected character ‘x’.’.

Try not to use JQuery.get() or JQuery.post() as they are special cases of JQuery.ajax, and does not allow you change content type or add error handlings. As default the content type for JQuery.post is “application/x-www-form-urlencoded; charset=UTF-8″

Server: service code

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode =
        AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehaviorAttribute(IncludeExceptionDetailInFaults = true)]
public class Service
{
    [OperationContract]
    [WebInvoke(
          Method = "GET",
          ResponseFormat = WebMessageFormat.Json)]
    public Person GetPerson(int id)
    {
        return new Person { ID = id.ToString(), Name = "John Smith" };
    }

    [OperationContract]
    [WebInvoke(
        Method = "POST", 
        BodyStyle = WebMessageBodyStyle.WrappedRequest, 
        ResponseFormat = WebMessageFormat.Json)]
    public string SavePerson(int id, string name)
    {
        return name + "-" + id.ToString();
    }
}

[DataContract]
public class Person
{
    [DataMember]
    public string ID { get; set; }

    [DataMember]
    public string Name { get; set; }

}

When using POST method, BodyStyle should use WrappedRequest only, otherwise the result could be wrapped by method name.

Enable logging using diagnostics

<configuration>
<system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Error">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "Traces.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
  
</configuration>

switchValue can enable logging on different level
initlializeData is the file name

Choose which binding of wcf to use for ajax

webHttpBinding : is the REST-style binding, where you basically just hit a URL and get back a truckload of XML or JSON from the web service

This is used by Ajax calls, as other two types are SOAP based

basicHttpBinding and wsHttpBinding are two SOAP-based bindings which is quite different from REST.

Services of these two bindings cannot be consumed by ajax

For WCF through none ssl aka http:

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
       multipleSiteBindingsEnabled="true" />

  <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="EndPointBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="ServiceBehavior" name="Service">
        <endpoint address="" binding="webHttpBinding" contract="Service" behaviorConfiguration="EndPointBehavior"/>
      </service>
    </services>
   
  </system.serviceModel>

So ajax will get an object like:

{“ID”:”1″,”Name”:”John Smith”}

You might use instead of as the end point behaviour, ajax result will be wrapped under ‘d’ node like:

{“d”:{“__type”:”Person:#”,”ID”:”1″,”Name”:”John Smith”}}

Eanble ssl between wcf and ajax

<system.serviceModel>
     <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
       multipleSiteBindingsEnabled="true" />

<bindings>
      <webHttpBinding>
        <binding name="TransportSecurity">
          <security mode="Transport">
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpsGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="EndPBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>

   
    <services>
      <service name="Service" behaviorConfiguration="ServiceBehavior">
        <endpoint address="" binding="webHttpBinding" behaviorConfiguration="EndPBehavior"
           bindingConfiguration="TransportSecurity" contract="Service"/>
      </service> 
    </services>
  </system.serviceModel>

This will enable wcf to be hosted on https, and client side does not need any change to just consume them.

Enable SSL on localhost@IIS

Create a server certificate under IIS server/ IIS

Create a site under the root ‘Sites’ IIS server/Sites

Site binding: https, port:443, and SSL certificate : select a certificate

SSL settings for this site: enable require SSL

Have fun.


Viewing all articles
Browse latest Browse all 28

Trending Articles