public async Task <IActionResult> Details(string id)
        {
            ICollection <ProductViewModel> mostOrderedProductsCache;

            if (!this.memoryCache.TryGetValue("MostOrderedProducts", out mostOrderedProductsCache))
            {
                mostOrderedProductsCache = this.productsService.GetMostOrderedProducts()
                                           .Select(p => p.Map <Product, ProductViewModel>()).ToList();

                MemoryCacheEntryOptions memoryCacheOptions = new MemoryCacheEntryOptions();
                memoryCacheOptions.AbsoluteExpiration = DateTime.UtcNow.AddMinutes(5);
                this.memoryCache.Set <ICollection <ProductViewModel> >("MostOrderedProducts", mostOrderedProductsCache, memoryCacheOptions);
            }

            var product = await this.productsService.GetProduct(id, this.User.Identity.Name);

            if (product == null)
            {
                this.TempData["Error"] = "Product does not exists.";
                return(RedirectToAction(nameof(Index)));
            }

            var details = product.Map <Product, ProductDetailsViewModel>();

            var model = new ProductDetailsPageViewModel
            {
                Product             = details,
                MostOrderedProducts = mostOrderedProductsCache
            };

            this.TempData["CurrentProductId"] = id;
            return(View(model));
        }
        public async Task <IActionResult> Details(ProductDetailsPageViewModel model, string id)
        {
            if (this.TempData["CurrentProductId"].ToString() != id)
            {
                this.TempData["Error"] = "Invalid operation.";
                return(RedirectToAction(nameof(Index)));
            }

            if (!this.ModelState.IsValid)
            {
                ICollection <ProductViewModel> mostOrderedProductsCache;
                if (!this.memoryCache.TryGetValue("MostOrderedProducts", out mostOrderedProductsCache))
                {
                    mostOrderedProductsCache = this.productsService.GetMostOrderedProducts()
                                               .Select(p => p.Map <Product, ProductViewModel>()).ToList();

                    MemoryCacheEntryOptions memoryCacheOptions = new MemoryCacheEntryOptions();
                    memoryCacheOptions.AbsoluteExpiration = DateTime.UtcNow.AddMinutes(5);
                    this.memoryCache.Set <ICollection <ProductViewModel> >("MostOrderedProducts", mostOrderedProductsCache, memoryCacheOptions);
                }

                var product = await this.productsService.GetProduct(id, this.User.Identity.Name);

                if (product == null)
                {
                    this.TempData["Error"] = "Product does not exists.";
                    return(RedirectToAction(nameof(Index)));
                }

                var details = product.Map <Product, ProductDetailsViewModel>();

                model.Product             = details;
                model.MostOrderedProducts = mostOrderedProductsCache;

                this.TempData["CurrentProductId"] = id;
                return(View(model));
            }

            var review = model.Map <ProductDetailsPageViewModel, Review>();

            review.ProductId = Guid.Parse(id);

            await this.reviewService.Create(review, this.User.Identity.Name);

            this.TempData["Success"] = "Review added.";
            return(RedirectToAction(nameof(Details), new { id }));
        }
        public ProductDetailsPage()
        {
            InitializeComponent();

            BindingContext = new ProductDetailsPageViewModel();
        }