Saturday, 13 February 2016

Web API-Sitecore-Glass Mapper Example

This blog explains a how to create a Web API which displays the data from Sitecore CMS. This also contains a simple example on how to use Glass Mapper (ORM for Sitecore)

Let’s consider an example where you created a data in Sitecore CMS and you want to consume in different application. Ex: Mobile App, different Web Application. This can be achieved using WebAPI which reads the data from Sitecore.
This example assumes that you have a knowledge of Sitecore and installed Sitecore instance which is running fine.

Ex: Consider URL of the Sitecore site: http://sitecoretest

  1. First create some data, example few products in Sitecore

Ex: Product and Category Template










Product/Category items






Publish the changes

2. Create WebAPI Project
Open Visual Studio and create a blank WebAPI project
















Name the project like "WebAPITest"

Add below reference to the project
Sitecore.Kernal.dll
System.Web.Mvc.dll

This example also uses the Glass Mapper as ORM for Sitecore
You can find more details of Glass Mapper here: http://glass.lu/

Add Glass Mapper using Nuget package manager
Refer this URL for more details: https://www.nuget.org/packages/Glass.Mapper.Sc/

In Visual Studio open the NuGet Package manager console
TOOLS->NuGet Package Manager->NuGet Package Manager Console
Install the Glass Mapper suing command “Install-Package Glass.Mapper.Sc

Press enter, verify for successful installation


This example shows 2 APIs
  • Get the list of products
  • Get the particular product details

3. Add the required Models and Controls
Ex: Create 2 Models

Product.cs
using System;
using Glass.Mapper.Sc.Configuration.Attributes;

namespace WebAPITest.Models
{
    public class Product
    {
        [SitecoreId]
        public virtual Guid Id { get; set; }
        public virtual string Title { get; set; }
        public virtual string Description { get; set; }
        public virtual string Price { get; set; }
    }
}

ProductList.cs
using System;
using System.Collections.Generic;

namespace WebAPITest.Models
{
    public class ProductList
    {
        public virtual IEnumerable<Product> Children { get; set; }
    }
}

Add controller to get the list of all products

ProductListController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Glass.Mapper.Sc;
using WebAPITest.Models;

namespace WebAPITest.Controllers
{
    public class ProductListController : ApiController
    {
        public ProductList Model { get; set; }

        [Route("api/productlist")]
        public IEnumerable<Product> GetProductList(string categoryId)
        {
            var context = new SitecoreContext();
            Model = context.GetItem<ProductList>(new Guid(categoryId));

            if(Model != null)
            {
                return Model.Children.Select(a => new Product()
                    {
                        Id = a.Id,
                        Title = a.Title,
                        Description = a.Description,
                        Price = a.Price
                    }).ToList<Product>();
            }

            return null;
        }
    }
}


Add controller to get the product details for the given product id

ProductController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Glass.Mapper.Sc;
using WebAPITest.Models;

namespace WebAPITest.Controllers
{
    public class ProductController : ApiController
    {
        public Product Model { get; set; }

        [Route("api/product")]
        public Product GetProduct(string productId)
        {
            var context = new SitecoreContext();
            Model = context.GetItem<Product>(new Guid(productId));

            return Model;
        }
    }
}

Lets consider WebAPI URL to access the List of products looks like this:
http://sitecoretest/api/product?productId=<Item GUID>

Now the important part here is, Sitecore always assumes the URL as page item and try to match the URL with corresponding content tree. To remove this assumption and mention the Web API route behavior, we need to register the Web API route.

Add a class under "App_Start" folder and register the rout like below.
RegisterWebApiRoute.cs

using System;
using System.Net.Http.Formatting;
using System.Web;
using System.Web.Http;
using Sitecore.Pipelines;

namespace WebAPITest
{
    public class RegisterWebApiRoute
    {
        public void Process(PipelineArgs args)
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);
        }

        public void Register(HttpConfiguration config)
        {
            // Web API routes
            config.MapHttpAttributeRoutes();

            // Get only JSON response
            config.Formatters.Clear();
            config.Formatters.Add(new JsonMediaTypeFormatter());
        }
    }
}

Create a config file and add Pipeline like below
WebAPITest.config
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <initialize>
        <processor type="WebAPITest.RegisterWebApiRoute, WebAPITest" />
      </initialize>
    </pipelines>
  </sitecore>
</configuration>

The new Glass Mapper is updated related to CastleWindsor WebACtivator
Refer this URL for more details: http://glass.lu/Blog/WebActivatorRemoval

As mentioned in the above URL, either uncomment the WebActivator code in GlassMapperSc.cs or add new config entry mention the pipeline with GlassMapperSc.

Ex: Glass.Mapper.Sc.CastleWindsor.config
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <initialize>
        <processor type="WebAPITest.App_Start.GlassMapperSc, WebAPITest" />
      </initialize>
    </pipelines>
  </sitecore>
</configuration>

Final Solution looks like below:


Build the solution and deploy the below files to the Sitecore instance's Website folder.

  •  \App_Config\Include\Glass.Mapper.Sc.config
  • \App_Config\Include\Glass.Mapper.Sc.Start.config
  • \App_Config\Include\WebAPITest.config
  • \App_Config\Include\Glass.Mapper.Sc.CastleWindsor.config

  • \bin\Castle.Core.dll
  • \bin\Glass.Mapper.dll
  • \bin\Glass.Mapper.Sc.dll
  • \bin\Glass.Mapper.Sc.Mvc.dll
  • \bin\Newtonsoft.Json.dll
  • \bin\System.Net.Http.Formatting.dll
  • \bin\System.Web.Http.dll
  • \bin\System.Web.Http.WebHost.dll
Now you are ready to get the result. Browse the URL like below.
To get the list of Products: 

Result:

<ArrayOfProduct xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/WebAPITest.Models">
<Product>
<Description>Professional DSLR Camera, good Picture quality</Description>
<Id>762f4b2d-2527-4bb1-b1dd-121ec1dd7904</Id>
<Price>1000</Price>
<Title>Canon 700D</Title>
</Product>
<Product>
<Description>Professional DSLR Camera, high Picture quality</Description>
<Id>f4e7f5a9-6112-46a2-ba2c-ae63e11d402e</Id>
<Price>1400</Price>
<Title>Canon 70D</Title>
</Product>
<Product>
<Description>Superior Picture quality, high performing Camera</Description>
<Id>59e78a91-9d45-41d7-9e7c-36a8264fca6c</Id>
<Price>2000</Price>
<Title>Nikon 500D</Title>
</Product>
</ArrayOfProduct>

To get the details of particular product:

http://sitecoretest/api/product?productId={762F4B2D-2527-4BB1-B1DD-121EC1DD7904}

<Product xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/WebAPITest.Models">
<Description>Professional DSLR Camera, good Picture quality</Description>
<Id>762f4b2d-2527-4bb1-b1dd-121ec1dd7904</Id>
<Price>1000</Price>
<Title>Canon 700D</Title>
</Product>

Note: Item GUID is used for simplicity purpose, other parameters can be used and corresponding changes can be done in the controller to get the items.


Note:
  • Do not deploy the Web.config and Global.asax file
  • It is better to replace the default Web.config and Global.asax file with Sitecore instance file
  • Compare the Newtonsoft and MVC library version between the solution reference and which is already available in Sitecore Instance


Thanks
Sharath

2 comments:

  1. I really appreciate information shared above. It’s of great help. If someone want to learn Online (Virtual) instructor lead live training in SITECORE , kindly Contact MaxMunus
    MaxMunus Offer World Class Virtual Instructor led training on SITECORE. We have industry expert trainer. We provide Training Material and Software Support. MaxMunus has successfully conducted 1,00,000 + trainings in India, USA, UK, Australlia, Switzerland, Qatar, Saudi Arabia, Bangladesh, Bahrain and UAE etc.
    For Demo Contact us.
    Saurabh srivastava
    MaxMunus
    E-mail: saurabh@maxmunus.com
    Skype id: saurabhmaxmunus
    Ph:+918553576305
    www.MaxMunus.com

    ReplyDelete