Navigation


Upcoming courses:

  • Aarhus, Denmark, March 5 - 9, 2012
  • New York City, USA, March 26 - 30, 2012
Read more on our website

About me

Brian Holmgård Kristensen

Hi, I'm Brian. I'm a Danish guy primarily working with ASP.NET e-commerce solutions using Microsoft Commerce Server.

I'm co-founder and core-member of Aarhus .NET Usergroup (ANUG), which is a offline community for .NET developers in Denmark.

You can visit my View Brian Holmgård Kristensen's profile on LinkedIn or follow me on Twitter @brianh_dk. Also please feel free to contact me via e-mail Send me an e-mail.

Categories

On this page

Archive

Blogroll

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

RSS 2.0

Send mail to the author(s) E-mail

Total Posts: 36
This Year: 0
This Month: 0
This Week: 0
Comments: 10

Sign In

Follow me on Twitter @brianh_dk
 Tuesday, 27 April 2010

In Commerce Server the Rank property is used as a sorting discriminator when retrieving categories, products and variants. This property is usually managed using Catalog Manager as shown in the screenshot below:

image

The Rank property could also be managed in your own application which will be the topic of a later blog-post. This blog-post will focus on how to get the actual Rank value when retrieving categories in Commerce Server.

How did we do this in in Commerce Server 2007?

Pretty easy! We just include “Rank” as an item in the PropertiesToReturnArray for child categories (line 12) when requesting a specific category and later retrieve the value from the property-bag of the Category instance (line 24) as shown in the example below:

   1:  public void RequestUsing2007(string catalogName, string categoryName)
   2:  {
   3:      var catalogSystem = CommerceContext.Current.CatalogSystem;
   4:   
   5:      var configuration = new CategoryConfiguration
   6:      {
   7:          LoadChildCategories = true,
   8:          ChildCategories =
   9:          {
  10:              SearchOptions =
  11:              {
  12:                  PropertiesToReturnArray = new[] { "DisplayName", "Rank" }
  13:              }
  14:          }
  15:      };
  16:   
  17:      var category =
  18:          catalogSystem.GetCategory(catalogName, categoryName, "da-DK", configuration);
  19:   
  20:      foreach (var childCategory in category.ChildCategories)
  21:      {
  22:          _writer.WriteLine("Id={0}", childCategory.Name);
  23:          _writer.WriteLine("DisplayName={0}", childCategory.DisplayName);
  24:          _writer.WriteLine("Rank={0}", childCategory["rank"]);
  25:   
  26:          _writer.WriteLine();
  27:      }
  28:  }

And how can I do it in Commerce Server 2009?

In Commerce Server 2009 with the new Foundation API the overall way of retrieving entities in Commerce Server has changed a lot. In the example below I’ve added “Rank” as part of the properties to retrieve when requesting child categories for a specific category (line 10):

   1:  public void RequestUsing2009(string catalogName, string categoryName)
   2:  {
   3:      var categoryQuery = new CommerceQuery<CommerceEntity>("Category");
   4:      categoryQuery.Model.Properties.Add(new[] { "Id", "DisplayName" });
   5:   
   6:      categoryQuery.SearchCriteria.Model.SetPropertyValue("CatalogId", catalogName);
   7:      categoryQuery.SearchCriteria.Model.SetPropertyValue("Id", categoryName);
   8:   
   9:      var childCategoryQuery = new CommerceQueryRelatedItem<CommerceEntity>("ChildCategories", "Category");
  10:      childCategoryQuery.Model.Properties.Add(new[] { "Id", "DisplayName", "Rank" });
  11:      categoryQuery.RelatedOperations.Add(childCategoryQuery);
  12:   
  13:      var operationServiceAgent = new OperationServiceAgent();
  14:   
  15:      var response = 
  16:          operationServiceAgent.ProcessRequest(
  17:              new CommerceRequestContext
  18:              {
  19:                  Channel = "MyChannel",
  20:                  UserLocale = "da-DK",
  21:                  UserUILocale = "da-DK",
  22:                  RequestId = Guid.NewGuid().ToString()
  23:              }, 
  24:              categoryQuery.ToRequest());
  25:   
  26:      var operationResponse = (CommerceQueryOperationResponse)response.OperationResponses.Single();
  27:   
  28:      var entity = operationResponse.CommerceEntities.SingleOrDefault();
  29:   
  30:      foreach (var childCategory in entity.Properties["ChildCategories"] as CommerceRelationshipList)
  31:      {
  32:          foreach (var categoryProperty in childCategory.Target.Properties)
  33:          {
  34:              _writer.WriteLine
  35:                  ("{0}={1} ({2})", 
  36:                  categoryProperty.Key, 
  37:                  categoryProperty.Value, 
  38:                  categoryProperty.Value.GetType().Name);
  39:          }
  40:   
  41:          _writer.WriteLine();
  42:      }
  43:  }

 

One of the Operation Sequence components being executed in this operation is responsible for creating the CategoryConfiguration instance, that we manually created in the Commerce Server 2007 example (CS 2007 example line 5). This Operation Sequence component is named “CategoryConfiguration_Prepare”.

The actual logic for building the CategoryConfiguration instance is implemented in a class named CatalogConfigurationBuilder. This class will look in the MetadataDefinitions.xml file to match up the properties requested by the developer (in our case “Id, DisplayName, Rank”) with the properties registered for the actual entity being requested (“Category”).

If Rank is not registred in the MetadataDefinitions.xml file, it will be ignored by the CatalogConfigurationBuilder (method doing this is called TranslatePropertyName) and will therefore not be part of the “PropertiesToReturnArray” that in the end decides which columns to retrieve from the catalog table in SQL Server.

To make sure that Rank is registred in MetadataDefinitions.xml verify it by follow these steps:

  1. Open MetadataDefinitions.xml
  2. Locate <CommerceEntity name=”Category”>
  3. Make sure that there is a <PropertyMapping> element for property=”Rank” (<PropertyMapping property=”Rank” csProperty=”rank” />)
  4. Make sure that there is a <Property> element for name=”Rank” (<Property name=”Rank” dataType=”String” />)

Step 3 explained:

   1:  <EntityMappings>
   2:    <EntityMapping
   3:          csType="Microsoft.CommerceServer.Catalog.Category"
   4:          csAssembly="Microsoft.CommerceServer.Catalog, Version=6.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
   5:   
   6:      <PropertyMappings>
   7:        <!-- 
   8:              The following mappings are required here to ensure that all
   9:              the product common properties are represented in the Microsoft Multi-Channel Commerce Foundation 
  10:              metadata. These are not returned by the Commerce Server
  11:              metadata automatically as the common properties.
  12:              -->
  13:        <PropertyMapping property="BaseCatalogName" csProperty="BaseCatalogName" />
  14:        <PropertyMapping property="Rank" csProperty="rank" />

 

Step 4 explained:

   1:  <Properties>
   2:    <!-- 
   3:      The following property definitions are required here to ensure that all
   4:      the product common properties are represented in the 
   5:      metadata. These are not returned by the Commerce Server
   6:      metadata automatically as the common properties.
   7:      -->
   8:    <Property name="BaseCatalogName"        dataType="String" >
   9:      <DisplayName value="Base Catalog Name"/>
  10:    </Property>
  11:    <Property name="Rank" dataType="String" />

 

That’s it! The response returned by the Foundation API should now have the actual Rank value returned for each child category entity:

Id=ThirdRankingCategory (String)
Rank=1 (Int32)
DisplayName=ThirdRankingCategory (String)

Id=AnotherRankingCategory (String)
Rank=2 (Int32)
DisplayName=AnotherRankingCategory (String)

Id=SomeRankingCategory (String)
Rank=3 (Int32)
DisplayName=SomeRankingCategory (String)
Posted on Tuesday, 27 April 2010 12:00:00 (Romance Standard Time, UTC+01:00)
# | Comments [0]
Comments are closed.