Sunday, December 2, 2012

WCF : A Simple WCF REST (3) - Use WCF REST template

[Articles for WCF REST Services]
1) WCF : A simple WCF REST service example (1)
2) WCF : A Simple WCF REST (2) - Remove .svc in REST URL
3) WCF : A Simple WCF REST (3) - Use WCF REST template
4) Client : WCF : A Simple REST Client using HttpClient 

The prior posts WCF : A Simple WCF REST (1) and WCF : A Simple WCF REST (2) show how we can create RESTful web service by using WCF. The posts explains all the steps for creating REST service which is good for educational purpose, practically we'd better use WCF REST VS project template. VS 2008 and VS 2010 does not have WCF REST project template by default. They are provided in Online Template which we have to download.
So to get the template, go to Tools -> Extension Manager -> Online Gallary -> Search for WCF REST. You will see WCF REST Service Template 40 (for .NET 4) and WCF REST Service Template 35 (for .NET 3.5).



Download a template and then the project template will be shown in New Project -> Web -> WCF REST Service Application. Below is VS 2010 template.


Once a new project is created from the template, it has a Service1.cs (without IService.cs - the template directly used [ServiceContract] onto the Service1 class, which is legal) , already REST enabled Web.config,  and Global.asax that already has REST routing.
Here is a Service1 class that is generated from the template.
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;

namespace WcfRestService2
{
    // Start the service and browse to http://<machine_name>:<port>/Service1/help to view the service's generated help page
    // NOTE: By default, a new instance of the service is created for each call; change the InstanceContextMode to Single if you want
    // a single instance of the service to process all calls. 
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    // NOTE: If the service is renamed, remember to update the global.asax.cs file
    public class Service1
    {
        // TODO: Implement the collection resource that will contain the SampleItem instances

        [WebGet(UriTemplate = "")]
        public List<SampleItem> GetCollection()
        {
            // TODO: Replace the current implementation to return a collection of SampleItem instances
            return new List<SampleItem>() { new SampleItem() { Id = 1, StringValue = "Hello" } };
        }

        [WebInvoke(UriTemplate = "", Method = "POST")]
        public SampleItem Create(SampleItem instance)
        {
            // TODO: Add the new instance of SampleItem to the collection
            throw new NotImplementedException();
        }

        [WebGet(UriTemplate = "{id}")]
        public SampleItem Get(string id)
        {
            // TODO: Return the instance of SampleItem with the given id
            throw new NotImplementedException();
        }

        [WebInvoke(UriTemplate = "{id}", Method = "PUT")]
        public SampleItem Update(string id, SampleItem instance)
        {
            // TODO: Update the given instance of SampleItem in the collection
            throw new NotImplementedException();
        }

        [WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
        public void Delete(string id)
        {
            // TODO: Remove the instance of SampleItem with the given id from the collection
            throw new NotImplementedException();
        }

    }
}
And Web.config is:
<?xml version="1.0"?>
<configuration>
  
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, 
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
  </system.webServer>

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <standardEndpoints>
      <webHttpEndpoint>
        <!-- 
            Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
            via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>

</configuration>

Global.asax:

using System;
using System.ServiceModel.Activation;
using System.Web;
using System.Web.Routing;

namespace WcfRestService2
{
    public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes();
        }

        private void RegisterRoutes()
        {
            // Edit the base address of Service1 by replacing 
            // the "Service1" string below
            RouteTable.Routes.Add(new ServiceRoute("Service1", 
               new WebServiceHostFactory(), typeof(Service1)));
        }
    }
}

Suppose we published this web service to localhost/app,  then we can test http://localhost/app/Service1 to call GetCollection method.

Online template by default sets helpEnabled to true in web.config. So http://localhost/app/Service1/help will show meta data information which is very convenient.

No comments:

Post a Comment