Posts Tagged ‘Commerce Server’

Why Microsoft Was Smart To Abandon Commerce Server

Written by Brad Foley. Posted in Commerce Server

Being a Microsoft Commerce Server MVP, when I got the news that Microsoft was transferring development of Commerce Server to a partner, Ascentium, I was at first a little disappointed. I have been working with Commerce Server for a few years, and have really grown to like the product and its extensibility. So being that I am not a man of many words, lets sum this up into a simple advantage/disadvantage list.

Disadvantages

  • Subscription based licensing (Not a big deal for most companies, but for capital based accounting, not so good)
  • Won’t be covered by Microsoft’s 10 year support lifecycle
    • You’ll have to keep your platform a little more current (I know a lot of sites still using Commerce Server 2000)

Advantages

  • Substantial decrease in cost
  • More aggressive release cycle (I would expect every 6 months or so)
  • Not bound by Microsoft’s development policies
    • We should start seeing integrated components like PayPal, Amazon, etc..
    • Faster releases
    • Better testability with releases
    • Improved delivery format
  • More personal experience for partners and developers
    • When dealing with the non-Giant firms, your relationship is more personal and valuable
  • Ascentium has committed to delivering the product and has a great road map

Reasons

This is only speculative but here’s my take. I imagine several higher ups in Microsoft sat in a room and realized simply that there weren’t many new Commerce Server customers, why?, because the product was becoming dated. So, what to do, this is what I would have done… (And what I believe they did…) Well, we can transfer the development of Commerce Server to a partner, for all the reasons above, and keep a good enterprise e-commerce platform that runs on the Microsoft Stack, and we’ll still get the licensing revenue for Windows Server, SQL Server, BizTalk, and possibly SharePoint. All is all, a good decision on the part of Microsoft, whether it went down this way or not.

Summary

So in summary, while there are few disadvantages, I feel the advantages far outnumber the negative. One key thing that was never listed on either side was customer perception. This could swing either way, many customer are comfortable with the Microsoft product lifecycle and even depend on it. Other customers however, feel that Microsoft wasn’t allowing them to be competitive, falling behind the competition. Being that Commerce Server is still being developed by the same “people” as it was before, the product will be the same strength.

How To Get The Commerce Server Extensibility Kit Deployment Friendly

Written by Brad Foley. Posted in Commerce Server

When you first start out developing for Commerce Server 2009 R2, you notice there are quite a large amount of code that they provide you to get started with.

Where To Start:
First you need to find the CommerceSharePointExtensibilityKit.zip file located at C:Program Files (x86)Microsoft Commerce Server 9.0Extensibility Kits
In this file you’ll see two Visual Studio solution files. I’m a fan of VS2010, so we’ll work with that, although it isn’t what these solutions were meant for.

Open the SharePointCommerce solution. Allow Visual Studio to do it’s conversion. You’ll now need to add the two other projects Common and SharePointCommon. They are located in the named directories from the base solution directory, you shouldn’t have any issues finding them.

Create your own SNK file:
Create a small console application with a SNK of your own choosing. Add signing to the project, then retrieve the PublicKeyToken for later use.

Replace the SNK file:
Copy your SNK file over the built in file MSSharedLibSN1024.snk, don’t delete rename, this will just create more work for you later.

Perform the following Search and Replace Operations within all files in the solution:

Search For:
Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

Replace With:
Version=1.0.0.0, Culture=neutral, PublicKeyToken=<YourKeyHere>

Search For:
Culture=Neutral, Version=1.0.0.0, PublicKeyToken=31bf3856ad364e35

Replace With:
Culture=Neutral, Version=1.0.0.0, PublicKeyToken=<YourKeyHere>

Manually Edit this file:
CommerceSharePointExtensibilityKitSharePointCommonFeatureActivationCommerceFeatureActivationJobDefinition.cs Line: 1836
"Microsoft.CommerceServer.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=<YourKeyHere>

Replace with:
"Microsoft.CommerceServer.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

Now you will be able to build the entire solution, create the three WSP’s used by the custom installer, and use their handy tool to provision the site.

Trouble Shooting Commerce Server 2009 Profile Extensions

Written by Brad Foley. Posted in Commerce Server

This is the Exception that we will be looking at today: The requested operation could not be performed because the CommerceEntity ‘CustomEntity’ does not map to a Commerce Server profile definition. [FaultException`1: The requested operation could not be performed because the CommerceEntity 'TaxForm' does not map to a Commerce Server profile definition.] Microsoft.Commerce.Providers.Utility.ProfileMetadata..ctor(CommerceEntityDefinition definition) +465 Microsoft.Commerce.Providers.Utility.ProfileMetadata.CreateProfileMetadata(MetadataCacheKey key, String modelName) +172 Microsoft.Commerce.Providers.Utility.<>c__DisplayClass5.<Get>b__4(MetadataCacheKey key) +54 Microsoft.Commerce.Application.Common.CachedFactory`2.GetOrCreate(TKey key, CreateInstance`2 factory) +435 Microsoft.Commerce.Providers.Utility.ProfileMetadata.Get(String modelName) +288 Microsoft.Commerce.Providers.Components.ProfileOperationSequenceComponent.get_Metadata() +89 Microsoft.Commerce.Providers.Components.ProfileOperationSequenceComponent.get_PrimaryKeyName() +40 Microsoft.Commerce.Providers.Components.RelatedProfileProcessorBase.ProcessQuery(CommerceQueryRelatedItem queryRelatedItem) +335 Microsoft.Commerce.Providers.Components.RelatedProfileOperationSequenceComponent.ExecuteQuery(CommerceQueryOperation queryOperation, OperationCacheDictionary operationCache, CommerceQueryOperationResponse response) +786 Microsoft.Commerce.Providers.Components.OperationSequenceComponent.Execute(CommerceOperation operation, OperationCacheDictionary operationCache, CommerceOperationResponse response) +348 Microsoft.Commerce.Providers.Components.ProfileOperationSequenceComponent.Execute(CommerceOperation operation, OperationCacheDictionary operationCache, CommerceOperationResponse response) +116 Microsoft.Commerce.Broker.OperationSequence.ExecuteComponentTree(List`1 executionTreeList, CommerceOperation operation, OperationCacheDictionary operationCache, CommerceOperationResponse response) +1040 Microsoft.Commerce.Broker.OperationSequence.Execute(CommerceOperation operation) +276 Microsoft.Commerce.Broker.MessageHandler.ProcessMessage(String messageHandlerName, CommerceOperation operation) +241 Microsoft.Commerce.Broker.OperationService.InternalProcessRequest(CommerceRequest request) +494 Microsoft.Commerce.Broker.OperationService.ProcessRequest(CommerceRequest request) +471 Microsoft.Commerce.Common.OperationServiceAgent.ProcessRequest(CommerceRequestContext requestContext, CommerceRequest request) +151 So I checked all of the standard things:
  1. Verified that ‘CustomEntity’ was setup correctly in Commerce Manager
  2. Ran a simple 2007 API based script to verify the relationship was setup correctly and that the ‘CustomEntity’ profile object was being returned correctly
  3. Checked the MetaDefinitions.xml and the ChannelConfiguration.config files to verify that they were indeed correct.
  4. Then I started scratching my head, I went over and over everything, and couldn’t figure out what was causing the problem.
Then I started using Reflector, in Visual Studio integrated mode, I choose the following assemblies to debug.
  • Microsoft.Commerce.Broker
  • Microsoft.Commerce.Common
  • Microsoft.Commerce.Contracts
  • Microsoft.Commerce.Providers
Then we start the debugging process and the exception occurs, but with out any indication as to why. Then I start stepping through the code and I notice a line in the Provider assembly.
 if (((target != null) && ProfileAssembly.Equals(target.get_CommerceServerAssembly(),
StringComparison.OrdinalIgnoreCase)) && ProfileTypeName.Equals(target.get_CommerceServerClass(),
StringComparison.OrdinalIgnoreCase))
          {
            return target;
          }
What this code is doing is essentially, checking the data we provided in our MetaDefinitions.xml file to make sure that it matches the assembly information.
  <!-- Custom Entity Start-->
            <CommerceEntity name="CustomEntity">
                <DisplayName value="Custom Entity" />
                <EntityMappings >
                    <EntityMapping
                                  csType="Microsoft.CommerceServer.Runtime.Profiles.Profile"
                                  csAssembly="Microsoft.CommerceServer.Runtime, Version=6.1.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                                  csDefinitionName="CustomEntity"
                                  csArea="Profiles">
                        <PropertyMappings>
                            <PropertyMapping property="Id" csProperty="GeneralInfo.u_Custom_Entity_id" />
                            <PropertyMapping property="FormName" csProperty="GeneralInfo.b_Custom_Entity_image" />
                            <PropertyMapping property="DateCreated" csProperty="GeneralInfo.dt_date_created" />
                            <PropertyMapping property="FormImage" csProperty="GeneralInfo.u_Custom_Entity_name"/>
                        </PropertyMappings>
                    </EntityMapping>
                </EntityMappings>
            </CommerceEntity>
            <!-- Custom Entity End—>
Do you see the problem? Well at first neither did I, and for that matter at second or third…. Look closely at this line csAssembly=”Microsoft.CommerceServer.Runtime, Version=6.1.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ Is should actually read: csAssembly=”Microsoft.CommerceServer.Runtime, Version=6.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ Once that simple typo was corrected, the whole process seemed to come to life.

Chasing the elusive (0×80004005): Unspecified error

Written by Brad Foley. Posted in Commerce Server

I have run accross this error many times, i would say about 90% of the time a good old IISRESET clean up the issue. However not this time. An exception occurred in the ‘ProfilesWebService’ Web service. Exception details follow: System.Runtime.InteropServices.COMException (0×80004005): Unspecified error at Microsoft.CommerceServer.Interop.Profiles.ProfileServiceClass.Initialize(String sConfigStore, String sCatalog) at Microsoft.CommerceServer.Profiles.WebService.ProfilesWebService.get_ProfileServicePIA() at Microsoft.CommerceServer.Profiles.WebService.ProfilesWebService.NewProfileStorage() at Microsoft.CommerceServer.Profiles.WebService.ProfilesWebService.CreateProfile(XmlElement& profileXml, Boolean inAdapterContext) I’m not sure why I did this or how it happened, but the error seemed to be caused and was ultimately fixed when I changed the profile partition data provide from OleDb to Sql Native Client (something which i now know is unsupported). Simply changing it back to the OleDb provider fixed the issue. You do this through the commerce server manager, by expanding your profiles resource and opening your data sources, you’ll see the partitions listed in the window on the right.

Force an update of a virtual catalog

Written by Brad Foley. Posted in Commerce Server

A simple script to force commerce server to update all the products in virtual catalogs. A few times in the past i have noticed that the virtual catalog doesn’t always update when a property is updated in the base catalog. Here is a simple solution.
static void Main(string[] args)
{

     CatalogContext context = CatalogContext.Create(new CatalogServiceAgent("http://yourhost/CatalogWebService/CatalogWebService.asmx"));

     CategoryConfiguration config = new CategoryConfiguration();

     config.RecursiveChildProducts = true;

     Category cat = context.GetCategory("Base Catalog", "", "en-us", config);

     foreach (Product p in cat.ChildProducts)
    {

     p["Description"] = DBNull.Value;
     p["DescriptionHtml"] = DBNull.Value;
     p.Save();

     }

     context.RebuildAllCatalogs(true);
}
You’ll notice that i set the description property to DBNull, you will need to include all properties you need updated in a manner similar to this.

Error When Verifying The Catalog Web Service

Written by Brad Foley. Posted in Commerce Server

When you attempt to access your Catalog Web Service,

http://localhost/DefaultSite_CatalogWebService/CatalogWebService.asmx?op=GetServiceVersion

Click the Invoke Button

image

A new window will open displaying the following error:

System.Web.Services.Protocols.SoapException: The catalog Web service does not have write access to the authorizationPolicyPath. Verify that the file exists and that it has the appropriate permissions. —> Microsoft.CommerceServer.ServerFaultException: The catalog Web service does not have write access to the authorizationPolicyPath. Verify that the file exists and that it has the appropriate permissions.
   — End of inner exception stack trace —
   at Microsoft.CommerceServer.Catalog.Internal.WebServiceUtility.PropagateOrLogException(Exception except)
   at Microsoft.CommerceServer.Catalog.Internal.WebServiceUtility.Initialize()
   at Microsoft.CommerceServer.Catalog.Internal.WebServiceUtility.get_CatalogExecutionContext()
   at Microsoft.CommerceServer.Catalog.WebService.CatalogWebService..ctor()

 

What you need to do to fix this, simply grant Modify permissions to the  CatalogAutorizationStore.xml file in the Web Service directory to the user for the Catalog Web Service Application Pool.

For example if the application pool runs as DOMAINCommerceService then you will need to ensure that that user has access to write to the CatalogAuthorizationStore.xml file.

Monitor Commerce Server to ensure that you are taking orders.

Written by Brad Foley. Posted in Commerce Server

I use a simple query that runs ever thirty minutes that just returns the number of hours since the last order.  It adjusts for local time. Load this into a stored procedure, write up a little console app that will email you if you haven’t recieved an order in a few hours.  
DECLARE @offset int

SELECT @offset = DATEDIFF(hh, GETUTCDATE(), GETDATE())

SELECT DATEDIFF(hh,(
     SELECT TOP 1 DateAdd(hh, @offset, created)
     FROM [DefaultSite_transactions].[dbo].[PurchaseOrders]
     WHERE subtotal > 0
     Order by created desc),
   GETDATE())