Пример #1
0
        public AffiliateProductDto Get()
        {
            // Input is passed in the query string. Interface might change eventually.
            // For now lets just get a keyword from query string and use that.
            // Do check the keyword though because our control will pass it otherwise what's the point.
            // Do input validation first because it is less expensive
            if (!Request.Query.ContainsKey(QUERY_STRING_PARAMETER_KEYWORD))
            {
                return(null);
            }
            var keyword = Request.Query[QUERY_STRING_PARAMETER_KEYWORD][0];

            if (string.IsNullOrEmpty(keyword) || string.IsNullOrWhiteSpace(keyword))
            {
                return(null);
            }
            string category = null;

            if (Request.Query.ContainsKey(QUERY_STRING_PARAMETER_CATEGORY))
            {
                category = Request.Query[QUERY_STRING_PARAMETER_CATEGORY][0];
            }

            // Check if caller gave us security header.
            // This might throw exception if there was a header but invalid. But if someone is just messing with us we will return null.
            // Null in this case because we will also check that in react.
            var product = new AffiliateProductDto();

            if (!ParseAntiForgeryHeader(_antiforgery, product, HttpContext))
            {
                return(product);
            }

            // Form the parameters object. This will get smarter then just keyword eventually.
            var parameters = new ProductSearchParameters()
            {
                Keyword = keyword, Category = category
            };

            // Call the service
            product = _productService.FindProduct(parameters);

            // this may be null but we are not going to do anything here no pint really. Just let the client side deal with results.
            return(product);
        }
Пример #2
0
        /// <summary>
        /// Add product to cache.
        /// </summary>
        /// <param name="productKey"></param>
        /// <param name="product"></param>
        public void CacheProduct(string productKey, AffiliateProductDto product)
        {
            // This is not intended to be called from the outside and is public only for tests and transparency.
            // This is supposed to be called only from this class therefor we can throw an expection.
            if (string.IsNullOrEmpty(productKey) || string.IsNullOrWhiteSpace(productKey))
            {
                throw new Exception("AmazonProductService CacheProduct function is called with empty productKey.");
            }
            if (_cacheManager == null)
            {
                throw new Exception("AmazonProductService CacheProduct function is called with empty cache manager.");
            }
            // Re-Check cache in case product is already added while we were waiting for amazon.
            var data = _cacheManager.Get(productKey);

            // return if found
            if (data != null)
            {
                return;
            }
            // Add to cache
            _cacheManager.Add(productKey, product, DEFAULT_PRODUCT_EXPIRATION_SECONDS);
        }
Пример #3
0
        /// <summary>
        /// Parses amazon product details into a generic dto object from the xml node retuned by amazon rest call.
        /// </summary>
        /// <param name="productXmlNode"></param>
        /// <returns></returns>
        /// <remarks>
        /// Check the myxml.xml file for xml example.
        /// I specifically decided not to parse into an object. Too much trouble with serialization/deserialization.
        /// Underneath it is probably parsing each node anyway when converting to object.
        /// </remarks>
        public AffiliateProductDto ParseProduct(XmlNode productXmlNode, XmlNamespaceManager nsmgr, string namespacePrefix)
        {
            // This starts in Item node
            // check input
            if (productXmlNode == null)
            {
                return(null);
            }

            var product = new AffiliateProductDto()
            {
                Merchant = "Amazon"
            };

            product.DetailPageURL     = GetChildNodeValue(productXmlNode, "DetailPageURL");
            product.MerchantProductId = GetChildNodeValue(productXmlNode, "ASIN");

            var attributesNode = GetChildNode(productXmlNode, "ItemAttributes");

            product.Title = GetChildNodeValue(attributesNode, "Title");

            // Parse price
            var listPriceNode = GetChildNode(attributesNode, "ListPrice");

            // Parse list price node if there. Search for ItemAttributes/ListPrice/FormattedPrice
            if (listPriceNode != null)
            {
                product.FormattedPrice = GetChildNodeValue(listPriceNode, "FormattedPrice");
            }
            else
            {
                // Search for OfferSummary/LowestNewPrice/FormattedPrice
                var offerSummaryNode = GetChildNode(productXmlNode, "OfferSummary");
                if (offerSummaryNode != null)
                {
                    var lowestNewPriceNode = GetChildNode(offerSummaryNode, "LowestNewPrice");
                    if (lowestNewPriceNode != null)
                    {
                        product.FormattedPrice = GetChildNodeValue(lowestNewPriceNode, "FormattedPrice");
                    }
                }
            }

            // Parse description
            // Search for OfferSummary/LowestNewPrice/FormattedPrice
            var editorialReviewsNode = GetChildNode(productXmlNode, "EditorialReviews");

            if (editorialReviewsNode != null)
            {
                foreach (XmlNode editorialReviewNode in editorialReviewsNode.ChildNodes)
                {
                    if (editorialReviewNode.Name == "EditorialReview")
                    {
                        var source  = GetChildNodeValue(editorialReviewNode, "Source");
                        var content = GetChildNodeValue(editorialReviewNode, "Content");
                        if (!product.Descriptions.ContainsKey(source))
                        {
                            product.Descriptions.Add(source, content);
                        }
                    }
                }
            }

            // Let's get all images because we need to pick some decent size.
            // I will let the function to add of not add image
            var images = new List <ProductImage>();

            // see if medium image is good enough
            ParseAndAddImage(images, productXmlNode, "MediumImage");
            // see if large image is good enough
            ParseAndAddImage(images, productXmlNode, "LargeImage");
            // see if small image is good enough
            ParseAndAddImage(images, productXmlNode, "SmallImage");

            if (images.Count > 0)
            {
                product.MiddleImageURL    = images[0].Url;
                product.MiddleImageWidth  = images[0].Width;
                product.MiddleImageHeight = images[0].Height;
            }

            return(product);
        }