public ActionResult ProductDetails(int productId, string attributes, ProductVariantQuery query) { var product = _productService.GetProductById(productId); if (product == null || product.Deleted || product.IsSystemProduct) { return(HttpNotFound()); } // Is published? Check whether the current user has a "Manage catalog" permission. // It allows him to preview a product before publishing. if (!product.Published && !_services.Permissions.Authorize(Permissions.Catalog.Product.Read)) { return(HttpNotFound()); } // ACL (access control list) if (!_aclService.Authorize(product)) { return(HttpNotFound()); } // Store mapping if (!_storeMappingService.Authorize(product)) { return(HttpNotFound()); } // Is product individually visible? if (product.Visibility == ProductVisibility.Hidden) { // Find parent grouped product. var parentGroupedProduct = _productService.GetProductById(product.ParentGroupedProductId); if (parentGroupedProduct == null) { return(HttpNotFound()); } var seName = parentGroupedProduct.GetSeName(); if (seName.IsEmpty()) { return(HttpNotFound()); } var routeValues = new RouteValueDictionary(); routeValues.Add("SeName", seName); // Add query string parameters. Request.QueryString.AllKeys.Each(x => routeValues.Add(x, Request.QueryString[x])); return(RedirectToRoute("Product", routeValues)); } // Prepare the view model var model = _helper.PrepareProductDetailsPageModel(product, query); // Some cargo data model.PictureSize = _mediaSettings.ProductDetailsPictureSize; model.CanonicalUrlsEnabled = _seoSettings.CanonicalUrlsEnabled; // Save as recently viewed _recentlyViewedProductsService.AddProductToRecentlyViewedList(product.Id); // Activity log _services.CustomerActivity.InsertActivity("PublicStore.ViewProduct", T("ActivityLog.PublicStore.ViewProduct"), product.Name); // Breadcrumb if (_catalogSettings.CategoryBreadcrumbEnabled) { _helper.GetCategoryBreadcrumb(_breadcrumb, ControllerContext, product); _breadcrumb.Track(new MenuItem { Text = model.Name, Rtl = model.Name.CurrentLanguage.Rtl, EntityId = product.Id, Url = Url.RouteUrl("Product", new { model.SeName }) }); } return(View(model.ProductTemplateViewPath, model)); }