public static SubcategoryDetailsJson Subcategory(string accountNameKey, SubcategoryModel subcategoryIn, bool includeItems, bool includeHidden) { var subcategoryObjectOut = new SubcategoryDetailsJson(); subcategoryObjectOut.subcategory = new Models.Json.Categorization.SubcategoryJson(); subcategoryObjectOut.subcategory.subsubcategories = new List <CategorizationListItemJson>(); #region include parent objects subcategoryObjectOut.category = new CategorizationParentItemJson { name = subcategoryIn.Category.CategoryName, nameKey = subcategoryIn.Category.CategoryNameKey, fullyQualifiedName = subcategoryIn.Category.FullyQualifiedName }; #endregion #region Build out subcategorization list foreach (SubsubcategoryListModel subsubcategoryModel in subcategoryIn.Subsubcategories) { var subsubcategoryListItem = new CategorizationListItemJson { //id = subsubcategoryModel.SubsubcategoryID.ToString(), name = subsubcategoryModel.SubsubcategoryName, nameKey = subsubcategoryModel.SubsubcategoryNameKey, fullyQualifiedName = subsubcategoryModel.FullyQualifiedName }; //Get listing images for each subcategory in the list subsubcategoryListItem.images = Dynamics.Images.BuildDynamicImagesListForJson(accountNameKey, "subsubcategory", subsubcategoryModel.SubsubcategoryID.ToString(), true); subcategoryObjectOut.subcategory.subsubcategories.Add(subsubcategoryListItem); } #endregion #region Build out product list if (includeItems && subcategoryIn.Subsubcategories.Count == 0) { var account = Common.GetAccountObject(accountNameKey); //Search products string filter = "(locationPath eq '" + subcategoryIn.FullyQualifiedName + "')"; var productResults = DataAccess.Search.SearchProducts(account, null, filter, "orderId asc", 0, 1000, false, null, includeHidden); subcategoryObjectOut.subcategory.items = Dynamics.Products.TransformDynamicProductsListForJson(productResults.Results); } #endregion //categoryObjectOut.count = categoryObjectOut.categories.Count; //Get images for this category subcategoryObjectOut.subcategory.images = Dynamics.Images.BuildDynamicImagesListForJson(accountNameKey, "subcategory", subcategoryIn.SubcategoryID.ToString(), false); //subcategoryObjectOut.subcategory.id = subcategoryIn.SubcategoryID.ToString(); subcategoryObjectOut.subcategory.name = subcategoryIn.SubcategoryName; subcategoryObjectOut.subcategory.nameKey = subcategoryIn.SubcategoryNameKey; subcategoryObjectOut.subcategory.fullyQualifiedName = subcategoryIn.FullyQualifiedName; subcategoryObjectOut.subcategory.description = subcategoryIn.Description; return(subcategoryObjectOut); }
public JsonNetResult Subcategory(string categoryNameKey, string subcategoryNameKey, bool includeHidden = false, bool includeItems = false) { ExecutionType executionType = ExecutionType.local; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); //Get the subdomain (if exists) for the api call string accountNameKey = Common.GetSubDomain(Request.Url); if (String.IsNullOrEmpty(accountNameKey)) { return(new JsonNetResult { Data = "Not found" }); //return Request.CreateResponse(HttpStatusCode.NotFound); } SubcategoryModel subcategory = null; SubcategoryDetailsJson subcategoryDetailsObjectJson = null; string localCacheKey = accountNameKey + ":subcategory:" + categoryNameKey + ":" + subcategoryNameKey + ":includeHidden:" + includeHidden + "includeProducts:" + includeItems; #region (Plan A) Get json from local cache try { subcategoryDetailsObjectJson = (SubcategoryDetailsJson)HttpRuntime.Cache[localCacheKey]; } catch (Exception e) { var error = e.Message; //TODO: Log: error message for local cache call } #endregion if (subcategoryDetailsObjectJson == null) { #region (Plan B) Get Public json from second layer of Redis Cache IDatabase cache = CoreServices.RedisConnectionMultiplexers.RedisMultiplexer.GetDatabase(); string pathAndQuery = Common.GetApiPathAndQuery(Request.Url); string hashApiKey = accountNameKey + ":apicache"; string hashApiField = pathAndQuery; try { var redisApiValue = cache.HashGet(hashApiKey, hashApiField); if (redisApiValue.HasValue) { subcategoryDetailsObjectJson = JsonConvert.DeserializeObject <SubcategoryDetailsJson>(redisApiValue); executionType = ExecutionType.redis_secondary; } } catch { } #endregion if (subcategoryDetailsObjectJson == null) { #region (Plan C) Get category data from Redis Cache and rebuild try { //IDatabase cache = CoreServices.RedisConnectionMultiplexers.RedisMultiplexer.GetDatabase(); string hashMainKey = accountNameKey + ":categories"; string hashMainField = categoryNameKey + "/" + subcategoryNameKey + ":public"; if (includeHidden == true) { hashMainField = categoryNameKey + "/" + subcategoryNameKey + ":private"; } try { var redisValue = cache.HashGet(hashMainKey, hashMainField); if (redisValue.HasValue) { subcategory = JsonConvert.DeserializeObject <ApplicationCategorizationService.SubcategoryModel>(redisValue); executionType = ExecutionType.redis_main; } } catch { } } catch (Exception e) { var error = e.Message; //TODO: Log: error message for Redis call } #endregion if (subcategory == null) { #region (Plan D) Get data from WCF var applicationCategorizationServiceClient = new ApplicationCategorizationService.ApplicationCategorizationServiceClient(); try { applicationCategorizationServiceClient.Open(); subcategory = applicationCategorizationServiceClient.GetSubcategoryByNames(accountNameKey, categoryNameKey, subcategoryNameKey, includeHidden, Common.SharedClientKey); executionType = ExecutionType.wcf; WCFManager.CloseConnection(applicationCategorizationServiceClient); } catch (Exception e) { #region Manage Exception string exceptionMessage = e.Message.ToString(); var currentMethod = System.Reflection.MethodBase.GetCurrentMethod(); string currentMethodString = currentMethod.DeclaringType.FullName + "." + currentMethod.Name; // Abort the connection & manage the exception WCFManager.CloseConnection(applicationCategorizationServiceClient, exceptionMessage, currentMethodString); #endregion } #endregion } } #region Transform into json object, add images & cache locally or locally and radisAPI layer if (subcategoryDetailsObjectJson != null) { //Just cache locally (we got json from the api redis layer) HttpRuntime.Cache.Insert(localCacheKey, subcategoryDetailsObjectJson, null, DateTime.Now.AddMinutes(Common.CategorizationCacheTimeInMinutes), TimeSpan.Zero); } else if (subcategory != null) { //Transform categories into JSON and cache BOTH locally AND into redis subcategoryDetailsObjectJson = Transforms.Json.CategorizationTransforms.Subcategory(accountNameKey, subcategory, includeItems, includeHidden); HttpRuntime.Cache.Insert(localCacheKey, subcategoryDetailsObjectJson, null, DateTime.Now.AddMinutes(Common.CategorizationCacheTimeInMinutes), TimeSpan.Zero); try { cache.HashSet(hashApiKey, hashApiField, JsonConvert.SerializeObject(subcategoryDetailsObjectJson), When.Always, CommandFlags.FireAndForget); } catch { } } #endregion } if (subcategoryDetailsObjectJson == null) { //return empty return(new JsonNetResult()); } //Add execution data stopWatch.Stop(); subcategoryDetailsObjectJson.executionType = executionType.ToString(); subcategoryDetailsObjectJson.executionTime = stopWatch.Elapsed.TotalMilliseconds + "ms"; JsonNetResult jsonNetResult = new JsonNetResult(); jsonNetResult.Formatting = Newtonsoft.Json.Formatting.Indented; jsonNetResult.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local; //<-- Convert UTC times to LocalTime jsonNetResult.Data = subcategoryDetailsObjectJson; return(jsonNetResult); }