Sitecore MVC MusicStore – Part 5

Now that we have some content in Sitecore we can show this in an overview of all the genres and albums.

First thing we need to do is create a service which will provide the data from Sitecore so that we can use this in a component.
The BoC module provides us with some very handy base services and functionalities to provide this content.
In the service we are creating, we will make use of the BaseModelService. This BoC service provides methods to get all or find a certain content item based on the GlassMapper model we created.

GenreService.cs
		public class GenreService : BaseModelService<Genre>, IGenreService
		{
			public GenreService(IModelValidator validator, IEventAggregator eventAggregator, IRepository<Genre> repository) : base(validator, eventAggregator, repository)
			{
			}
		  
			public IEnumerable<Genre> GetAll()
			{
				using (DataContext.BeginDataContext())
				{
					return ListAll();
				}
			}
		 
			public Genre GetGenre(string name)
			{
				using (DataContext.BeginDataContext())
				{
					return Find(g => g.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
				}
			}
		}
	

In above service we created two methods, one to get all genres from Sitecore, and one to get a single genre based on the name of this item.

To provide the album content, we do the same thing but add another method to get an album based on its Sitecore id or display name.

AlbumService.cs
		public class AlbumService : BaseModelService<Album>, IAlbumService
		{
			public AlbumService(IModelValidator validator, IEventAggregator eventAggregator, IRepository<Album> repository) : base(validator, eventAggregator, repository)
			{
			}
		  
			public Album GetAlbum(object id)
			{
				using (DataContext.BeginDataContext())
				{
					int externalId;
					Album album = null;
					if (id is Guid)
						album = Get(id.ToString());
					else if (ID.IsID(string.Concat(id)))
						album = Get(string.Concat(id));
					else if (int.TryParse(string.Concat(id), out externalId))
						album = Find(a => a.ExternalId.Equals(string.Concat(id), StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
					else
						album = Find(a => a.DisplayName.Equals(string.Concat(id), StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
		  
					return album;
				}
			}
		 
			public IEnumerable<Album> GetAlbumsByGenre(Guid id)
			{
				using (DataContext.BeginDataContext())
				{
					return Find(a => a.Genre.Id == id);
				}
			}
		  
			public IEnumerable<Album> GetAll()
			{
				using (DataContext.BeginDataContext())
				{
					return ListAll();
				}
			}
		}
	

To use these new services in combination with the IoC container, we will need to add it to the container.
To do this create a new class in the App_Start folder of the project. This class will have to derive from the IContainerInitializer interface from the BoC.InversionOfControl package.
Inside the Execute method you will need to add both services to the resolver.

SetDependencies.cs
		public class SetDependencies : IContainerInitializer
		{
			private readonly IDependencyResolver _resolver;
		 
			public SetDependencies(IDependencyResolver resolver)
			{
				_resolver = resolver;
			}
		 
			public void Execute()
			{
				_resolver.RegisterType<IAlbumService, AlbumService>();
				_resolver.RegisterType<IGenreService, GenreService>();
			}
		}
	

Now that we have the means to get the content, we can create overview components to show this content.

Lets first create the StoreController. In this controller's index method we will show the genre overview, which displays all genres available in Sitecore.

StoreController.cs
		public class StoreController : Controller
		{
			private readonly IGenreService _genreService;
		 
			public StoreController(IGenreService genreService)
			{
				_genreService = genreService;
			}
		 
			public ActionResult Index()
			{
				return View(_genreService.GetAll());
			}
		}
	

This method uses the service we just created to get all the genres from Sitecore and returns them to the view.

Index.cshtml
		@inherits Glass.Mapper.Sc.Web.Mvc.GlassView<IEnumerable<MusicStore.Web.Models.Genre>>
		@{
			ViewBag.Title = "Store";
		}
		<h3>Browse Genres</h3>
		<p>
			Select from @Model.Count()
			genres:
		</p>
		<ul>
			@foreach (var genre in Model)
			{
				<li><a href="/Store/Browse?genre=@genre.Name">@genre.Name</a></li>
			}
		</ul>
	

And finally we will need to add this view as a rendering to Sitecore:

Now it is ready to be used on any page you like. For this tutorial you will at least have to place it on the Browse page which you should create under the homepage.

Note: If you don't see any content on your site, make sure everything is published and that you have rebuild the content indexes.

It would also be nice if your customers could see which albums are ordered the most in the store. To provide this we will update the homepage index rendering to show the top 5 albums.

HomeController.cs
		public class HomeController : Controller
		{
			private readonly IAlbumService _albumService;
		  
			public HomeController(IAlbumService albumService)
			{
				_albumService = albumService;
			}
		  
			public ActionResult Index()
			{
				List<Album> albums = _albumService.GetAll().OrderBy(a => Globals.LinkDatabase.GetReferenceCount(Database.GetDatabase("master").Items[new ID(a.Id)])).Take(5).ToList();
				return View(albums);
			}
		}
	

The OrderBy Linq query, will sort the albums based on how many times each album is referenced. Later on in this series we will create the orders, and in these order we will add a reference to each album ordered.

The view will look like this:

Index.cshtml
		@inherits Glass.Mapper.Sc.Web.Mvc.GlassView<List<MusicStore.Web.Models.Album>>
		@{
			ViewBag.Title = "ASP.NET MVC Music Store";
		}
		<div id="promotion">
		</div>
		  
		<h3><em>Fresh</em> off the grill</h3>
		  
		<ul id="album-list">
			@foreach (var album in Model)
			{
				<li>
					<a href="/Store/Details?id=@album.Id">
						@RenderImage(a => album.AlbumArt)
						<span>@album.Title</span>
					</a>
				</li>
			}
		</ul>
	

In the next part of this series, we will create a genre detail page by using wildcard functionalities.

Go to Part 6

Leave a Reply

Your email address will not be published. Required fields are marked *