<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>blog.brianh.dk</title>
    <link>http://blog.brianh.dk/</link>
    <description>My personal blog about working with Microsoft .NET technology from Aarhus, Denmark</description>
    <language>en-us</language>
    <copyright>Brian Holmgård Kristensen</copyright>
    <lastBuildDate>Mon, 21 Feb 2011 20:13:33 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>bhk@yourhost.dk</managingEditor>
    <webMaster>bhk@yourhost.dk</webMaster>
    <item>
      <trackback:ping>http://blog.brianh.dk/Trackback.aspx?guid=ac502761-8454-4c92-8db3-626c662c42fa</trackback:ping>
      <pingback:server>http://blog.brianh.dk/pingback.aspx</pingback:server>
      <pingback:target>http://blog.brianh.dk/PermaLink,guid,ac502761-8454-4c92-8db3-626c662c42fa.aspx</pingback:target>
      <dc:creator>Brian Holmgård Kristensen</dc:creator>
      <wfw:comment>http://blog.brianh.dk/CommentView,guid,ac502761-8454-4c92-8db3-626c662c42fa.aspx</wfw:comment>
      <wfw:commentRss>http://blog.brianh.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=ac502761-8454-4c92-8db3-626c662c42fa</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
As a contribution to the Commerce Server developer community I’ve decided to start
working on a small library that will provide some useful functionality for developing
Microsoft Commerce Server solutions.
</p>
        <p>
The library was initially hosted on MSDN Code but due to recent restructuring of the
way that hosting facility works, I’ve decided to move it to Google Code. From here
you can follow the roadmap, change history, download the latest code base (using any
SubVersion client) and read documentation on how to use the CSUtilities library. 
</p>
        <p>
More information on the CSUtilities library can be found at <a href="http://code.google.com/p/csutilities/">http://code.google.com/p/csutilities/</a></p>
        <p>
          <strong>Roadmap of CSUtilities</strong>
        </p>
        <ul>
          <li>
Avoid magic strings with Code Generation based on MetadataDefinitions.xml <strong>(RELEASED
– see below)</strong></li>
          <li>
Get Connection Strings to Commerce Server databases 
</li>
          <li>
Custom Shipments (replace the built-in Shipping Methods) 
</li>
          <li>
Custom Payments (replace the built-in Payment Methods) 
</li>
          <li>
Custom Pricing (pricing outside Commerce Server - ERP, Custom Database, other) 
</li>
          <li>
LineItemRollup with Commerce Server 2009 
</li>
          <li>
Multi-currency pricing in a single catalog 
</li>
          <li>
Replace the Profiles System with a real ORM 
</li>
          <li>
ASP.NET Templates (.NET 3.5/4.0, MVC/WebForms/Razor) 
</li>
          <li>
Auto generate Order Schema (SQL/XSD) 
</li>
          <li>
Foundation API extension methods 
</li>
          <li>
Deploy pipelines 
</li>
          <li>
and hopefully a lore more :)</li>
        </ul>
        <p>
          <strong>CSUtilities 0.0.0.1</strong>
        </p>
        <p>
The first release of the new CSUtilities library is now available for you to download
on Google Code. 
</p>
        <p>
Read more about this release at <a href="http://code.google.com/p/csutilities/wiki/CSUtilities0001">http://code.google.com/p/csutilities/wiki/CSUtilities0001</a></p>
        <img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=ac502761-8454-4c92-8db3-626c662c42fa" />
      </body>
      <title>Announcing CSUtilities library</title>
      <guid isPermaLink="false">http://blog.brianh.dk/PermaLink,guid,ac502761-8454-4c92-8db3-626c662c42fa.aspx</guid>
      <link>http://blog.brianh.dk/2011/02/21/AnnouncingCSUtilitiesLibrary.aspx</link>
      <pubDate>Mon, 21 Feb 2011 20:13:33 GMT</pubDate>
      <description>&lt;p&gt;
As a contribution to the Commerce Server developer community I’ve decided to start
working on a small library that will provide some useful functionality for developing
Microsoft Commerce Server solutions.
&lt;/p&gt;
&lt;p&gt;
The library was initially hosted on MSDN Code but due to recent restructuring of the
way that hosting facility works, I’ve decided to move it to Google Code. From here
you can follow the roadmap, change history, download the latest code base (using any
SubVersion client) and read documentation on how to use the CSUtilities library. 
&lt;/p&gt;
&lt;p&gt;
More information on the CSUtilities library can be found at &lt;a href="http://code.google.com/p/csutilities/"&gt;http://code.google.com/p/csutilities/&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Roadmap of CSUtilities&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Avoid magic strings with Code Generation based on MetadataDefinitions.xml &lt;strong&gt;(RELEASED
– see below)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
Get Connection Strings to Commerce Server databases 
&lt;/li&gt;
&lt;li&gt;
Custom Shipments (replace the built-in Shipping Methods) 
&lt;/li&gt;
&lt;li&gt;
Custom Payments (replace the built-in Payment Methods) 
&lt;/li&gt;
&lt;li&gt;
Custom Pricing (pricing outside Commerce Server - ERP, Custom Database, other) 
&lt;/li&gt;
&lt;li&gt;
LineItemRollup with Commerce Server 2009 
&lt;/li&gt;
&lt;li&gt;
Multi-currency pricing in a single catalog 
&lt;/li&gt;
&lt;li&gt;
Replace the Profiles System with a real ORM 
&lt;/li&gt;
&lt;li&gt;
ASP.NET Templates (.NET 3.5/4.0, MVC/WebForms/Razor) 
&lt;/li&gt;
&lt;li&gt;
Auto generate Order Schema (SQL/XSD) 
&lt;/li&gt;
&lt;li&gt;
Foundation API extension methods 
&lt;/li&gt;
&lt;li&gt;
Deploy pipelines 
&lt;/li&gt;
&lt;li&gt;
and hopefully a lore more :)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;CSUtilities 0.0.0.1&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The first release of the new CSUtilities library is now available for you to download
on Google Code. 
&lt;/p&gt;
&lt;p&gt;
Read more about this release at &lt;a href="http://code.google.com/p/csutilities/wiki/CSUtilities0001"&gt;http://code.google.com/p/csutilities/wiki/CSUtilities0001&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=ac502761-8454-4c92-8db3-626c662c42fa" /&gt;</description>
      <comments>http://blog.brianh.dk/CommentView,guid,ac502761-8454-4c92-8db3-626c662c42fa.aspx</comments>
      <category>Commerce Server</category>
      <category>CSUtilities</category>
    </item>
    <item>
      <trackback:ping>http://blog.brianh.dk/Trackback.aspx?guid=f7147731-bd9b-4c00-8771-0e77199a1f41</trackback:ping>
      <pingback:server>http://blog.brianh.dk/pingback.aspx</pingback:server>
      <pingback:target>http://blog.brianh.dk/PermaLink,guid,f7147731-bd9b-4c00-8771-0e77199a1f41.aspx</pingback:target>
      <dc:creator>Brian Holmgård Kristensen</dc:creator>
      <wfw:comment>http://blog.brianh.dk/CommentView,guid,f7147731-bd9b-4c00-8771-0e77199a1f41.aspx</wfw:comment>
      <wfw:commentRss>http://blog.brianh.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=f7147731-bd9b-4c00-8771-0e77199a1f41</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Working with Enterprise Applications like large e-commerce sites often requires interaction
with different systems for different purposes, like:
</p>
        <ul>
          <li>
Retrieving catalog data (products and categories) 
</li>
          <li>
Retrieving customer information 
</li>
          <li>
Retrieving inventory skus 
</li>
          <li>
Retrieving prices 
</li>
          <li>
Sending fullfilled orders 
</li>
          <li>
… and the list continues … 
</li>
        </ul>
        <p>
In Vertica most of our projects are based on the principles of <a href="http://domaindrivendesign.org/resources/what_is_ddd">Domain-Driven
Design</a>. In short DDD is all about keeping the focus on the domain – e.g. a B2B-driven
e-commerce site. The way we structure Commerce Server is to look at Commerce Server
as a number of repositories applying the <a href="http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/10/08/the-repository-pattern.aspx">Repository
Pattern</a>. That means that we have somewhat few classes that encapsulate all Commerce
Server specific logic and return not Commerce Server data types (Microsoft.CommerceServer…*)
but data types that we have defined in our own application. 
</p>
        <p>
This is illustrated in the image below.
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/CommerceServerasaRepository_FED7/CS-application-design_2.png" target="_blank">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="CS-application-design" border="0" alt="CS-application-design" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/CommerceServerasaRepository_FED7/CS-application-design_thumb.png" width="244" height="168" />
          </a>
        </p>
        <p>
          <strong>Cons</strong>
        </p>
        <ul>
          <li>
We need to map from Commerce Server types (ICommerceEntity in CS 2009) 
<ul><li>
Solution: We have created functionality that based on attributes and conventions can
do the mappings automatically 
</li></ul></li>
        </ul>
        <p>
          <strong>Pros</strong>
        </p>
        <ul>
          <li>
All Commerce Server code/queries are encapsulated in few classes 
<ul><li>
Not all developers need to know about Commerce Server 
</li><li>
Upgrading to newer versions becomes less painfull 
</li></ul></li>
          <li>
Commerce Server repositories are mockable allowing us to unit-test functionality in
caller classes 
</li>
          <li>
We cache only lightweight objects that we own and not the large DataSets returned
by Commerce Server 
<ul><li>
We can use distributed caching 
</li></ul></li>
        </ul>
        <p>
Properly there are more pros and cons than mentioned above. Please feel free to add
your comment on this.
</p>
        <p>
My point is that while Commerce Server is definitely a great platform and a good investment,
and I’ll explain why I think so in the section below, it is reasonable to think outside
the box when you develop your application. You don’t need to store anything in Commerce
Server and you don’t need to spent that much time with their API’s rather than spending
the time on the actual feature that you are implementing.
</p>
        <p>
Commerce Server as a platform provides data storage, end-points and APIs for many
of these purposes via the different subsystems (Catalog System, Orders System, Marketing
System etc.). Most of these subsystems can be widely extended to fit business requirements,
like having different product types, customized order schema and custom data entities.
Also the product comes with out of the box client tools that that supports working
on these different entities in Commerce Server, like creating products in Catalog
Manager, viewing orders in Customer and Orders Manager and setting up campaigns in
the Marketing Manager.
</p>
        <p>
This is great stuff. If we were to implement the functionality that Commerce Server
offers by ourselves most of us properly would not have gotten further than implementing
a basic catalog system that could handle multiple products in multiple categories
for the same budget than if we had bought a standard license to Commerce Server.
</p>
        <p>
You can build a complete webshop by just utilizing the various components and subsystems
in Commerce Server. Microsoft did it in Commerce Server 2007 with the ASP.NET StarterSite.
In Commerce Server 2009 they did it again with the StoreFront/Contemporary Site in
SharePoint/MOSS. 
</p>
        <p>
The problem is that in real world projects the business requirements to presenting
data are often quite different that what can be expressed in e.g. a Catalog System.
Pricing is one example. In Commerce Server a price is expressed as a single property
on a product/variant in the Catalog System. If you add this product to your basket,
the price will automatically be set on the Line Item. If you are building an international
e-commerce site you properly need to express your price in different currencies. To
do that, you would have to create different virtual catalogs, and your application
logic would have to adapted to that making your design more complex and harder to
maintain. Another scenario is when your price is dependent on the customer buying
it – again you would need to have customer specific catalogs and maintain the prices
there. In most of the B2B sites that I’ve seen prices are not even “static data” stored
in some database, instead they are requested at runtime from the back-end ERP system.
</p>
        <p>
To address the problem with custom pricing we need to tweak Commerce Server to override
the price retrieved from the Product in the Catalog System with a price coming from
ERP. This can be accomplished by creating a simple pipeline component. 
</p>
        <p>
As mentioned earlier there are many ways to extend Commerce Server to fit your business
needs. The Profiles System allow you to create new data entities if you need to store
custom data, like users, logins, roles, accounts, gift certificates, &lt;insert data
here&gt; and the API on top supports all CRUD operations and returns .NET objects
(like what you would expect from any <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">ORM
– object relational mapping software</a> . While this might sound great: that you
can extend and store any data that you would like in the Profiles System, it comes
with a price. The price is bad performance (using non-parameterized OLEDB-queries,
really bad support for one-to-many/many-to-many relationsships and cumbersome and
ineffective extensibility/development model. And why would you even consider using
anything remotely cumbersome when we have ORMs frameworks like Castle Active Record,
NHibernate and Entity Framework to just name a few that very easily allows you to
map data from a database and into your domain?
</p>
        <p>
Besides using a ORM instead of the Profiles System we use and apply a number of different
technologies and principles in our applications, like:
</p>
        <ul>
          <li>
Model-View-Presenter/Model-View-Controller 
<ul><li>
Clean separation of UI and model 
</li></ul></li>
          <li>
Dependency Injection pattern 
<ul><li>
With a Inversion of Control container in place 
</li></ul></li>
          <li>
Unit-testing 
<ul><li>
With Mocking framework in place 
</li></ul></li>
          <li>
Aspect Oriented Programming – DynamicProxy 
<ul><li>
Caching 
</li><li>
Logging 
</li></ul></li>
          <li>
Domain Events 
</li>
          <li>
… 
</li>
        </ul>
        <p>
I hope to see some comments on this blog-post as application design usually is very
subjective :)
</p>
        <img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=f7147731-bd9b-4c00-8771-0e77199a1f41" />
      </body>
      <title>Commerce Server as a Repository</title>
      <guid isPermaLink="false">http://blog.brianh.dk/PermaLink,guid,f7147731-bd9b-4c00-8771-0e77199a1f41.aspx</guid>
      <link>http://blog.brianh.dk/2011/01/12/CommerceServerAsARepository.aspx</link>
      <pubDate>Wed, 12 Jan 2011 16:17:00 GMT</pubDate>
      <description>&lt;p&gt;
Working with Enterprise Applications like large e-commerce sites often requires interaction
with different systems for different purposes, like:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Retrieving catalog data (products and categories) 
&lt;/li&gt;
&lt;li&gt;
Retrieving customer information 
&lt;/li&gt;
&lt;li&gt;
Retrieving inventory skus 
&lt;/li&gt;
&lt;li&gt;
Retrieving prices 
&lt;/li&gt;
&lt;li&gt;
Sending fullfilled orders 
&lt;/li&gt;
&lt;li&gt;
… and the list continues … 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In Vertica most of our projects are based on the principles of &lt;a href="http://domaindrivendesign.org/resources/what_is_ddd"&gt;Domain-Driven
Design&lt;/a&gt;. In short DDD is all about keeping the focus on the domain – e.g. a B2B-driven
e-commerce site. The way we structure Commerce Server is to look at Commerce Server
as a number of repositories applying the &lt;a href="http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/10/08/the-repository-pattern.aspx"&gt;Repository
Pattern&lt;/a&gt;. That means that we have somewhat few classes that encapsulate all Commerce
Server specific logic and return not Commerce Server data types (Microsoft.CommerceServer…*)
but data types that we have defined in our own application. 
&lt;/p&gt;
&lt;p&gt;
This is illustrated in the image below.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/CommerceServerasaRepository_FED7/CS-application-design_2.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="CS-application-design" border="0" alt="CS-application-design" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/CommerceServerasaRepository_FED7/CS-application-design_thumb.png" width="244" height="168" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Cons&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
We need to map from Commerce Server types (ICommerceEntity in CS 2009) 
&lt;ul&gt;
&lt;li&gt;
Solution: We have created functionality that based on attributes and conventions can
do the mappings automatically 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Pros&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
All Commerce Server code/queries are encapsulated in few classes 
&lt;ul&gt;
&lt;li&gt;
Not all developers need to know about Commerce Server 
&lt;/li&gt;
&lt;li&gt;
Upgrading to newer versions becomes less painfull 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Commerce Server repositories are mockable allowing us to unit-test functionality in
caller classes 
&lt;/li&gt;
&lt;li&gt;
We cache only lightweight objects that we own and not the large DataSets returned
by Commerce Server 
&lt;ul&gt;
&lt;li&gt;
We can use distributed caching 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Properly there are more pros and cons than mentioned above. Please feel free to add
your comment on this.
&lt;/p&gt;
&lt;p&gt;
My point is that while Commerce Server is definitely a great platform and a good investment,
and I’ll explain why I think so in the section below, it is reasonable to think outside
the box when you develop your application. You don’t need to store anything in Commerce
Server and you don’t need to spent that much time with their API’s rather than spending
the time on the actual feature that you are implementing.
&lt;/p&gt;
&lt;p&gt;
Commerce Server as a platform provides data storage, end-points and APIs for many
of these purposes via the different subsystems (Catalog System, Orders System, Marketing
System etc.). Most of these subsystems can be widely extended to fit business requirements,
like having different product types, customized order schema and custom data entities.
Also the product comes with out of the box client tools that that supports working
on these different entities in Commerce Server, like creating products in Catalog
Manager, viewing orders in Customer and Orders Manager and setting up campaigns in
the Marketing Manager.
&lt;/p&gt;
&lt;p&gt;
This is great stuff. If we were to implement the functionality that Commerce Server
offers by ourselves most of us properly would not have gotten further than implementing
a basic catalog system that could handle multiple products in multiple categories
for the same budget than if we had bought a standard license to Commerce Server.
&lt;/p&gt;
&lt;p&gt;
You can build a complete webshop by just utilizing the various components and subsystems
in Commerce Server. Microsoft did it in Commerce Server 2007 with the ASP.NET StarterSite.
In Commerce Server 2009 they did it again with the StoreFront/Contemporary Site in
SharePoint/MOSS. 
&lt;/p&gt;
&lt;p&gt;
The problem is that in real world projects the business requirements to presenting
data are often quite different that what can be expressed in e.g. a Catalog System.
Pricing is one example. In Commerce Server a price is expressed as a single property
on a product/variant in the Catalog System. If you add this product to your basket,
the price will automatically be set on the Line Item. If you are building an international
e-commerce site you properly need to express your price in different currencies. To
do that, you would have to create different virtual catalogs, and your application
logic would have to adapted to that making your design more complex and harder to
maintain. Another scenario is when your price is dependent on the customer buying
it – again you would need to have customer specific catalogs and maintain the prices
there. In most of the B2B sites that I’ve seen prices are not even “static data” stored
in some database, instead they are requested at runtime from the back-end ERP system.
&lt;/p&gt;
&lt;p&gt;
To address the problem with custom pricing we need to tweak Commerce Server to override
the price retrieved from the Product in the Catalog System with a price coming from
ERP. This can be accomplished by creating a simple pipeline component. 
&lt;/p&gt;
&lt;p&gt;
As mentioned earlier there are many ways to extend Commerce Server to fit your business
needs. The Profiles System allow you to create new data entities if you need to store
custom data, like users, logins, roles, accounts, gift certificates, &amp;lt;insert data
here&amp;gt; and the API on top supports all CRUD operations and returns .NET objects
(like what you would expect from any &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping"&gt;ORM
– object relational mapping software&lt;/a&gt; . While this might sound great: that you
can extend and store any data that you would like in the Profiles System, it comes
with a price. The price is bad performance (using non-parameterized OLEDB-queries,
really bad support for one-to-many/many-to-many relationsships and cumbersome and
ineffective extensibility/development model. And why would you even consider using
anything remotely cumbersome when we have ORMs frameworks like Castle Active Record,
NHibernate and Entity Framework to just name a few that very easily allows you to
map data from a database and into your domain?
&lt;/p&gt;
&lt;p&gt;
Besides using a ORM instead of the Profiles System we use and apply a number of different
technologies and principles in our applications, like:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Model-View-Presenter/Model-View-Controller 
&lt;ul&gt;
&lt;li&gt;
Clean separation of UI and model 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Dependency Injection pattern 
&lt;ul&gt;
&lt;li&gt;
With a Inversion of Control container in place 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Unit-testing 
&lt;ul&gt;
&lt;li&gt;
With Mocking framework in place 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Aspect Oriented Programming – DynamicProxy 
&lt;ul&gt;
&lt;li&gt;
Caching 
&lt;/li&gt;
&lt;li&gt;
Logging 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Domain Events 
&lt;/li&gt;
&lt;li&gt;
… 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I hope to see some comments on this blog-post as application design usually is very
subjective :)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=f7147731-bd9b-4c00-8771-0e77199a1f41" /&gt;</description>
      <comments>http://blog.brianh.dk/CommentView,guid,f7147731-bd9b-4c00-8771-0e77199a1f41.aspx</comments>
      <category>Commerce Server</category>
    </item>
    <item>
      <trackback:ping>http://blog.brianh.dk/Trackback.aspx?guid=4a4d4827-e92d-4892-abe1-546692906372</trackback:ping>
      <pingback:server>http://blog.brianh.dk/pingback.aspx</pingback:server>
      <pingback:target>http://blog.brianh.dk/PermaLink,guid,4a4d4827-e92d-4892-abe1-546692906372.aspx</pingback:target>
      <dc:creator>Brian Holmgård Kristensen</dc:creator>
      <wfw:comment>http://blog.brianh.dk/CommentView,guid,4a4d4827-e92d-4892-abe1-546692906372.aspx</wfw:comment>
      <wfw:commentRss>http://blog.brianh.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=4a4d4827-e92d-4892-abe1-546692906372</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For some reason my Feedburner feed is not showing my latest post on <a href="http://blog.brianh.dk/2010/10/15/HowToImplementCustomShippingMethodsInCommerceServer.aspx">implementing
custom shipping methods in Commerce Server</a>, so I’m just publishing this post to
make sure that people subscribing to my feed gets the latest information.
</p>
        <p>
If you did get the latest post in your RSS-reader <u>please ignore this post, and
I’m sorry about the inconvenience.</u></p>
        <p>
          <strong>Have a great weekend to all of you :-)</strong>
        </p>
        <img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=4a4d4827-e92d-4892-abe1-546692906372" />
      </body>
      <title>REF: How to implement Custom Shipping Methods in Commerce Server</title>
      <guid isPermaLink="false">http://blog.brianh.dk/PermaLink,guid,4a4d4827-e92d-4892-abe1-546692906372.aspx</guid>
      <link>http://blog.brianh.dk/2010/10/22/REFHowToImplementCustomShippingMethodsInCommerceServer.aspx</link>
      <pubDate>Fri, 22 Oct 2010 06:08:00 GMT</pubDate>
      <description>&lt;p&gt;
For some reason my Feedburner feed is not showing my latest post on &lt;a href="http://blog.brianh.dk/2010/10/15/HowToImplementCustomShippingMethodsInCommerceServer.aspx"&gt;implementing
custom shipping methods in Commerce Server&lt;/a&gt;, so I’m just publishing this post to
make sure that people subscribing to my feed gets the latest information.
&lt;/p&gt;
&lt;p&gt;
If you did get the latest post in your RSS-reader &lt;u&gt;please ignore this post, and
I’m sorry about the inconvenience.&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Have a great weekend to all of you :-)&lt;/strong&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=4a4d4827-e92d-4892-abe1-546692906372" /&gt;</description>
      <comments>http://blog.brianh.dk/CommentView,guid,4a4d4827-e92d-4892-abe1-546692906372.aspx</comments>
      <category>Commerce Server</category>
    </item>
    <item>
      <trackback:ping>http://blog.brianh.dk/Trackback.aspx?guid=b5d7885b-2a8e-4a23-801b-037d3ca7524a</trackback:ping>
      <pingback:server>http://blog.brianh.dk/pingback.aspx</pingback:server>
      <pingback:target>http://blog.brianh.dk/PermaLink,guid,b5d7885b-2a8e-4a23-801b-037d3ca7524a.aspx</pingback:target>
      <dc:creator>Brian Holmgård Kristensen</dc:creator>
      <wfw:comment>http://blog.brianh.dk/CommentView,guid,b5d7885b-2a8e-4a23-801b-037d3ca7524a.aspx</wfw:comment>
      <wfw:commentRss>http://blog.brianh.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=b5d7885b-2a8e-4a23-801b-037d3ca7524a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A couple of years back I wrote a blog-post on <a href="/2007/12/16/HowToExtendCommerceServerPaymentMethodsAndShipmentMethods.aspx">How
to extend Commerce Server Payment Methods and Shipment Methods</a> which described
how you could use the Profiles System in Commerce Server to extend properties of Shipment-
and Payment Methods and with very little effort customize the UI of the Customer And
Orders Manager to allow easy management of these new properties. This technique is
definitely still valid, but I’ve would like to explain another approach that overrides
the overall of how Commerce Server handles Shipping Methods to allow custom business
logic, custom pricing etc.
</p>
        <p>
Also this post serves as a (late, but promised) follow up answer to a question asked
on the Commerce Server Forum on MSDN (<a title="http://social.msdn.microsoft.com/Forums/en-US/commserver2009/thread/bca894c3-122a-4f11-8fe0-35e2b49de1b8/#5cad8631-ca9f-47bf-8bd9-5ad01d77ba8c" href="http://social.msdn.microsoft.com/Forums/en-US/commserver2009/thread/bca894c3-122a-4f11-8fe0-35e2b49de1b8/#5cad8631-ca9f-47bf-8bd9-5ad01d77ba8c">http://social.msdn.microsoft.com/Forums/en-US/commserver2009/thread/bca894c3-122a-4f11-8fe0-35e2b49de1b8/#5cad8631-ca9f-47bf-8bd9-5ad01d77ba8c</a>)
on how the best way to implement custom business logic for handling shipping in Commerce
Server.
</p>
        <p>
In this blog post I’ll show you can implement custom shipping methods in a Commerce
Server 2007/2009 project. In order to better explain the “Why”-part, I’ll start by
briefly explaining how Commerce Server works out of the box in regards to applying
shipping on a basket. Last but not least I’ll explain the “How”-part, so you can implement
this in your own project.
</p>
        <p>
          <strong>Shipping out of the box</strong>
        </p>
        <p>
Shipping Methods are configured in Customer And Orders Manager. Here you specify name
and description for the different languages that you support, the cost of a given
shipping method based on weight, subtotal or quantity and a Shipping Cost Calculator,
which is a pipeline component that automatically gets executed from the Total-pipeline.
As for prices you cannot specify multiple prices in multiple currencies – <u>so you
are stuck with only prices in one currency</u>. Also important to mention is that
there is no supported way to extend this schema, e.g. adding new properties, as you
would also read about in my previously mentioned post.
</p>
        <p>
This screenshot below shows the link between a Shipping Method created in Customer
and Orders Manager and how and where this is persisted in the database.
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/ShippingMethods_2.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ShippingMethods" border="0" alt="ShippingMethods" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/ShippingMethods_thumb.png" width="244" height="186" />
          </a>
        </p>
        <p>
In short Shipping Methods are added to a Basket by specifying a ShippingMethodId (Guid)
to your Line Items as shown below for both 2007 and 2009 version of Commerce Server.
</p>
        <p>
In Commerce Server 2007:
</p>
        <div class="csharpcode">
          <div class="csharpcode">
            <pre>
              <span class="lnum"> 1: </span>var lineItem = <span class="kwrd">new</span> LineItem(<span class="str">"TestCatalog"</span>, <span class="str">"ProductID"</span>, <span class="kwrd">null <span class="rem">/*
VariantID */</span></span>, 1 <span class="rem">/* Quantity */</span>)</pre>
            <pre>
              <span class="lnum"> 2: </span>{</pre>
            <pre>
              <span class="lnum"> 3: </span> ShippingMethodId = <span class="kwrd">new</span> Guid(<span class="str">"MethodId
on Shipping Method"</span>)</pre>
            <pre>
              <span class="lnum"> 4: </span>};</pre>
          </div>
          <style type="text/css">


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        </div>
        <style type="text/css">


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
In Commerce Server 2009:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>lineItem.SetPropertyValue(<span class="str">"CatalogName"</span>, <span class="str">"TestCatalog"</span>);</pre>
          <pre>
            <span class="lnum"> 2: </span>lineItem.SetPropertyValue(<span class="str">"ProductId"</span>, <span class="str">"ProductID"</span>);</pre>
          <pre>
            <span class="lnum"> 3: </span>lineItem.SetPropertyValue(<span class="str">"Quantity"</span>,
1 <span class="rem">/* Quantity */</span>);</pre>
          <pre>
            <span class="lnum"> 4: </span>lineItem.SetPropertyValue(<span class="str">"ShippingMethodId"</span>, <span class="str">"GroupId
on Shipping Method"</span>);</pre>
        </div>
        <p>
 
</p>
        <p>
After adding a Line Item to the Basket you run the Total-pipeline in which there is
a number of pipeline component responsible of requesting the database and actually
create one or more instances of the Microsoft.CommerceServer.Runtime.Orders.Shipment
class based on the ShippingMethodId on the Line Items. This new instance then gets
added to the Shipments-collection on the OrderForm. Basically the same as I’m doing
manually in the code example below:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>var orderForm = basket.OrderForms[0];</pre>
          <pre>
            <span class="lnum"> 2: </span>var shipment = <span class="kwrd">new</span> Shipment();</pre>
          <pre>
            <span class="lnum"> 3: </span>orderForm.Shipments.Add(shipment);</pre>
        </div>
        <style type="text/css">


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
The bottom-line is that you are not in control of the actual creation process of the
Shipment instance, as this is taken care of in the Total-pipeline by the two components
marked in red in the screenshot below.
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/PipelineComponents_2.png" target="_blank">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PipelineComponents" border="0" alt="PipelineComponents" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/PipelineComponents_thumb.png" width="244" height="124" />
          </a>
        </p>
        <p>
If you do try to add it manually the Total-pipeline will throw an error because you
did not specify a ShippingMethodId on your Line Items.
</p>
        <p>
          <strong>Why use custom shipping?</strong>
        </p>
        <p>
On most of the e-commerce projects I’ve been working on, pricing is a very complex
thing – it heavily depends on a lot of context information like customer, country,
currency, content of the basket, suppliers and sometimes more making it impossible
to setup in Customer and Orders Manager. Sure you can try to create your own Shipping
Cost Calculator pipeline component, but that requires you to do work and <u>business
logic</u> in the Pipeline infrastructure of Commerce Server, which is cumbersome,
because  you are dealing with COM, magic strings, and weak-types like the IDictionary
and ISimpleList. Also it is difficult to interact with your existing infrastructure
like services, repositories etc from your pipelines, and it is hard to automate tests
for this. Pipeline components are just not the right place to put your business logic
in my opinion.
</p>
        <p>
So what we would really like is to be able to create the Shipping Methods from within
our domain ourselves, being able to specify the price in that proces, e.g. having
the price coming from a calculation made in the backend/ERP-system. And I’ll show
you how to accomplish that in the next section.
</p>
        <p>
          <strong>How to implement custom shipping</strong>
        </p>
        <p>
First off we need to modify the Total-pipeline. The two pipeline components marked
in red in the previous image needs to be removed thus making the Total-pipeline look
like in the screenshot below:
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/CustomizedPipeline_2.png" target="_blank">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="CustomizedPipeline" border="0" alt="CustomizedPipeline" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/CustomizedPipeline_thumb.png" width="244" height="182" />
          </a>
        </p>
        <p>
The next steps really depend on whether you are working on a CS 2007 or CS 2009 project.
I’ll start by explaining the CS 2007 approach:
</p>
        <p>
          <u>CS 2007</u>
        </p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">void</span> CreateBasketInCs2007()</pre>
          <pre>
            <span class="lnum"> 2: </span>{</pre>
          <pre>
            <span class="lnum"> 3: </span>
            <span class="rem">// Create a new basket</span>
          </pre>
          <pre>
            <span class="lnum"> 4: </span> var basket =</pre>
          <pre>
            <span class="lnum"> 5: </span> CommerceContext.Current.OrderSystem.GetBasket(Guid.NewGuid(), <span class="str">"Default2007"</span>);</pre>
          <pre>
            <span class="lnum"> 6: </span> </pre>
          <pre>
            <span class="lnum"> 7: </span>
            <span class="rem">// Create a new OrderForm</span>
          </pre>
          <pre>
            <span class="lnum"> 8: </span>
            <span class="kwrd">if</span> (basket.OrderForms.Count
== 0)</pre>
          <pre>
            <span class="lnum"> 9: </span> basket.OrderForms.Add(<span class="kwrd">new</span> OrderForm());</pre>
          <pre>
            <span class="lnum"> 10: </span> </pre>
          <pre>
            <span class="lnum"> 11: </span>
            <span class="rem">// Add some line items</span>
          </pre>
          <pre>
            <span class="lnum"> 12: </span>
            <span class="kwrd">foreach</span> (<span class="kwrd">string</span> productId <span class="kwrd">in</span><span class="kwrd">new</span>[]
{ <span class="str">"2-1"</span>, <span class="str">"2-2"</span> })</pre>
          <pre>
            <span class="lnum"> 13: </span> {</pre>
          <pre>
            <span class="lnum"> 14: </span> basket.OrderForms[0].LineItems.Add(<span class="kwrd">new</span> LineItem(<span class="str">"TestCatalog"</span>,
productId, <span class="kwrd">null</span>, 1));</pre>
          <pre>
            <span class="lnum"> 15: </span> }</pre>
          <pre>
            <span class="lnum"> 16: </span> </pre>
          <pre>
            <span class="lnum"> 17: </span>
            <span class="rem">// Add an address</span>
          </pre>
          <pre>
            <span class="lnum"> 18: </span> var address = <span class="kwrd">new</span> OrderAddress(<span class="str">"Default"</span>,
String.Empty) { FirstName = <span class="str">"First Name"</span> };</pre>
          <pre>
            <span class="lnum"> 19: </span> basket.Addresses.Add(address);</pre>
          <pre>
            <span class="lnum"> 20: </span> </pre>
          <pre>
            <span class="lnum"> 21: </span>
            <span class="rem">// Add your custom shipment
with custom price (300)</span>
          </pre>
          <pre>
            <span class="lnum"> 22: </span> basket.OrderForms[0].Shipments.Add(</pre>
          <pre>
            <span class="lnum"> 23: </span>
            <span class="kwrd">new</span> Shipment </pre>
          <pre>
            <span class="lnum"> 24: </span> { </pre>
          <pre>
            <span class="lnum"> 25: </span> ShippingMethodName = <span class="str">"MyShippingMethod"</span>,</pre>
          <pre>
            <span class="lnum"> 26: </span> ShipmentTrackingNumber = <span class="str">"My
Tracking"</span>,</pre>
          <pre>
            <span class="lnum"> 27: </span> ShipmentTotal = 300m, </pre>
          <pre>
            <span class="lnum"> 28: </span> ShippingAddressId = address.OrderAddressId </pre>
          <pre>
            <span class="lnum"> 29: </span> });</pre>
          <pre>
            <span class="lnum"> 30: </span> </pre>
          <pre>
            <span class="lnum"> 31: </span>
            <span class="rem">// Associate Shipping and Line
Items</span>
          </pre>
          <pre>
            <span class="lnum"> 32: </span> basket.OrderForms[0].Shipments[0].LineItemIndexes.Add(0);</pre>
          <pre>
            <span class="lnum"> 33: </span> basket.OrderForms[0].Shipments[0].LineItemIndexes.Add(1);</pre>
          <pre>
            <span class="lnum"> 34: </span> </pre>
          <pre>
            <span class="lnum"> 35: </span>
            <span class="rem">// Execute the pipelines</span>
          </pre>
          <pre>
            <span class="lnum"> 36: </span>
            <span class="kwrd">using</span> (var pipeline
= <span class="kwrd">new</span> PipelineInfo(<span class="str">"Basket"</span>,
OrderPipelineType.Basket))</pre>
          <pre>
            <span class="lnum"> 37: </span> {</pre>
          <pre>
            <span class="lnum"> 38: </span> _writer.WriteLine(basket.RunPipeline(pipeline));</pre>
          <pre>
            <span class="lnum"> 39: </span> }</pre>
          <pre>
            <span class="lnum"> 40: </span> </pre>
          <pre>
            <span class="lnum"> 41: </span>
            <span class="kwrd">using</span> (var pipeline
= <span class="kwrd">new</span> PipelineInfo(<span class="str">"Total"</span>,
OrderPipelineType.Total))</pre>
          <pre>
            <span class="lnum"> 42: </span> {</pre>
          <pre>
            <span class="lnum"> 43: </span> _writer.WriteLine(basket.RunPipeline(pipeline));</pre>
          <pre>
            <span class="lnum"> 44: </span> }</pre>
          <pre>
            <span class="lnum"> 45: </span> </pre>
          <pre>
            <span class="lnum"> 46: </span> basket.Save();</pre>
          <pre>
            <span class="lnum"> 47: </span>}</pre>
        </div>
        <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
The example above creates a new Basket, adds some line items, and adds a Shipment
instance with a custom price. The point is that this custom price could come from
anywhere: web-service call to ERP, custom database, custom pricing calculation logic,
etc. Here is the result of the basket shown in Customer and Orders Manager:
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2007-1_2.png" target="_blank">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="BasketCS2007-1" border="0" alt="BasketCS2007-1" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2007-1_thumb.png" width="244" height="171" />
          </a>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2007-2_2.png" target="_blank">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="BasketCS2007-2" border="0" alt="BasketCS2007-2" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2007-2_thumb.png" width="244" height="171" />
          </a>
        </p>
        <p>
To illustrate the same in CS 2009 we need to do a bit more work as shown below.
</p>
        <p>
          <u>CS 2009</u>
        </p>
        <p>
Lets start by looking at the actual query code:
</p>
        <p>
        </p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">void</span> CreateBasketInCs2009()</pre>
          <pre>
            <span class="lnum"> 2: </span>{</pre>
          <pre>
            <span class="lnum"> 3: </span> var basketUpdateQuery =</pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="kwrd">new</span> CommerceUpdate&lt;CommerceEntity,
CommerceModelSearch&lt;CommerceEntity&gt;, CommerceBasketUpdateOptionsBuilder&gt;(<span class="str">"Basket"</span>);</pre>
          <pre>
            <span class="lnum"> 5: </span> </pre>
          <pre>
            <span class="lnum"> 6: </span> basketUpdateQuery.SearchCriteria.Model.SetPropertyValue(<span class="str">"UserId"</span>,
Guid.NewGuid().ToString());</pre>
          <pre>
            <span class="lnum"> 7: </span> basketUpdateQuery.SearchCriteria.Model.SetPropertyValue(<span class="str">"BasketType"</span>,
0); <span class="rem">// Basket</span></pre>
          <pre>
            <span class="lnum"> 8: </span> basketUpdateQuery.SearchCriteria.Model.SetPropertyValue(<span class="str">"Name"</span>, <span class="str">"Default2009"</span>);</pre>
          <pre>
            <span class="lnum"> 9: </span> </pre>
          <pre>
            <span class="lnum"> 10: </span>
            <span class="rem">// Must be set to "ReadyForCheckout"
in order to have Total pipeline executed</span>
          </pre>
          <pre>
            <span class="lnum"> 11: </span> basketUpdateQuery.Model.SetPropertyValue(<span class="str">"Status"</span>, <span class="str">"ReadyForCheckout"</span>);</pre>
          <pre>
            <span class="lnum"> 12: </span> </pre>
          <pre>
            <span class="lnum"> 13: </span> basketUpdateQuery.Model.SetPropertyValue(<span class="str">"BasketType"</span>,
0); <span class="rem">// 0 = Basket</span></pre>
          <pre>
            <span class="lnum"> 14: </span> </pre>
          <pre>
            <span class="lnum"> 15: </span>
            <span class="rem">// Decides whether to run pipelines
or not</span>
          </pre>
          <pre>
            <span class="lnum"> 16: </span> basketUpdateQuery.UpdateOptions.RefreshBasket
= <span class="kwrd">true</span>;</pre>
          <pre>
            <span class="lnum"> 17: </span> </pre>
          <pre>
            <span class="lnum"> 18: </span>
            <span class="rem">// Add an address</span>
          </pre>
          <pre>
            <span class="lnum"> 19: </span> var address = <span class="kwrd">new</span> CommerceEntity(<span class="str">"Address"</span>)</pre>
          <pre>
            <span class="lnum"> 20: </span> {</pre>
          <pre>
            <span class="lnum"> 21: </span> Id = Guid.NewGuid().ToString(<span class="str">"B"</span>)</pre>
          <pre>
            <span class="lnum"> 22: </span> };</pre>
          <pre>
            <span class="lnum"> 23: </span> </pre>
          <pre>
            <span class="lnum"> 24: </span> address.SetPropertyValue(<span class="str">"AddressName"</span>, <span class="str">"Home"</span>);</pre>
          <pre>
            <span class="lnum"> 25: </span> address.SetPropertyValue(<span class="str">"FirstName"</span>, <span class="str">"First
Name"</span>);</pre>
          <pre>
            <span class="lnum"> 26: </span> address.SetPropertyValue(<span class="str">"ProfileAddressId"</span>,
String.Empty);</pre>
          <pre>
            <span class="lnum"> 27: </span> </pre>
          <pre>
            <span class="lnum"> 28: </span> basketUpdateQuery.RelatedOperations.Add(</pre>
          <pre>
            <span class="lnum"> 29: </span>
            <span class="kwrd">new</span> CommerceCreateRelatedItem&lt;CommerceEntity&gt;(<span class="str">"Addresses"</span>, <span class="str">"Address"</span>)
{ Model = address });</pre>
          <pre>
            <span class="lnum"> 30: </span> </pre>
          <pre>
            <span class="lnum"> 31: </span>
            <span class="rem">// Add some line items</span>
          </pre>
          <pre>
            <span class="lnum"> 32: </span>
            <span class="kwrd">foreach</span> (<span class="kwrd">string</span> productId <span class="kwrd">in</span><span class="kwrd">new</span>[]
{ <span class="str">"2-1"</span>, <span class="str">"2-2"</span> })</pre>
          <pre>
            <span class="lnum"> 33: </span> {</pre>
          <pre>
            <span class="lnum"> 34: </span> var lineItem = <span class="kwrd">new</span> CommerceEntity(<span class="str">"LineItem"</span>);</pre>
          <pre>
            <span class="lnum"> 35: </span> </pre>
          <pre>
            <span class="lnum"> 36: </span> lineItem.SetPropertyValue(<span class="str">"ProductId"</span>,
productId);</pre>
          <pre>
            <span class="lnum"> 37: </span> lineItem.SetPropertyValue(<span class="str">"Quantity"</span>,
1);</pre>
          <pre>
            <span class="lnum"> 38: </span> lineItem.SetPropertyValue(<span class="str">"CatalogName"</span>, <span class="str">"TestCatalog"</span>);</pre>
          <pre>
            <span class="lnum"> 39: </span> lineItem.SetPropertyValue(<span class="str">"ShippingAddressId"</span>,
address.Id);</pre>
          <pre>
            <span class="lnum"> 40: </span> </pre>
          <pre>
            <span class="lnum"> 41: </span>
            <span class="rem">// if using multiple shippings
- use this to pair line item and shipping</span>
          </pre>
          <pre>
            <span class="lnum"> 42: </span> lineItem.SetPropertyValue(<span class="str">"ShippingMethodName"</span>, <span class="str">"MyShippingMethod"</span>);</pre>
          <pre>
            <span class="lnum"> 43: </span> </pre>
          <pre>
            <span class="lnum"> 44: </span> basketUpdateQuery.RelatedOperations.Add(</pre>
          <pre>
            <span class="lnum"> 45: </span>
            <span class="kwrd">new</span> CommerceCreateRelatedItem&lt;CommerceEntity&gt;(<span class="str">"LineItems"</span>, <span class="str">"LineItem"</span>)
{ Model = lineItem });</pre>
          <pre>
            <span class="lnum"> 46: </span> }</pre>
          <pre>
            <span class="lnum"> 47: </span> </pre>
          <pre>
            <span class="lnum"> 48: </span>
            <span class="rem">// Add a custom shipment</span>
          </pre>
          <pre>
            <span class="lnum"> 49: </span> var shipment = <span class="kwrd">new</span> CommerceEntity(<span class="str">"Shipment"</span>);</pre>
          <pre>
            <span class="lnum"> 50: </span> shipment.SetPropertyValue(<span class="str">"Total"</span>,
300m); <span class="rem">// custom price right here!</span></pre>
          <pre>
            <span class="lnum"> 51: </span> shipment.SetPropertyValue(<span class="str">"ShippingAddressId"</span>,
address.Id);</pre>
          <pre>
            <span class="lnum"> 52: </span> shipment.SetPropertyValue(<span class="str">"TrackingNumber"</span>, <span class="str">"some-tracking-code"</span>);</pre>
          <pre>
            <span class="lnum"> 53: </span> shipment.SetPropertyValue(<span class="str">"StatusCode"</span>, <span class="str">"some-status"</span>);</pre>
          <pre>
            <span class="lnum"> 54: </span> shipment.SetPropertyValue(<span class="str">"ShippingMethodName"</span>, <span class="str">"MyShippingMethod"</span>);</pre>
          <pre>
            <span class="lnum"> 55: </span> </pre>
          <pre>
            <span class="lnum"> 56: </span> basketUpdateQuery.RelatedOperations.Add(</pre>
          <pre>
            <span class="lnum"> 57: </span>
            <span class="kwrd">new</span> CommerceCreateRelatedItem&lt;CommerceEntity&gt;(<span class="str">"Shipments"</span>)
{ Model = shipment });</pre>
          <pre>
            <span class="lnum"> 58: </span> </pre>
          <pre>
            <span class="lnum"> 59: </span> var operationServiceAgent = <span class="kwrd">new</span> OperationServiceAgent();</pre>
          <pre>
            <span class="lnum"> 60: </span> </pre>
          <pre>
            <span class="lnum"> 61: </span> var response =</pre>
          <pre>
            <span class="lnum"> 62: </span> operationServiceAgent</pre>
          <pre>
            <span class="lnum"> 63: </span> .ProcessRequest(Request.CreateCommerceRequestContext(),
basketUpdateQuery.ToRequest())</pre>
          <pre>
            <span class="lnum"> 64: </span> .OperationResponses</pre>
          <pre>
            <span class="lnum"> 65: </span> .Single() <span class="kwrd">as</span> CommerceUpdateOperationResponse;</pre>
          <pre>
            <span class="lnum"> 66: </span> </pre>
          <pre>
            <span class="lnum"> 67: </span>
            <span class="kwrd">foreach</span> (var entity <span class="kwrd">in</span> response.CommerceEntities
?? Enumerable.Empty&lt;CommerceEntity&gt;())</pre>
          <pre>
            <span class="lnum"> 68: </span> entity.Output(_writer);</pre>
          <pre>
            <span class="lnum"> 69: </span> </pre>
          <pre>
            <span class="lnum"> 70: </span> _writer.WriteLine(<span class="str">"Count
= {0}"</span>, response.Count);</pre>
          <pre>
            <span class="lnum"> 71: </span>}</pre>
        </div>
        <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
Executing this query with the standard Operation Sequence Components and Translators
in the Multi Channel Foundation API will fail. The reason why is that there is logic
in these classes that validates whether Line Items have a valid ShippingMethodId in
order to execute the Total-pipeline, and also there is simply no translator to translate
from a CS 2009 Shipment-CommerceEntity to a Shipment-type in CS 2007. 
</p>
        <p>
More work needs to be put in this effort, lets start with the Translator part. First
off we need to extend the current LineItemTranslator to have the ShippingMethodName
translated:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">class</span> CustomShippingSupportingLineItemTranslator
: LineItemTranslator</pre>
          <pre>
            <span class="lnum"> 2: </span>{</pre>
          <pre>
            <span class="lnum"> 3: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">override</span>
            <span class="kwrd">bool</span> TranslateToStronglyTypedCommerceServerProperty(LineItem
commerceServerObject, <span class="kwrd">string</span> commerceServerPropertyName, <span class="kwrd">object</span><span class="kwrd">value</span>)</pre>
          <pre>
            <span class="lnum"> 4: </span> {</pre>
          <pre>
            <span class="lnum"> 5: </span>
            <span class="kwrd">bool</span> result =</pre>
          <pre>
            <span class="lnum"> 6: </span>
            <span class="kwrd">base</span>.TranslateToStronglyTypedCommerceServerProperty(commerceServerObject,
commerceServerPropertyName, <span class="kwrd">value</span>);</pre>
          <pre>
            <span class="lnum"> 7: </span> </pre>
          <pre>
            <span class="lnum"> 8: </span>
            <span class="kwrd">if</span> (!result &amp;&amp; </pre>
          <pre>
            <span class="lnum"> 9: </span>
            <span class="kwrd">value</span>
            <span class="kwrd">is</span> String
&amp;&amp;</pre>
          <pre>
            <span class="lnum"> 10: </span> String.Equals(commerceServerPropertyName, <span class="str">"ShippingMethodName"</span>,
StringComparison.OrdinalIgnoreCase))</pre>
          <pre>
            <span class="lnum"> 11: </span> {</pre>
          <pre>
            <span class="lnum"> 12: </span> commerceServerObject.ShippingMethodName = <span class="kwrd">value</span>.ToString();</pre>
          <pre>
            <span class="lnum"> 13: </span> result = <span class="kwrd">true</span>;</pre>
          <pre>
            <span class="lnum"> 14: </span> }</pre>
          <pre>
            <span class="lnum"> 15: </span> </pre>
          <pre>
            <span class="lnum"> 16: </span>
            <span class="kwrd">return</span> result;</pre>
          <pre>
            <span class="lnum"> 17: </span> }</pre>
          <pre>
            <span class="lnum"> 18: </span>}</pre>
        </div>
        <p>
And register this in the ChannelConfiguration.config:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">Translator</span>
          </pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="attr">sourceModelName</span>
            <span class="kwrd">="LineItem"</span>
          </pre>
          <pre>
            <span class="lnum"> 3: </span>
            <span class="attr">destinationType</span>
            <span class="kwrd">="Microsoft.CommerceServer.Runtime.Orders.LineItem,
Microsoft.CommerceServer.Runtime, Version=6.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"</span>
          </pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="attr">type</span>
            <span class="kwrd">="Extensions.Providers.Translators.CustomShippingSupportingLineItemTranslator,
Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4c1d6c3df403d290"</span>
            <span class="kwrd">/&gt;</span>
          </pre>
        </div>
        <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
Next up is extending the existing ShipmentTranslator to support External Entity translation,
like this:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">class</span> ExternalEntitySupportingShipmentTranslator
: ShipmentTranslator, IToExternalEntityTranslator</pre>
          <pre>
            <span class="lnum"> 2: </span>{</pre>
          <pre>
            <span class="lnum"> 3: </span>
            <span class="kwrd">private</span>
            <span class="kwrd">readonly</span> PropertyTranslator&lt;Shipment&gt;
_propertyTranslator;</pre>
          <pre>
            <span class="lnum"> 4: </span> </pre>
          <pre>
            <span class="lnum"> 5: </span>
            <span class="kwrd">public</span> ExternalEntitySupportingShipmentTranslator()</pre>
          <pre>
            <span class="lnum"> 6: </span> {</pre>
          <pre>
            <span class="lnum"> 7: </span> _propertyTranslator = </pre>
          <pre>
            <span class="lnum"> 8: </span>
            <span class="kwrd">new</span> PropertyTranslator&lt;Shipment&gt;(</pre>
          <pre>
            <span class="lnum"> 9: </span>
            <span class="kwrd">null</span>, </pre>
          <pre>
            <span class="lnum"> 10: </span>
            <span class="kwrd">null</span>,</pre>
          <pre>
            <span class="lnum"> 11: </span> TranslateToStronglyTypedCommerceServerProperty,</pre>
          <pre>
            <span class="lnum"> 12: </span> TranslateToWeaklyTypedCommerceServerProperty);</pre>
          <pre>
            <span class="lnum"> 13: </span> }</pre>
          <pre>
            <span class="lnum"> 14: </span> </pre>
          <pre>
            <span class="lnum"> 15: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">void</span> Translate(CommerceEntity
sourceCommerceEntity, <span class="kwrd">object</span> destination)</pre>
          <pre>
            <span class="lnum"> 16: </span> {</pre>
          <pre>
            <span class="lnum"> 17: </span>
            <span class="kwrd">if</span> (sourceCommerceEntity
== <span class="kwrd">null</span>) <span class="kwrd">throw</span><span class="kwrd">new</span> ArgumentNullException(<span class="str">"sourceCommerceEntity"</span>);</pre>
          <pre>
            <span class="lnum"> 18: </span>
            <span class="kwrd">if</span> (destination == <span class="kwrd">null</span>) <span class="kwrd">throw</span><span class="kwrd">new</span> ArgumentNullException(<span class="str">"destination"</span>);</pre>
          <pre>
            <span class="lnum"> 19: </span> </pre>
          <pre>
            <span class="lnum"> 20: </span> _propertyTranslator.TranslateToCommerceServer(sourceCommerceEntity,
destination <span class="kwrd">as</span> Shipment, <span class="kwrd">null</span>);</pre>
          <pre>
            <span class="lnum"> 21: </span> }</pre>
          <pre>
            <span class="lnum"> 22: </span> </pre>
          <pre>
            <span class="lnum"> 23: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">virtual</span>
            <span class="kwrd">bool</span> TranslateToWeaklyTypedCommerceServerProperty(Shipment
commerceServerObject, <span class="kwrd">string</span> commerceServerPropertyName, <span class="kwrd">object</span><span class="kwrd">value</span>)</pre>
          <pre>
            <span class="lnum"> 24: </span> {</pre>
          <pre>
            <span class="lnum"> 25: </span> commerceServerObject[commerceServerPropertyName]
= <span class="kwrd">value</span>;</pre>
          <pre>
            <span class="lnum"> 26: </span>
            <span class="kwrd">return</span>
            <span class="kwrd">true</span>;</pre>
          <pre>
            <span class="lnum"> 27: </span> }</pre>
          <pre>
            <span class="lnum"> 28: </span> </pre>
          <pre>
            <span class="lnum"> 29: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">virtual</span>
            <span class="kwrd">bool</span> TranslateToStronglyTypedCommerceServerProperty(Shipment
commerceServerObject, <span class="kwrd">string</span> commerceServerPropertyName, <span class="kwrd">object</span><span class="kwrd">value</span>)</pre>
          <pre>
            <span class="lnum"> 30: </span> {</pre>
          <pre>
            <span class="lnum"> 31: </span>
            <span class="kwrd">switch</span> (commerceServerPropertyName)</pre>
          <pre>
            <span class="lnum"> 32: </span> {</pre>
          <pre>
            <span class="lnum"> 33: </span>
            <span class="kwrd">case</span>
            <span class="str">"ShipmentTotal"</span>:</pre>
          <pre>
            <span class="lnum"> 34: </span>
            <span class="kwrd">if</span> (<span class="kwrd">value</span> != <span class="kwrd">null</span>)</pre>
          <pre>
            <span class="lnum"> 35: </span> commerceServerObject.ShipmentTotal = Convert.ToDecimal(<span class="kwrd">value</span>,
CultureInfo.InvariantCulture);</pre>
          <pre>
            <span class="lnum"> 36: </span>
            <span class="kwrd">break</span>;</pre>
          <pre>
            <span class="lnum"> 37: </span> </pre>
          <pre>
            <span class="lnum"> 38: </span>
            <span class="kwrd">case</span>
            <span class="str">"ShippingAddressId"</span>:</pre>
          <pre>
            <span class="lnum"> 39: </span> commerceServerObject.ShippingAddressId = <span class="kwrd">value</span><span class="kwrd">as</span><span class="kwrd">string</span>;</pre>
          <pre>
            <span class="lnum"> 40: </span>
            <span class="kwrd">break</span>;</pre>
          <pre>
            <span class="lnum"> 41: </span> </pre>
          <pre>
            <span class="lnum"> 42: </span>
            <span class="kwrd">case</span>
            <span class="str">"ShippingMethodName"</span>:</pre>
          <pre>
            <span class="lnum"> 43: </span> commerceServerObject.ShippingMethodName = <span class="kwrd">value</span><span class="kwrd">as</span><span class="kwrd">string</span>;</pre>
          <pre>
            <span class="lnum"> 44: </span>
            <span class="kwrd">break</span>;</pre>
          <pre>
            <span class="lnum"> 45: </span> </pre>
          <pre>
            <span class="lnum"> 46: </span>
            <span class="kwrd">case</span>
            <span class="str">"ShippingMethodId"</span>:</pre>
          <pre>
            <span class="lnum"> 47: </span> Guid methodId = (<span class="kwrd">value</span><span class="kwrd">is</span><span class="kwrd">string</span>)
? <span class="kwrd">new</span> Guid(<span class="kwrd">value</span><span class="kwrd">as</span><span class="kwrd">string</span>)
: Guid.Empty;</pre>
          <pre>
            <span class="lnum"> 48: </span> commerceServerObject.ShippingMethodId = methodId;</pre>
          <pre>
            <span class="lnum"> 49: </span>
            <span class="kwrd">break</span>;</pre>
          <pre>
            <span class="lnum"> 50: </span> </pre>
          <pre>
            <span class="lnum"> 51: </span>
            <span class="kwrd">case</span>
            <span class="str">"Status"</span>:</pre>
          <pre>
            <span class="lnum"> 52: </span> commerceServerObject.Status = <span class="kwrd">value</span><span class="kwrd">as</span><span class="kwrd">string</span>;</pre>
          <pre>
            <span class="lnum"> 53: </span>
            <span class="kwrd">break</span>;</pre>
          <pre>
            <span class="lnum"> 54: </span> </pre>
          <pre>
            <span class="lnum"> 55: </span>
            <span class="kwrd">case</span>
            <span class="str">"ShipmentTrackingNumber"</span>:</pre>
          <pre>
            <span class="lnum"> 56: </span> commerceServerObject.ShipmentTrackingNumber = <span class="kwrd">value</span><span class="kwrd">as</span><span class="kwrd">string</span>;</pre>
          <pre>
            <span class="lnum"> 57: </span>
            <span class="kwrd">break</span>;</pre>
          <pre>
            <span class="lnum"> 58: </span> </pre>
          <pre>
            <span class="lnum"> 59: </span>
            <span class="kwrd">default</span>:</pre>
          <pre>
            <span class="lnum"> 60: </span>
            <span class="kwrd">return</span>
            <span class="kwrd">false</span>;</pre>
          <pre>
            <span class="lnum"> 61: </span> }</pre>
          <pre>
            <span class="lnum"> 62: </span> </pre>
          <pre>
            <span class="lnum"> 63: </span>
            <span class="kwrd">return</span>
            <span class="kwrd">true</span>;</pre>
          <pre>
            <span class="lnum"> 64: </span> }</pre>
          <pre>
            <span class="lnum"> 65: </span>}</pre>
        </div>
        <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
And again register this in the ChannelConfiguration.config:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">Translator</span>
          </pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="attr">sourceModelName</span>
            <span class="kwrd">="Shipment"</span>
          </pre>
          <pre>
            <span class="lnum"> 3: </span>
            <span class="attr">destinationType</span>
            <span class="kwrd">="Microsoft.CommerceServer.Runtime.Orders.Shipment,
Microsoft.CommerceServer.Runtime, Version=6.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"</span>
          </pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="attr">type</span>
            <span class="kwrd">="Extensions.Providers.Translators.ExternalEntitySupportingShipmentTranslator,
Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4c1d6c3df403d290"</span>
            <span class="kwrd">/&gt;</span>
          </pre>
        </div>
        <p>
 
</p>
        <p>
This covers the translation part, so we can map/translate from a CS 2009 entity to
a CS 2007 entity.
</p>
        <p>
The next part is where it gets a little tricky. We need to create a custom Operation
Sequence Component, that will take care of the actual creation of the CS 2007 Shipment-instance,
and add this to the Shipments collection of the Basket that we are executing a query
against.
</p>
        <p>
To create a custom Operation Sequence Component, we create the following class:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">class</span> CustomShipmentsProcessor
: BasketRelatedItemOperationSequenceComponent</pre>
          <pre>
            <span class="lnum"> 2: </span>{</pre>
          <pre>
            <span class="lnum"> 3: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">override</span>
            <span class="kwrd">string</span> RelationshipName</pre>
          <pre>
            <span class="lnum"> 4: </span> {</pre>
          <pre>
            <span class="lnum"> 5: </span> get { <span class="kwrd">return</span><span class="str">"Shipments"</span>;
}</pre>
          <pre>
            <span class="lnum"> 6: </span> }</pre>
          <pre>
            <span class="lnum"> 7: </span> </pre>
          <pre>
            <span class="lnum"> 8: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">override</span>
            <span class="kwrd">void</span> CreateRelatedItem(CommerceCreateRelatedItem
createRelatedItemOperation)</pre>
          <pre>
            <span class="lnum"> 9: </span> {</pre>
          <pre>
            <span class="lnum"> 10: </span> CommerceEntity shipmentEntity = createRelatedItemOperation.Model;</pre>
          <pre>
            <span class="lnum"> 11: </span> </pre>
          <pre>
            <span class="lnum"> 12: </span> var newShipment =</pre>
          <pre>
            <span class="lnum"> 13: </span> CommerceServerClassFactory.CreateInstance&lt;Shipment&gt;(</pre>
          <pre>
            <span class="lnum"> 14: </span> shipmentEntity.ModelName, CommerceServerArea.Orders);</pre>
          <pre>
            <span class="lnum"> 15: </span> </pre>
          <pre>
            <span class="lnum"> 16: </span> shipmentEntity.Id = newShipment.ShipmentId.ToString(<span class="str">"B"</span>);</pre>
          <pre>
            <span class="lnum"> 17: </span> </pre>
          <pre>
            <span class="lnum"> 18: </span> Translator.ToExternalEntity(shipmentEntity, newShipment);</pre>
          <pre>
            <span class="lnum"> 19: </span> </pre>
          <pre>
            <span class="lnum"> 20: </span> OrderForm orderForm = CachedOrderGroup.GetDefaultOrderForm();</pre>
          <pre>
            <span class="lnum"> 21: </span> </pre>
          <pre>
            <span class="lnum"> 22: </span> UpdateShippingLineItemsAssociation(newShipment,
orderForm);</pre>
          <pre>
            <span class="lnum"> 23: </span> </pre>
          <pre>
            <span class="lnum"> 24: </span> orderForm.Shipments.Add(newShipment);</pre>
          <pre>
            <span class="lnum"> 25: </span> }</pre>
          <pre>
            <span class="lnum"> 26: </span> </pre>
          <pre>
            <span class="lnum"> 27: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">override</span>
            <span class="kwrd">void</span> ExecuteUpdate(CommerceUpdateOperation
updateOperation, Microsoft.Commerce.Broker.OperationCacheDictionary operationCache,
CommerceUpdateOperationResponse response)</pre>
          <pre>
            <span class="lnum"> 28: </span> {</pre>
          <pre>
            <span class="lnum"> 29: </span>
            <span class="kwrd">base</span>.ExecuteUpdate(updateOperation,
operationCache, response);</pre>
          <pre>
            <span class="lnum"> 30: </span> </pre>
          <pre>
            <span class="lnum"> 31: </span> EnsureLineItemsHasShippingMethod();</pre>
          <pre>
            <span class="lnum"> 32: </span> }</pre>
          <pre>
            <span class="lnum"> 33: </span> </pre>
          <pre>
            <span class="lnum"> 34: </span>
            <span class="kwrd">private</span>
            <span class="kwrd">void</span> EnsureLineItemsHasShippingMethod()</pre>
          <pre>
            <span class="lnum"> 35: </span> {</pre>
          <pre>
            <span class="lnum"> 36: </span> OrderForm orderForm = CachedOrderGroup.GetDefaultOrderForm();</pre>
          <pre>
            <span class="lnum"> 37: </span> </pre>
          <pre>
            <span class="lnum"> 38: </span>
            <span class="kwrd">foreach</span> (LineItem lineItem <span class="kwrd">in</span></pre>
          <pre>
            <span class="lnum"> 39: </span> orderForm.LineItems</pre>
          <pre>
            <span class="lnum"> 40: </span> .OfType&lt;LineItem&gt;()</pre>
          <pre>
            <span class="lnum"> 41: </span> .Where(x =&gt; x.ShippingMethodId == Guid.Empty))</pre>
          <pre>
            <span class="lnum"> 42: </span> {</pre>
          <pre>
            <span class="lnum"> 43: </span> lineItem.ShippingMethodId = Guid.NewGuid();</pre>
          <pre>
            <span class="lnum"> 44: </span> }</pre>
          <pre>
            <span class="lnum"> 45: </span> }</pre>
          <pre>
            <span class="lnum"> 46: </span> </pre>
          <pre>
            <span class="lnum"> 47: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">override</span>
            <span class="kwrd">void</span> DeleteRelatedItem(CommerceDeleteRelatedItem
deleteRelatedItemOperation)</pre>
          <pre>
            <span class="lnum"> 48: </span> {</pre>
          <pre>
            <span class="lnum"> 49: </span>
            <span class="kwrd">string</span> shipmentId =
GetSearchModelId(deleteRelatedItemOperation, <span class="str">"Shipment"</span>, <span class="kwrd">true</span>);</pre>
          <pre>
            <span class="lnum"> 50: </span> </pre>
          <pre>
            <span class="lnum"> 51: </span>
            <span class="kwrd">if</span> (!String.IsNullOrEmpty(shipmentId))</pre>
          <pre>
            <span class="lnum"> 52: </span> {</pre>
          <pre>
            <span class="lnum"> 53: </span> Shipment deletingShipment = GetShipmentFromCachedOrderGroup(shipmentId);</pre>
          <pre>
            <span class="lnum"> 54: </span> CachedOrderGroup.GetDefaultOrderForm().Shipments.Remove(deletingShipment);</pre>
          <pre>
            <span class="lnum"> 55: </span> }</pre>
          <pre>
            <span class="lnum"> 56: </span>
            <span class="kwrd">else</span>
          </pre>
          <pre>
            <span class="lnum"> 57: </span> CachedOrderGroup.GetDefaultOrderForm().Shipments.Clear();</pre>
          <pre>
            <span class="lnum"> 58: </span> }</pre>
          <pre>
            <span class="lnum"> 59: </span> </pre>
          <pre>
            <span class="lnum"> 60: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">override</span>
            <span class="kwrd">void</span> UpdateRelatedItem(CommerceUpdateRelatedItem
updateRelatedItemOperation)</pre>
          <pre>
            <span class="lnum"> 61: </span> {</pre>
          <pre>
            <span class="lnum"> 62: </span> OrderForm orderForm = CachedOrderGroup.GetDefaultOrderForm();</pre>
          <pre>
            <span class="lnum"> 63: </span> </pre>
          <pre>
            <span class="lnum"> 64: </span> CommerceEntity model = updateRelatedItemOperation.GetModel(<span class="str">"Shipment"</span>);</pre>
          <pre>
            <span class="lnum"> 65: </span>
            <span class="kwrd">string</span> shipmentId =
GetSearchModelId(updateRelatedItemOperation, <span class="str">"Shipment"</span>, <span class="kwrd">true</span>);</pre>
          <pre>
            <span class="lnum"> 66: </span> </pre>
          <pre>
            <span class="lnum"> 67: </span>
            <span class="kwrd">if</span> (!String.IsNullOrEmpty(shipmentId))</pre>
          <pre>
            <span class="lnum"> 68: </span> {</pre>
          <pre>
            <span class="lnum"> 69: </span> Shipment updatingShipment = GetShipmentFromCachedOrderGroup(shipmentId);</pre>
          <pre>
            <span class="lnum"> 70: </span> Translator.ToExternalEntity(model, updatingShipment);</pre>
          <pre>
            <span class="lnum"> 71: </span> UpdateShippingLineItemsAssociation(updatingShipment,
orderForm);</pre>
          <pre>
            <span class="lnum"> 72: </span> }</pre>
          <pre>
            <span class="lnum"> 73: </span>
            <span class="kwrd">else</span>
          </pre>
          <pre>
            <span class="lnum"> 74: </span> {</pre>
          <pre>
            <span class="lnum"> 75: </span>
            <span class="kwrd">foreach</span> (Shipment shipment <span class="kwrd">in</span> orderForm.Shipments)</pre>
          <pre>
            <span class="lnum"> 76: </span> Translator.ToExternalEntity(model, shipment);</pre>
          <pre>
            <span class="lnum"> 77: </span> }</pre>
          <pre>
            <span class="lnum"> 78: </span> }</pre>
          <pre>
            <span class="lnum"> 79: </span> </pre>
          <pre>
            <span class="lnum"> 80: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">virtual</span> Shipment
GetShipmentFromCachedOrderGroup(<span class="kwrd">string</span> shipmentId)</pre>
          <pre>
            <span class="lnum"> 81: </span> {</pre>
          <pre>
            <span class="lnum"> 82: </span> OrderForm orderForm = CachedOrderGroup.GetDefaultOrderForm();</pre>
          <pre>
            <span class="lnum"> 83: </span> </pre>
          <pre>
            <span class="lnum"> 84: </span>
            <span class="kwrd">int</span> index = orderForm.Shipments.IndexOf(<span class="kwrd">new</span> Guid(shipmentId));</pre>
          <pre>
            <span class="lnum"> 85: </span> </pre>
          <pre>
            <span class="lnum"> 86: </span>
            <span class="kwrd">if</span> (index &lt; 0)</pre>
          <pre>
            <span class="lnum"> 87: </span>
            <span class="kwrd">throw</span> ItemDoesNotExist(<span class="str">"Shipment"</span>,
shipmentId);</pre>
          <pre>
            <span class="lnum"> 88: </span> </pre>
          <pre>
            <span class="lnum"> 89: </span>
            <span class="kwrd">return</span> orderForm.Shipments[index];</pre>
          <pre>
            <span class="lnum"> 90: </span> }</pre>
          <pre>
            <span class="lnum"> 91: </span> </pre>
          <pre>
            <span class="lnum"> 92: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">virtual</span>
            <span class="kwrd">void</span> UpdateShippingLineItemsAssociation(Shipment
shipment, OrderForm orderForm)</pre>
          <pre>
            <span class="lnum"> 93: </span> {</pre>
          <pre>
            <span class="lnum"> 94: </span>
            <span class="kwrd">foreach</span> (LineItem lineItem <span class="kwrd">in</span></pre>
          <pre>
            <span class="lnum"> 95: </span> orderForm.LineItems</pre>
          <pre>
            <span class="lnum"> 96: </span> .OfType&lt;LineItem&gt;()</pre>
          <pre>
            <span class="lnum"> 97: </span> .Where(x =&gt; </pre>
          <pre>
            <span class="lnum"> 98: </span> String.IsNullOrEmpty(x.ShippingMethodName) ||</pre>
          <pre>
            <span class="lnum"> 99: </span> String.Equals(x.ShippingMethodName, shipment.ShippingMethodName,
StringComparison.OrdinalIgnoreCase)))</pre>
          <pre>
            <span class="lnum"> 100: </span> {</pre>
          <pre>
            <span class="lnum"> 101: </span> lineItem.ShippingMethodId = shipment.ShipmentId;</pre>
          <pre>
            <span class="lnum"> 102: </span> shipment.LineItemIndexes.Add(lineItem.Index);</pre>
          <pre>
            <span class="lnum"> 103: </span> }</pre>
          <pre>
            <span class="lnum"> 104: </span> }</pre>
          <pre>
            <span class="lnum"> 105: </span> </pre>
          <pre>
            <span class="lnum"> 106: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">virtual</span> FaultException&lt;ItemDoesNotExistFault&gt;
ItemDoesNotExist(<span class="kwrd">string</span> entityName, <span class="kwrd">string</span> entityId)</pre>
          <pre>
            <span class="lnum"> 107: </span> {</pre>
          <pre>
            <span class="lnum"> 108: </span>
            <span class="kwrd">string</span> message = ProviderResources.ExceptionMessages.GetMessage(<span class="str">"ItemDoesNotExist"</span>, <span class="kwrd">new</span><span class="kwrd">object</span>[0]);</pre>
          <pre>
            <span class="lnum"> 109: </span> </pre>
          <pre>
            <span class="lnum"> 110: </span> var detail = <span class="kwrd">new</span> ItemDoesNotExistFault(message);</pre>
          <pre>
            <span class="lnum"> 111: </span>
            <span class="kwrd">if</span> (!String.IsNullOrEmpty(entityName))</pre>
          <pre>
            <span class="lnum"> 112: </span> {</pre>
          <pre>
            <span class="lnum"> 113: </span> detail.CommerceEntityName = entityName;</pre>
          <pre>
            <span class="lnum"> 114: </span> }</pre>
          <pre>
            <span class="lnum"> 115: </span>
            <span class="kwrd">if</span> (!String.IsNullOrEmpty(entityId))</pre>
          <pre>
            <span class="lnum"> 116: </span> {</pre>
          <pre>
            <span class="lnum"> 117: </span> detail.CommerceEntityId = entityId;</pre>
          <pre>
            <span class="lnum"> 118: </span> }</pre>
          <pre>
            <span class="lnum"> 119: </span> </pre>
          <pre>
            <span class="lnum"> 120: </span>
            <span class="kwrd">return</span>
            <span class="kwrd">new</span> FaultException&lt;ItemDoesNotExistFault&gt;(detail,
message);</pre>
          <pre>
            <span class="lnum"> 121: </span> }</pre>
          <pre>
            <span class="lnum"> 122: </span>}</pre>
        </div>
        <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
This Operation Sequence Component will make sure that all the prerequisites required
for the Total-pipeline component to be executed by the standard OrderPipelineProcessor
are met, and it will make sure that Line Items and the newly created Shipments are
associated to each other. This is particular necessary if you need multiple shipment
– having different line items using different shipment methods.
</p>
        <p>
To register the new Operation Sequence Component we again have to do some work in
the ChannelConfiguration.config:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">Component</span>
            <span class="attr">name</span>
            <span class="kwrd">="Requested
Promo Codes processor"</span>
            <span class="attr">type</span>
            <span class="kwrd">="Microsoft.Commerce.Prov…"</span>
            <span class="kwrd">&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">Configuration</span>
          </pre>
          <pre>
            <span class="lnum"> 3: </span>
            <span class="attr">customElementName</span>
            <span class="kwrd">="RequestedPromoCodesProcessorConfiguration"</span>
          </pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="attr">customElementType</span>
            <span class="kwrd">="Microsoft.Commerce.Providers.Components.RequestedPromoCodesPr…"</span>
            <span class="kwrd">&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 5: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">RequestedPromoCodesProcessorConfiguration</span>
            <span class="attr">promoUserIdentityProperty</span>
            <span class="kwrd">="Email"</span>
            <span class="kwrd">/&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 6: </span>
            <span class="kwrd">&lt;/</span>
            <span class="html">Configuration</span>
            <span class="kwrd">&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 7: </span>
            <span class="kwrd">&lt;/</span>
            <span class="html">Component</span>
            <span class="kwrd">&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 8: </span>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 9: </span>
              <span class="kwrd">&lt;</span>
              <span class="html">Component</span>
              <span class="attr">name</span>
              <span class="kwrd">="Custom
Shipments processor"</span>
              <span class="attr">type</span>
              <span class="kwrd">="Extensions.Providers.Components.CustomShipmentsProcessor,
Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4c1d6c3df403d290"</span>
              <span class="kwrd">/&gt;</span>
            </strong>
          </pre>
          <pre>
            <span class="lnum"> 10: </span>
          </pre>
          <pre>
            <span class="lnum"> 11: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">Component</span>
            <span class="attr">name</span>
            <span class="kwrd">="Payments
processor"</span>
            <span class="attr">type</span>
            <span class="kwrd">="Microsoft.Commerce.Providers.Components.PaymentsProcessor,
Microsoft.Commerce.Providers, Version=1.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35"</span>
            <span class="kwrd">/&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 12: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">Component</span>
            <span class="attr">name</span>
            <span class="kwrd">="Targeting
Profiles"</span>
            <span class="attr">type</span>
            <span class="kwrd">="Microsoft.Commerce.Providers.Components.TargetingProfilesProcessor,
Microsoft.Commerce.Providers, Version=1.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35"</span>
            <span class="kwrd">/&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 13: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">Component</span>
            <span class="attr">name</span>
            <span class="kwrd">="Order
Pipelines Processor"</span>
            <span class="attr">type</span>
            <span class="kwrd">="Microsoft.Commerce.Providers.Components.OrderPipelinesProcessor,
Microsoft.Commerce.Providers, Version=1.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35"</span>
            <span class="kwrd">&gt;</span>
          </pre>
        </div>
        <p>
          <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        </p>
        <p>
The component needs to be added before the Order Pipelines Processor.
</p>
        <p>
Thats it. Execute the query, and the result will look like the following in Customer
and Orders Manager:
</p>
        <p>
 
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2009-1_2.png" target="_blank">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="BasketCS2009-1" border="0" alt="BasketCS2009-1" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2009-1_thumb.png" width="244" height="171" />
          </a>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2009-2_2.png" target="_blank">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="BasketCS2009-2" border="0" alt="BasketCS2009-2" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2009-2_thumb.png" width="244" height="171" />
          </a>
        </p>
        <p>
 
</p>
        <p>
I hope this was useful. If you have any questions or want me to elaborate more on
this subject please don't hesitate to contact me in any way.
</p>
        <img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=b5d7885b-2a8e-4a23-801b-037d3ca7524a" />
      </body>
      <title>How to implement Custom Shipping Methods in Commerce Server</title>
      <guid isPermaLink="false">http://blog.brianh.dk/PermaLink,guid,b5d7885b-2a8e-4a23-801b-037d3ca7524a.aspx</guid>
      <link>http://blog.brianh.dk/2010/10/15/HowToImplementCustomShippingMethodsInCommerceServer.aspx</link>
      <pubDate>Fri, 15 Oct 2010 08:36:37 GMT</pubDate>
      <description>&lt;p&gt;
A couple of years back I wrote a blog-post on &lt;a href="/2007/12/16/HowToExtendCommerceServerPaymentMethodsAndShipmentMethods.aspx"&gt;How
to extend Commerce Server Payment Methods and Shipment Methods&lt;/a&gt; which described
how you could use the Profiles System in Commerce Server to extend properties of Shipment-
and Payment Methods and with very little effort customize the UI of the Customer And
Orders Manager to allow easy management of these new properties. This technique is
definitely still valid, but I’ve would like to explain another approach that overrides
the overall of how Commerce Server handles Shipping Methods to allow custom business
logic, custom pricing etc.
&lt;/p&gt;
&lt;p&gt;
Also this post serves as a (late, but promised) follow up answer to a question asked
on the Commerce Server Forum on MSDN (&lt;a title="http://social.msdn.microsoft.com/Forums/en-US/commserver2009/thread/bca894c3-122a-4f11-8fe0-35e2b49de1b8/#5cad8631-ca9f-47bf-8bd9-5ad01d77ba8c" href="http://social.msdn.microsoft.com/Forums/en-US/commserver2009/thread/bca894c3-122a-4f11-8fe0-35e2b49de1b8/#5cad8631-ca9f-47bf-8bd9-5ad01d77ba8c"&gt;http://social.msdn.microsoft.com/Forums/en-US/commserver2009/thread/bca894c3-122a-4f11-8fe0-35e2b49de1b8/#5cad8631-ca9f-47bf-8bd9-5ad01d77ba8c&lt;/a&gt;)
on how the best way to implement custom business logic for handling shipping in Commerce
Server.
&lt;/p&gt;
&lt;p&gt;
In this blog post I’ll show you can implement custom shipping methods in a Commerce
Server 2007/2009 project. In order to better explain the “Why”-part, I’ll start by
briefly explaining how Commerce Server works out of the box in regards to applying
shipping on a basket. Last but not least I’ll explain the “How”-part, so you can implement
this in your own project.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Shipping out of the box&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Shipping Methods are configured in Customer And Orders Manager. Here you specify name
and description for the different languages that you support, the cost of a given
shipping method based on weight, subtotal or quantity and a Shipping Cost Calculator,
which is a pipeline component that automatically gets executed from the Total-pipeline.
As for prices you cannot specify multiple prices in multiple currencies – &lt;u&gt;so you
are stuck with only prices in one currency&lt;/u&gt;. Also important to mention is that
there is no supported way to extend this schema, e.g. adding new properties, as you
would also read about in my previously mentioned post.
&lt;/p&gt;
&lt;p&gt;
This screenshot below shows the link between a Shipping Method created in Customer
and Orders Manager and how and where this is persisted in the database.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/ShippingMethods_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ShippingMethods" border="0" alt="ShippingMethods" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/ShippingMethods_thumb.png" width="244" height="186" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
In short Shipping Methods are added to a Basket by specifying a ShippingMethodId (Guid)
to your Line Items as shown below for both 2007 and 2009 version of Commerce Server.
&lt;/p&gt;
&lt;p&gt;
In Commerce Server 2007:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;var lineItem = &lt;span class="kwrd"&gt;new&lt;/span&gt; LineItem(&lt;span class="str"&gt;&amp;quot;TestCatalog&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;ProductID&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;null &lt;span class="rem"&gt;/*
VariantID */&lt;/span&gt;&lt;/span&gt;, 1 &lt;span class="rem"&gt;/* Quantity */&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; ShippingMethodId = &lt;span class="kwrd"&gt;new&lt;/span&gt; Guid(&lt;span class="str"&gt;&amp;quot;MethodId
on Shipping Method&amp;quot;&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt;};&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
In Commerce Server 2009:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;lineItem.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;CatalogName&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;TestCatalog&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;lineItem.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;ProductId&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;ProductID&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt;lineItem.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;Quantity&amp;quot;&lt;/span&gt;,
1 &lt;span class="rem"&gt;/* Quantity */&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt;lineItem.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;ShippingMethodId&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;GroupId
on Shipping Method&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
After adding a Line Item to the Basket you run the Total-pipeline in which there is
a number of pipeline component responsible of requesting the database and actually
create one or more instances of the Microsoft.CommerceServer.Runtime.Orders.Shipment
class based on the ShippingMethodId on the Line Items. This new instance then gets
added to the Shipments-collection on the OrderForm. Basically the same as I’m doing
manually in the code example below:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;var orderForm = basket.OrderForms[0];&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;var shipment = &lt;span class="kwrd"&gt;new&lt;/span&gt; Shipment();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt;orderForm.Shipments.Add(shipment);&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
The bottom-line is that you are not in control of the actual creation process of the
Shipment instance, as this is taken care of in the Total-pipeline by the two components
marked in red in the screenshot below.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/PipelineComponents_2.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PipelineComponents" border="0" alt="PipelineComponents" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/PipelineComponents_thumb.png" width="244" height="124" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
If you do try to add it manually the Total-pipeline will throw an error because you
did not specify a ShippingMethodId on your Line Items.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Why use custom shipping?&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
On most of the e-commerce projects I’ve been working on, pricing is a very complex
thing – it heavily depends on a lot of context information like customer, country,
currency, content of the basket, suppliers and sometimes more making it impossible
to setup in Customer and Orders Manager. Sure you can try to create your own Shipping
Cost Calculator pipeline component, but that requires you to do work and &lt;u&gt;business
logic&lt;/u&gt; in the Pipeline infrastructure of Commerce Server, which is cumbersome,
because&amp;#160; you are dealing with COM, magic strings, and weak-types like the IDictionary
and ISimpleList. Also it is difficult to interact with your existing infrastructure
like services, repositories etc from your pipelines, and it is hard to automate tests
for this. Pipeline components are just not the right place to put your business logic
in my opinion.
&lt;/p&gt;
&lt;p&gt;
So what we would really like is to be able to create the Shipping Methods from within
our domain ourselves, being able to specify the price in that proces, e.g. having
the price coming from a calculation made in the backend/ERP-system. And I’ll show
you how to accomplish that in the next section.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;How to implement custom shipping&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
First off we need to modify the Total-pipeline. The two pipeline components marked
in red in the previous image needs to be removed thus making the Total-pipeline look
like in the screenshot below:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/CustomizedPipeline_2.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="CustomizedPipeline" border="0" alt="CustomizedPipeline" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/CustomizedPipeline_thumb.png" width="244" height="182" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
The next steps really depend on whether you are working on a CS 2007 or CS 2009 project.
I’ll start by explaining the CS 2007 approach:
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;CS 2007&lt;/u&gt;
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CreateBasketInCs2007()&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; &lt;span class="rem"&gt;// Create a new basket&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; var basket =&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt; CommerceContext.Current.OrderSystem.GetBasket(Guid.NewGuid(), &lt;span class="str"&gt;&amp;quot;Default2007&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; &lt;span class="rem"&gt;// Create a new OrderForm&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (basket.OrderForms.Count
== 0)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; basket.OrderForms.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; OrderForm());&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; &lt;span class="rem"&gt;// Add some line items&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; productId &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt;[]
{ &lt;span class="str"&gt;&amp;quot;2-1&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;2-2&amp;quot;&lt;/span&gt; })&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt; basket.OrderForms[0].LineItems.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; LineItem(&lt;span class="str"&gt;&amp;quot;TestCatalog&amp;quot;&lt;/span&gt;,
productId, &lt;span class="kwrd"&gt;null&lt;/span&gt;, 1));&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 17: &lt;/span&gt; &lt;span class="rem"&gt;// Add an address&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 18: &lt;/span&gt; var address = &lt;span class="kwrd"&gt;new&lt;/span&gt; OrderAddress(&lt;span class="str"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;,
String.Empty) { FirstName = &lt;span class="str"&gt;&amp;quot;First Name&amp;quot;&lt;/span&gt; };&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 19: &lt;/span&gt; basket.Addresses.Add(address);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 20: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 21: &lt;/span&gt; &lt;span class="rem"&gt;// Add your custom shipment
with custom price (300)&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 22: &lt;/span&gt; basket.OrderForms[0].Shipments.Add(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 23: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Shipment &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 24: &lt;/span&gt; { &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 25: &lt;/span&gt; ShippingMethodName = &lt;span class="str"&gt;&amp;quot;MyShippingMethod&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 26: &lt;/span&gt; ShipmentTrackingNumber = &lt;span class="str"&gt;&amp;quot;My
Tracking&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 27: &lt;/span&gt; ShipmentTotal = 300m, &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 28: &lt;/span&gt; ShippingAddressId = address.OrderAddressId &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 29: &lt;/span&gt; });&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 30: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 31: &lt;/span&gt; &lt;span class="rem"&gt;// Associate Shipping and Line
Items&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 32: &lt;/span&gt; basket.OrderForms[0].Shipments[0].LineItemIndexes.Add(0);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 33: &lt;/span&gt; basket.OrderForms[0].Shipments[0].LineItemIndexes.Add(1);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 34: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 35: &lt;/span&gt; &lt;span class="rem"&gt;// Execute the pipelines&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 36: &lt;/span&gt; &lt;span class="kwrd"&gt;using&lt;/span&gt; (var pipeline
= &lt;span class="kwrd"&gt;new&lt;/span&gt; PipelineInfo(&lt;span class="str"&gt;&amp;quot;Basket&amp;quot;&lt;/span&gt;,
OrderPipelineType.Basket))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 37: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 38: &lt;/span&gt; _writer.WriteLine(basket.RunPipeline(pipeline));&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 39: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 40: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 41: &lt;/span&gt; &lt;span class="kwrd"&gt;using&lt;/span&gt; (var pipeline
= &lt;span class="kwrd"&gt;new&lt;/span&gt; PipelineInfo(&lt;span class="str"&gt;&amp;quot;Total&amp;quot;&lt;/span&gt;,
OrderPipelineType.Total))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 42: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 43: &lt;/span&gt; _writer.WriteLine(basket.RunPipeline(pipeline));&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 44: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 45: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 46: &lt;/span&gt; basket.Save();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 47: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
The example above creates a new Basket, adds some line items, and adds a Shipment
instance with a custom price. The point is that this custom price could come from
anywhere: web-service call to ERP, custom database, custom pricing calculation logic,
etc. Here is the result of the basket shown in Customer and Orders Manager:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2007-1_2.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="BasketCS2007-1" border="0" alt="BasketCS2007-1" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2007-1_thumb.png" width="244" height="171" /&gt;&lt;/a&gt; &lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2007-2_2.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="BasketCS2007-2" border="0" alt="BasketCS2007-2" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2007-2_thumb.png" width="244" height="171" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
To illustrate the same in CS 2009 we need to do a bit more work as shown below.
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;CS 2009&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
Lets start by looking at the actual query code:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CreateBasketInCs2009()&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; var basketUpdateQuery =&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceUpdate&amp;lt;CommerceEntity,
CommerceModelSearch&amp;lt;CommerceEntity&amp;gt;, CommerceBasketUpdateOptionsBuilder&amp;gt;(&lt;span class="str"&gt;&amp;quot;Basket&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; basketUpdateQuery.SearchCriteria.Model.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;UserId&amp;quot;&lt;/span&gt;,
Guid.NewGuid().ToString());&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; basketUpdateQuery.SearchCriteria.Model.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;BasketType&amp;quot;&lt;/span&gt;,
0); &lt;span class="rem"&gt;// Basket&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; basketUpdateQuery.SearchCriteria.Model.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Default2009&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; &lt;span class="rem"&gt;// Must be set to &amp;quot;ReadyForCheckout&amp;quot;
in order to have Total pipeline executed&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; basketUpdateQuery.Model.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;Status&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;ReadyForCheckout&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; basketUpdateQuery.Model.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;BasketType&amp;quot;&lt;/span&gt;,
0); &lt;span class="rem"&gt;// 0 = Basket&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt; &lt;span class="rem"&gt;// Decides whether to run pipelines
or not&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt; basketUpdateQuery.UpdateOptions.RefreshBasket
= &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 17: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 18: &lt;/span&gt; &lt;span class="rem"&gt;// Add an address&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 19: &lt;/span&gt; var address = &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceEntity(&lt;span class="str"&gt;&amp;quot;Address&amp;quot;&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 20: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 21: &lt;/span&gt; Id = Guid.NewGuid().ToString(&lt;span class="str"&gt;&amp;quot;B&amp;quot;&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 22: &lt;/span&gt; };&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 23: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 24: &lt;/span&gt; address.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;AddressName&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Home&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 25: &lt;/span&gt; address.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;First
Name&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 26: &lt;/span&gt; address.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;ProfileAddressId&amp;quot;&lt;/span&gt;,
String.Empty);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 27: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 28: &lt;/span&gt; basketUpdateQuery.RelatedOperations.Add(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 29: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceCreateRelatedItem&amp;lt;CommerceEntity&amp;gt;(&lt;span class="str"&gt;&amp;quot;Addresses&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Address&amp;quot;&lt;/span&gt;)
{ Model = address });&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 30: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 31: &lt;/span&gt; &lt;span class="rem"&gt;// Add some line items&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 32: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; productId &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt;[]
{ &lt;span class="str"&gt;&amp;quot;2-1&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;2-2&amp;quot;&lt;/span&gt; })&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 33: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 34: &lt;/span&gt; var lineItem = &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceEntity(&lt;span class="str"&gt;&amp;quot;LineItem&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 35: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 36: &lt;/span&gt; lineItem.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;ProductId&amp;quot;&lt;/span&gt;,
productId);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 37: &lt;/span&gt; lineItem.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;Quantity&amp;quot;&lt;/span&gt;,
1);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 38: &lt;/span&gt; lineItem.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;CatalogName&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;TestCatalog&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 39: &lt;/span&gt; lineItem.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;ShippingAddressId&amp;quot;&lt;/span&gt;,
address.Id);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 40: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 41: &lt;/span&gt; &lt;span class="rem"&gt;// if using multiple shippings
- use this to pair line item and shipping&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 42: &lt;/span&gt; lineItem.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;ShippingMethodName&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;MyShippingMethod&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 43: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 44: &lt;/span&gt; basketUpdateQuery.RelatedOperations.Add(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 45: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceCreateRelatedItem&amp;lt;CommerceEntity&amp;gt;(&lt;span class="str"&gt;&amp;quot;LineItems&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;LineItem&amp;quot;&lt;/span&gt;)
{ Model = lineItem });&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 46: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 47: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 48: &lt;/span&gt; &lt;span class="rem"&gt;// Add a custom shipment&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 49: &lt;/span&gt; var shipment = &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceEntity(&lt;span class="str"&gt;&amp;quot;Shipment&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 50: &lt;/span&gt; shipment.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;Total&amp;quot;&lt;/span&gt;,
300m); &lt;span class="rem"&gt;// custom price right here!&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 51: &lt;/span&gt; shipment.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;ShippingAddressId&amp;quot;&lt;/span&gt;,
address.Id);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 52: &lt;/span&gt; shipment.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;TrackingNumber&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;some-tracking-code&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 53: &lt;/span&gt; shipment.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;StatusCode&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;some-status&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 54: &lt;/span&gt; shipment.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;ShippingMethodName&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;MyShippingMethod&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 55: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 56: &lt;/span&gt; basketUpdateQuery.RelatedOperations.Add(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 57: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceCreateRelatedItem&amp;lt;CommerceEntity&amp;gt;(&lt;span class="str"&gt;&amp;quot;Shipments&amp;quot;&lt;/span&gt;)
{ Model = shipment });&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 58: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 59: &lt;/span&gt; var operationServiceAgent = &lt;span class="kwrd"&gt;new&lt;/span&gt; OperationServiceAgent();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 60: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 61: &lt;/span&gt; var response =&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 62: &lt;/span&gt; operationServiceAgent&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 63: &lt;/span&gt; .ProcessRequest(Request.CreateCommerceRequestContext(),
basketUpdateQuery.ToRequest())&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 64: &lt;/span&gt; .OperationResponses&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 65: &lt;/span&gt; .Single() &lt;span class="kwrd"&gt;as&lt;/span&gt; CommerceUpdateOperationResponse;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 66: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 67: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var entity &lt;span class="kwrd"&gt;in&lt;/span&gt; response.CommerceEntities
?? Enumerable.Empty&amp;lt;CommerceEntity&amp;gt;())&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 68: &lt;/span&gt; entity.Output(_writer);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 69: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 70: &lt;/span&gt; _writer.WriteLine(&lt;span class="str"&gt;&amp;quot;Count
= {0}&amp;quot;&lt;/span&gt;, response.Count);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 71: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
Executing this query with the standard Operation Sequence Components and Translators
in the Multi Channel Foundation API will fail. The reason why is that there is logic
in these classes that validates whether Line Items have a valid ShippingMethodId in
order to execute the Total-pipeline, and also there is simply no translator to translate
from a CS 2009 Shipment-CommerceEntity to a Shipment-type in CS 2007. 
&lt;/p&gt;
&lt;p&gt;
More work needs to be put in this effort, lets start with the Translator part. First
off we need to extend the current LineItemTranslator to have the ShippingMethodName
translated:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomShippingSupportingLineItemTranslator
: LineItemTranslator&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; TranslateToStronglyTypedCommerceServerProperty(LineItem
commerceServerObject, &lt;span class="kwrd"&gt;string&lt;/span&gt; commerceServerPropertyName, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; result =&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; &lt;span class="kwrd"&gt;base&lt;/span&gt;.TranslateToStronglyTypedCommerceServerProperty(commerceServerObject,
commerceServerPropertyName, &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (!result &amp;amp;&amp;amp; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt; &lt;span class="kwrd"&gt;is&lt;/span&gt; String
&amp;amp;&amp;amp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; String.Equals(commerceServerPropertyName, &lt;span class="str"&gt;&amp;quot;ShippingMethodName&amp;quot;&lt;/span&gt;,
StringComparison.OrdinalIgnoreCase))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; commerceServerObject.ShippingMethodName = &lt;span class="kwrd"&gt;value&lt;/span&gt;.ToString();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; result = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; result;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 17: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 18: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
And register this in the ChannelConfiguration.config:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Translator&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt; &lt;span class="attr"&gt;sourceModelName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;LineItem&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; &lt;span class="attr"&gt;destinationType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.CommerceServer.Runtime.Orders.LineItem,
Microsoft.CommerceServer.Runtime, Version=6.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Extensions.Providers.Translators.CustomShippingSupportingLineItemTranslator,
Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4c1d6c3df403d290&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
Next up is extending the existing ShipmentTranslator to support External Entity translation,
like this:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ExternalEntitySupportingShipmentTranslator
: ShipmentTranslator, IToExternalEntityTranslator&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; PropertyTranslator&amp;lt;Shipment&amp;gt;
_propertyTranslator;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; ExternalEntitySupportingShipmentTranslator()&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; _propertyTranslator = &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; PropertyTranslator&amp;lt;Shipment&amp;gt;(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; TranslateToStronglyTypedCommerceServerProperty,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; TranslateToWeaklyTypedCommerceServerProperty);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Translate(CommerceEntity
sourceCommerceEntity, &lt;span class="kwrd"&gt;object&lt;/span&gt; destination)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 17: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (sourceCommerceEntity
== &lt;span class="kwrd"&gt;null&lt;/span&gt;) &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="str"&gt;&amp;quot;sourceCommerceEntity&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 18: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (destination == &lt;span class="kwrd"&gt;null&lt;/span&gt;) &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="str"&gt;&amp;quot;destination&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 19: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 20: &lt;/span&gt; _propertyTranslator.TranslateToCommerceServer(sourceCommerceEntity,
destination &lt;span class="kwrd"&gt;as&lt;/span&gt; Shipment, &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 21: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 22: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 23: &lt;/span&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; TranslateToWeaklyTypedCommerceServerProperty(Shipment
commerceServerObject, &lt;span class="kwrd"&gt;string&lt;/span&gt; commerceServerPropertyName, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 24: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 25: &lt;/span&gt; commerceServerObject[commerceServerPropertyName]
= &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 26: &lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 27: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 28: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 29: &lt;/span&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; TranslateToStronglyTypedCommerceServerProperty(Shipment
commerceServerObject, &lt;span class="kwrd"&gt;string&lt;/span&gt; commerceServerPropertyName, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 30: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 31: &lt;/span&gt; &lt;span class="kwrd"&gt;switch&lt;/span&gt; (commerceServerPropertyName)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 32: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 33: &lt;/span&gt; &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;ShipmentTotal&amp;quot;&lt;/span&gt;:&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 34: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;value&lt;/span&gt; != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 35: &lt;/span&gt; commerceServerObject.ShipmentTotal = Convert.ToDecimal(&lt;span class="kwrd"&gt;value&lt;/span&gt;,
CultureInfo.InvariantCulture);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 36: &lt;/span&gt; &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 37: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 38: &lt;/span&gt; &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;ShippingAddressId&amp;quot;&lt;/span&gt;:&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 39: &lt;/span&gt; commerceServerObject.ShippingAddressId = &lt;span class="kwrd"&gt;value&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 40: &lt;/span&gt; &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 41: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 42: &lt;/span&gt; &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;ShippingMethodName&amp;quot;&lt;/span&gt;:&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 43: &lt;/span&gt; commerceServerObject.ShippingMethodName = &lt;span class="kwrd"&gt;value&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 44: &lt;/span&gt; &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 45: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 46: &lt;/span&gt; &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;ShippingMethodId&amp;quot;&lt;/span&gt;:&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 47: &lt;/span&gt; Guid methodId = (&lt;span class="kwrd"&gt;value&lt;/span&gt; &lt;span class="kwrd"&gt;is&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;)
? &lt;span class="kwrd"&gt;new&lt;/span&gt; Guid(&lt;span class="kwrd"&gt;value&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;)
: Guid.Empty;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 48: &lt;/span&gt; commerceServerObject.ShippingMethodId = methodId;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 49: &lt;/span&gt; &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 50: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 51: &lt;/span&gt; &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Status&amp;quot;&lt;/span&gt;:&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 52: &lt;/span&gt; commerceServerObject.Status = &lt;span class="kwrd"&gt;value&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 53: &lt;/span&gt; &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 54: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 55: &lt;/span&gt; &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;ShipmentTrackingNumber&amp;quot;&lt;/span&gt;:&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 56: &lt;/span&gt; commerceServerObject.ShipmentTrackingNumber = &lt;span class="kwrd"&gt;value&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 57: &lt;/span&gt; &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 58: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 59: &lt;/span&gt; &lt;span class="kwrd"&gt;default&lt;/span&gt;:&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 60: &lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 61: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 62: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 63: &lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 64: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 65: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
And again register this in the ChannelConfiguration.config:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Translator&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt; &lt;span class="attr"&gt;sourceModelName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Shipment&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; &lt;span class="attr"&gt;destinationType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.CommerceServer.Runtime.Orders.Shipment,
Microsoft.CommerceServer.Runtime, Version=6.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Extensions.Providers.Translators.ExternalEntitySupportingShipmentTranslator,
Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4c1d6c3df403d290&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
This covers the translation part, so we can map/translate from a CS 2009 entity to
a CS 2007 entity.
&lt;/p&gt;
&lt;p&gt;
The next part is where it gets a little tricky. We need to create a custom Operation
Sequence Component, that will take care of the actual creation of the CS 2007 Shipment-instance,
and add this to the Shipments collection of the Basket that we are executing a query
against.
&lt;/p&gt;
&lt;p&gt;
To create a custom Operation Sequence Component, we create the following class:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomShipmentsProcessor
: BasketRelatedItemOperationSequenceComponent&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; RelationshipName&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt; get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Shipments&amp;quot;&lt;/span&gt;;
}&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CreateRelatedItem(CommerceCreateRelatedItem
createRelatedItemOperation)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; CommerceEntity shipmentEntity = createRelatedItemOperation.Model;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; var newShipment =&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; CommerceServerClassFactory.CreateInstance&amp;lt;Shipment&amp;gt;(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt; shipmentEntity.ModelName, CommerceServerArea.Orders);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt; shipmentEntity.Id = newShipment.ShipmentId.ToString(&lt;span class="str"&gt;&amp;quot;B&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 17: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 18: &lt;/span&gt; Translator.ToExternalEntity(shipmentEntity, newShipment);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 19: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 20: &lt;/span&gt; OrderForm orderForm = CachedOrderGroup.GetDefaultOrderForm();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 21: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 22: &lt;/span&gt; UpdateShippingLineItemsAssociation(newShipment,
orderForm);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 23: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 24: &lt;/span&gt; orderForm.Shipments.Add(newShipment);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 25: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 26: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 27: &lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ExecuteUpdate(CommerceUpdateOperation
updateOperation, Microsoft.Commerce.Broker.OperationCacheDictionary operationCache,
CommerceUpdateOperationResponse response)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 28: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 29: &lt;/span&gt; &lt;span class="kwrd"&gt;base&lt;/span&gt;.ExecuteUpdate(updateOperation,
operationCache, response);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 30: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 31: &lt;/span&gt; EnsureLineItemsHasShippingMethod();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 32: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 33: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 34: &lt;/span&gt; &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; EnsureLineItemsHasShippingMethod()&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 35: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 36: &lt;/span&gt; OrderForm orderForm = CachedOrderGroup.GetDefaultOrderForm();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 37: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 38: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (LineItem lineItem &lt;span class="kwrd"&gt;in&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 39: &lt;/span&gt; orderForm.LineItems&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 40: &lt;/span&gt; .OfType&amp;lt;LineItem&amp;gt;()&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 41: &lt;/span&gt; .Where(x =&amp;gt; x.ShippingMethodId == Guid.Empty))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 42: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 43: &lt;/span&gt; lineItem.ShippingMethodId = Guid.NewGuid();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 44: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 45: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 46: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 47: &lt;/span&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DeleteRelatedItem(CommerceDeleteRelatedItem
deleteRelatedItemOperation)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 48: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 49: &lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; shipmentId =
GetSearchModelId(deleteRelatedItemOperation, &lt;span class="str"&gt;&amp;quot;Shipment&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 50: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 51: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (!String.IsNullOrEmpty(shipmentId))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 52: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 53: &lt;/span&gt; Shipment deletingShipment = GetShipmentFromCachedOrderGroup(shipmentId);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 54: &lt;/span&gt; CachedOrderGroup.GetDefaultOrderForm().Shipments.Remove(deletingShipment);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 55: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 56: &lt;/span&gt; &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 57: &lt;/span&gt; CachedOrderGroup.GetDefaultOrderForm().Shipments.Clear();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 58: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 59: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 60: &lt;/span&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; UpdateRelatedItem(CommerceUpdateRelatedItem
updateRelatedItemOperation)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 61: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 62: &lt;/span&gt; OrderForm orderForm = CachedOrderGroup.GetDefaultOrderForm();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 63: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 64: &lt;/span&gt; CommerceEntity model = updateRelatedItemOperation.GetModel(&lt;span class="str"&gt;&amp;quot;Shipment&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 65: &lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; shipmentId =
GetSearchModelId(updateRelatedItemOperation, &lt;span class="str"&gt;&amp;quot;Shipment&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 66: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 67: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (!String.IsNullOrEmpty(shipmentId))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 68: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 69: &lt;/span&gt; Shipment updatingShipment = GetShipmentFromCachedOrderGroup(shipmentId);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 70: &lt;/span&gt; Translator.ToExternalEntity(model, updatingShipment);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 71: &lt;/span&gt; UpdateShippingLineItemsAssociation(updatingShipment,
orderForm);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 72: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 73: &lt;/span&gt; &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 74: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 75: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Shipment shipment &lt;span class="kwrd"&gt;in&lt;/span&gt; orderForm.Shipments)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 76: &lt;/span&gt; Translator.ToExternalEntity(model, shipment);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 77: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 78: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 79: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 80: &lt;/span&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; Shipment
GetShipmentFromCachedOrderGroup(&lt;span class="kwrd"&gt;string&lt;/span&gt; shipmentId)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 81: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 82: &lt;/span&gt; OrderForm orderForm = CachedOrderGroup.GetDefaultOrderForm();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 83: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 84: &lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; index = orderForm.Shipments.IndexOf(&lt;span class="kwrd"&gt;new&lt;/span&gt; Guid(shipmentId));&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 85: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 86: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (index &amp;lt; 0)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 87: &lt;/span&gt; &lt;span class="kwrd"&gt;throw&lt;/span&gt; ItemDoesNotExist(&lt;span class="str"&gt;&amp;quot;Shipment&amp;quot;&lt;/span&gt;,
shipmentId);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 88: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 89: &lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; orderForm.Shipments[index];&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 90: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 91: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 92: &lt;/span&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; UpdateShippingLineItemsAssociation(Shipment
shipment, OrderForm orderForm)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 93: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 94: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (LineItem lineItem &lt;span class="kwrd"&gt;in&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 95: &lt;/span&gt; orderForm.LineItems&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 96: &lt;/span&gt; .OfType&amp;lt;LineItem&amp;gt;()&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 97: &lt;/span&gt; .Where(x =&amp;gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 98: &lt;/span&gt; String.IsNullOrEmpty(x.ShippingMethodName) ||&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 99: &lt;/span&gt; String.Equals(x.ShippingMethodName, shipment.ShippingMethodName,
StringComparison.OrdinalIgnoreCase)))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 100: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 101: &lt;/span&gt; lineItem.ShippingMethodId = shipment.ShipmentId;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 102: &lt;/span&gt; shipment.LineItemIndexes.Add(lineItem.Index);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 103: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 104: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 105: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 106: &lt;/span&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; FaultException&amp;lt;ItemDoesNotExistFault&amp;gt;
ItemDoesNotExist(&lt;span class="kwrd"&gt;string&lt;/span&gt; entityName, &lt;span class="kwrd"&gt;string&lt;/span&gt; entityId)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 107: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 108: &lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; message = ProviderResources.ExceptionMessages.GetMessage(&lt;span class="str"&gt;&amp;quot;ItemDoesNotExist&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[0]);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 109: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 110: &lt;/span&gt; var detail = &lt;span class="kwrd"&gt;new&lt;/span&gt; ItemDoesNotExistFault(message);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 111: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (!String.IsNullOrEmpty(entityName))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 112: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 113: &lt;/span&gt; detail.CommerceEntityName = entityName;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 114: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 115: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (!String.IsNullOrEmpty(entityId))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 116: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 117: &lt;/span&gt; detail.CommerceEntityId = entityId;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 118: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 119: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 120: &lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; FaultException&amp;lt;ItemDoesNotExistFault&amp;gt;(detail,
message);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 121: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 122: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
This Operation Sequence Component will make sure that all the prerequisites required
for the Total-pipeline component to be executed by the standard OrderPipelineProcessor
are met, and it will make sure that Line Items and the newly created Shipments are
associated to each other. This is particular necessary if you need multiple shipment
– having different line items using different shipment methods.
&lt;/p&gt;
&lt;p&gt;
To register the new Operation Sequence Component we again have to do some work in
the ChannelConfiguration.config:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Component&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Requested
Promo Codes processor&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Commerce.Prov…&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Configuration&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; &lt;span class="attr"&gt;customElementName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;RequestedPromoCodesProcessorConfiguration&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; &lt;span class="attr"&gt;customElementType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Commerce.Providers.Components.RequestedPromoCodesPr…&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RequestedPromoCodesProcessorConfiguration&lt;/span&gt; &lt;span class="attr"&gt;promoUserIdentityProperty&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Email&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;strong&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Component&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Custom
Shipments processor&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Extensions.Providers.Components.CustomShipmentsProcessor,
Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4c1d6c3df403d290&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Component&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Payments
processor&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Commerce.Providers.Components.PaymentsProcessor,
Microsoft.Commerce.Providers, Version=1.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Component&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Targeting
Profiles&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Commerce.Providers.Components.TargetingProfilesProcessor,
Microsoft.Commerce.Providers, Version=1.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Component&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Order
Pipelines Processor&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Commerce.Providers.Components.OrderPipelinesProcessor,
Microsoft.Commerce.Providers, Version=1.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;/p&gt;
&lt;p&gt;
The component needs to be added before the Order Pipelines Processor.
&lt;/p&gt;
&lt;p&gt;
Thats it. Execute the query, and the result will look like the following in Customer
and Orders Manager:
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2009-1_2.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="BasketCS2009-1" border="0" alt="BasketCS2009-1" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2009-1_thumb.png" width="244" height="171" /&gt;&lt;/a&gt; &lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2009-2_2.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="BasketCS2009-2" border="0" alt="BasketCS2009-2" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoimplementCustomShippingMethodsinCom_D08F/BasketCS2009-2_thumb.png" width="244" height="171" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
I hope this was useful. If you have any questions or want me to elaborate more on
this subject please don't hesitate to contact me in any way.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=b5d7885b-2a8e-4a23-801b-037d3ca7524a" /&gt;</description>
      <comments>http://blog.brianh.dk/CommentView,guid,b5d7885b-2a8e-4a23-801b-037d3ca7524a.aspx</comments>
      <category>Commerce Server</category>
    </item>
    <item>
      <trackback:ping>http://blog.brianh.dk/Trackback.aspx?guid=c355a310-817e-486a-9c4b-11ff8bd032bc</trackback:ping>
      <pingback:server>http://blog.brianh.dk/pingback.aspx</pingback:server>
      <pingback:target>http://blog.brianh.dk/PermaLink,guid,c355a310-817e-486a-9c4b-11ff8bd032bc.aspx</pingback:target>
      <dc:creator>Brian Holmgård Kristensen</dc:creator>
      <wfw:comment>http://blog.brianh.dk/CommentView,guid,c355a310-817e-486a-9c4b-11ff8bd032bc.aspx</wfw:comment>
      <wfw:commentRss>http://blog.brianh.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=c355a310-817e-486a-9c4b-11ff8bd032bc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Interested in taking your Commerce Server skills to the next level? 
</p>
        <p>
Do you want to know how you can apply custom pricing, custom shipping and custom payment?
</p>
        <p>
These are just some of the subjects that we will be covering in our upcoming <a href="http://www.commerceservertraining.com/instructor-led-classroom/commerce-server-developer-week.aspx">Commerce
Server Developer Week course</a> held in New York and Europe this November. 
</p>
        <p>
          <strong>November 1st – 5th 2010 
<br /></strong>
          <a href="http://www1.hilton.com/en_US/hi/hotel/NYCTSHF-Hilton-Times-Square-New-York/index.do;jsessionid=CB2E27673F69B5F76DE1EC7207D550F5.etc13?brand_id=HI&amp;brand_directory=/en/hi/&amp;xch=735460808,2IESFZ2ABXFAOCSGBJBMVCQ">Hilton
Times Square</a>
          <br />
234 West, 42nd Street 
<br />
New York
</p>
        <p>
          <strong>November 22nd – 26th 2010 
<br /></strong>Quality Airport Hotel Dan 
<br />
Kastruplundgade 15 
<br />
2770 Kastrup, Copenhagen 
<br />
Denmark
</p>
        <p>
Read more and sign-up on <a title="http://www.commerceservertraining.com/events.aspx" href="http://www.commerceservertraining.com/events.aspx">http://www.commerceservertraining.com/events.aspx</a> where
you will also be able to read reviews from previous courses held.
</p>
        <p>
Hope to see you there :-)
</p>
        <img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=c355a310-817e-486a-9c4b-11ff8bd032bc" />
      </body>
      <title>Commerce Server Training in November 2010 &amp;ndash; still spots left</title>
      <guid isPermaLink="false">http://blog.brianh.dk/PermaLink,guid,c355a310-817e-486a-9c4b-11ff8bd032bc.aspx</guid>
      <link>http://blog.brianh.dk/2010/10/05/CommerceServerTrainingInNovember2010NdashStillSpotsLeft.aspx</link>
      <pubDate>Tue, 05 Oct 2010 07:07:12 GMT</pubDate>
      <description>&lt;p&gt;
Interested in taking your Commerce Server skills to the next level? 
&lt;/p&gt;
&lt;p&gt;
Do you want to know how you can apply custom pricing, custom shipping and custom payment?
&lt;/p&gt;
&lt;p&gt;
These are just some of the subjects that we will be covering in our upcoming &lt;a href="http://www.commerceservertraining.com/instructor-led-classroom/commerce-server-developer-week.aspx"&gt;Commerce
Server Developer Week course&lt;/a&gt; held in New York and Europe this November. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;November 1st – 5th 2010 
&lt;br /&gt;
&lt;/strong&gt;&lt;a href="http://www1.hilton.com/en_US/hi/hotel/NYCTSHF-Hilton-Times-Square-New-York/index.do;jsessionid=CB2E27673F69B5F76DE1EC7207D550F5.etc13?brand_id=HI&amp;amp;brand_directory=/en/hi/&amp;amp;xch=735460808,2IESFZ2ABXFAOCSGBJBMVCQ"&gt;Hilton
Times Square&lt;/a&gt; 
&lt;br /&gt;
234 West, 42nd Street 
&lt;br /&gt;
New York
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;November 22nd – 26th 2010 
&lt;br /&gt;
&lt;/strong&gt;Quality Airport Hotel Dan 
&lt;br /&gt;
Kastruplundgade 15 
&lt;br /&gt;
2770 Kastrup, Copenhagen 
&lt;br /&gt;
Denmark
&lt;/p&gt;
&lt;p&gt;
Read more and sign-up on &lt;a title="http://www.commerceservertraining.com/events.aspx" href="http://www.commerceservertraining.com/events.aspx"&gt;http://www.commerceservertraining.com/events.aspx&lt;/a&gt; where
you will also be able to read reviews from previous courses held.
&lt;/p&gt;
&lt;p&gt;
Hope to see you there :-)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=c355a310-817e-486a-9c4b-11ff8bd032bc" /&gt;</description>
      <comments>http://blog.brianh.dk/CommentView,guid,c355a310-817e-486a-9c4b-11ff8bd032bc.aspx</comments>
      <category>Commerce Server</category>
      <category>Training</category>
    </item>
    <item>
      <trackback:ping>http://blog.brianh.dk/Trackback.aspx?guid=ff65ec7c-8922-4dd0-9b9c-f25f79999452</trackback:ping>
      <pingback:server>http://blog.brianh.dk/pingback.aspx</pingback:server>
      <pingback:target>http://blog.brianh.dk/PermaLink,guid,ff65ec7c-8922-4dd0-9b9c-f25f79999452.aspx</pingback:target>
      <dc:creator>Brian Holmgård Kristensen</dc:creator>
      <wfw:comment>http://blog.brianh.dk/CommentView,guid,ff65ec7c-8922-4dd0-9b9c-f25f79999452.aspx</wfw:comment>
      <wfw:commentRss>http://blog.brianh.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=ff65ec7c-8922-4dd0-9b9c-f25f79999452</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
There is a built-in restriction in the new Commerce Server 2009 Foundation API (MCCF
- Multi Channel Commerce Foundation) to only expect one OrderForm instance on the
aggregate root, being the OrderGroup. An OrderGroup is either a Basket or PurchaseOrder
(or OrderTemplate if you are using that).
</p>
        <p>
Below is a simplified diagram of the key classes in the Object Model for the Orders
System. Please notice that we have the OrderForms collection on the OrderGroup class,
where each instance of an OrderForm can be retrieved either by index or by a name
(string). 
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/OnlyoneOrderForminCommerceServer2009_B453/ClassHierachy_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Orders API - class hierachy" border="0" alt="Orders API - class hierachy" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/OnlyoneOrderForminCommerceServer2009_B453/ClassHierachy_thumb.png" width="490" height="506" />
          </a>
        </p>
        <p>
This allows us to create multiple OrderForms, each with their own data like Line Items,
Payments, Shipments etc, and share other data like Addresses, TrackingNumber and a
few more properties on the OrderGroup class. 
</p>
        <p>
In all projects I’ve been working on we don’t actually use the ability to have multiple
OrderForms. We only have one single OrderForm at all times.
</p>
        <p>
The Commerce Server 2007 code would then look something like:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>Basket basket = OrderContext.Current.GetBasket(userId,
basketName);</pre>
          <pre>
            <span class="lnum"> 2: </span> </pre>
          <pre>
            <span class="lnum"> 3: </span>
            <span class="kwrd">if</span> (basket.OrderForms.Count
== 0)</pre>
          <pre>
            <span class="lnum"> 4: </span> basket.OrderForms.Add(<span class="kwrd">new</span> OrderForm());</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
This retrieves a named Basket from the Orders System and if the basket is new, it
will create an instance of OrderForm and add this to the OrderForms collection.
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>basket.OrderForms[0].LineItems.Add(</pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="kwrd">new</span> LineItem(<span class="str">"ProductCatalog"</span>, <span class="str">"ProductID"</span>, <span class="str">"VariantID"</span>,
1m));</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
At some point we would then like to add a Line Item to our basket as illustrated above
where we hardcode the index-value to 0 to retrieve the one and only OrderForm we have.
</p>
        <p>
In Commerce Server 2009 though, we never deal with the actual types, instead we work
with the ICommerceEntity type. The Commerce Server 2009 code for retrieving a basket
would be something like:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>var query = <span class="kwrd">new</span> CommerceQuery&lt;CommerceEntity&gt;(<span class="str">"Basket"</span>);</pre>
          <pre>
            <span class="lnum"> 2: </span> </pre>
          <pre>
            <span class="lnum"> 3: </span>query.SearchCriteria.Model.SetPropertyValue(<span class="str">"UserId"</span>,
userId);</pre>
          <pre>
            <span class="lnum"> 4: </span>query.SearchCriteria.Model.SetPropertyValue(<span class="str">"BasketType"</span>,
0); <span class="rem">// 0 = Basket, 1 = Purchase Order</span></pre>
          <pre>
            <span class="lnum"> 5: </span>query.SearchCriteria.Model.SetPropertyValue(<span class="str">"Name"</span>,
basketName);</pre>
          <pre>
            <span class="lnum"> 6: </span> </pre>
          <pre>
            <span class="lnum"> 7: </span>var operationServiceAgent = <span class="kwrd">new</span> OperationServiceAgent();</pre>
          <pre>
            <span class="lnum"> 8: </span> </pre>
          <pre>
            <span class="lnum"> 9: </span>var response =</pre>
          <pre>
            <span class="lnum"> 10: </span> operationServiceAgent</pre>
          <pre>
            <span class="lnum"> 11: </span> .ProcessRequest(</pre>
          <pre>
            <span class="lnum"> 12: </span>
            <span class="kwrd">new</span> CommerceRequestContext</pre>
          <pre>
            <span class="lnum"> 13: </span> {</pre>
          <pre>
            <span class="lnum"> 14: </span> Channel = <span class="str">"DefaultChannel"</span>,</pre>
          <pre>
            <span class="lnum"> 15: </span> UserId = Guid.NewGuid().ToString(<span class="str">"b"</span>),</pre>
          <pre>
            <span class="lnum"> 16: </span> UserLocale = CultureInfo.CurrentCulture.ToString(),</pre>
          <pre>
            <span class="lnum"> 17: </span> UserUILocale = CultureInfo.CurrentUICulture.ToString(),</pre>
          <pre>
            <span class="lnum"> 18: </span> RequestId = Guid.NewGuid().ToString()</pre>
          <pre>
            <span class="lnum"> 19: </span> }, </pre>
          <pre>
            <span class="lnum"> 20: </span> query.ToRequest())</pre>
          <pre>
            <span class="lnum"> 21: </span> .OperationResponses</pre>
          <pre>
            <span class="lnum"> 22: </span> .Single() <span class="kwrd">as</span> CommerceQueryOperationResponse;</pre>
          <pre>
            <span class="lnum"> 23: </span> </pre>
          <pre>
            <span class="lnum"> 24: </span>var basketEntity = response.CommerceEntities.Single();</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
Effectively this will execute the <strong>CommerceQueryOperation_Basket</strong> Operation
Sequence defined in ChannelConfiguration.config which in short will load the Basket
from the Orders System and map this to the generic ICommerceEntity type. 
</p>
        <p>
In the process of retrieving and mapping a Basket to a ICommerceEntity the following
extension method from Microsoft.Commerce.Providers.Utility.OrderGroupExtensions is
being called on the OrderGroup:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">static</span>
            <span class="kwrd">void</span> EnsureDefaultOrderForm(<span class="kwrd">this</span> OrderGroup
orderGroup, <span class="kwrd">string</span> modelName)</pre>
          <pre>
            <span class="lnum"> 2: </span>{</pre>
          <pre>
            <span class="lnum"> 3: </span> ParameterChecker.CheckForNull(orderGroup, <span class="str">"orderGroup"</span>);</pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="kwrd">if</span> (orderGroup.OrderForms[<span class="str">"Default"</span>]
== <span class="kwrd">null</span>)</pre>
          <pre>
            <span class="lnum"> 5: </span> {</pre>
          <pre>
            <span class="lnum"> 6: </span>
            <span class="kwrd">if</span> (<span class="kwrd">string</span>.IsNullOrEmpty(modelName))</pre>
          <pre>
            <span class="lnum"> 7: </span> {</pre>
          <pre>
            <span class="lnum"> 8: </span> modelName = <span class="str">"Basket"</span>;</pre>
          <pre>
            <span class="lnum"> 9: </span> }</pre>
          <pre>
            <span class="lnum"> 10: </span> OrderForm orderForm = CommerceServerClassFactory.CreateInstance&lt;OrderForm&gt;(modelName,
2, <span class="kwrd">new</span><span class="kwrd">object</span>[] { <span class="str">"Default"</span> });</pre>
          <pre>
            <span class="lnum"> 11: </span> orderGroup.OrderForms.Add(orderForm);</pre>
          <pre>
            <span class="lnum"> 12: </span> }</pre>
          <pre>
            <span class="lnum"> 13: </span>}</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
          <span class="lnum">
          </span>
        </p>
        <p>
          <span class="lnum">This method is responsible of making sure that a single OrderForm
with the name “Default” is always available in the OrderForms collection of the OrderGroup
instance.</span>
        </p>
        <p>
          <span class="lnum">Also there is an extension method to always retrieve this single
OrderForm called Microsoft.Commerce.Providers.Utility.OrderGroupExtensions.GetDefaultOrderForm.</span>
        </p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">static</span> OrderForm
GetDefaultOrderForm(<span class="kwrd">this</span> OrderGroup orderGroup, <span class="kwrd">string</span> modelName)</pre>
          <pre>
            <span class="lnum"> 2: </span>{</pre>
          <pre>
            <span class="lnum"> 3: </span> ParameterChecker.CheckForNull(orderGroup, <span class="str">"orderGroup"</span>);</pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="kwrd">if</span> (orderGroup.OrderForms[<span class="str">"Default"</span>]
== <span class="kwrd">null</span>)</pre>
          <pre>
            <span class="lnum"> 5: </span> {</pre>
          <pre>
            <span class="lnum"> 6: </span>
            <span class="kwrd">if</span> (<span class="kwrd">string</span>.IsNullOrEmpty(modelName))</pre>
          <pre>
            <span class="lnum"> 7: </span> {</pre>
          <pre>
            <span class="lnum"> 8: </span> modelName = <span class="str">"Basket"</span>;</pre>
          <pre>
            <span class="lnum"> 9: </span> }</pre>
          <pre>
            <span class="lnum"> 10: </span> OrderForm orderForm = CommerceServerClassFactory.CreateInstance&lt;OrderForm&gt;(modelName,
2, <span class="kwrd">new</span><span class="kwrd">object</span>[] { <span class="str">"Default"</span> });</pre>
          <pre>
            <span class="lnum"> 11: </span> orderGroup.OrderForms.Add(orderForm);</pre>
          <pre>
            <span class="lnum"> 12: </span> }</pre>
          <pre>
            <span class="lnum"> 13: </span>
            <span class="kwrd">return</span> orderGroup.OrderForms[<span class="str">"Default"</span>];</pre>
          <pre>
            <span class="lnum"> 14: </span>}</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
          <span class="lnum">
          </span>
        </p>
        <p>
          <span class="lnum">This method is used throughout the many Operation Sequence Components
in the Foundation API and if you are developing your own custom Operation Sequence
Components that works on the Orders System this method is properly something you would
like to use.</span>
        </p>
        <p>
          <span class="lnum">As mentioned earlier we’ve just been using one OrderForm in all
our Commerce Server projects, so this new limitation is not a problem for us, but
on one of my Commerce Server Training courses I had a guy telling me that they where
actually using multiple OrderForms on a CS 2007 project, so this new limitation would
be a problem for them if they were to upgrade or create a similar solution on a new
CS 2009 project.</span>
        </p>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
          <strong>What if we need more than OrderForm on our project, what to do?</strong>
        </p>
        <p>
In short: <strong>rethink</strong>. A solution with multiple OrderForms in CS 2009
will be too difficult to implement because of the many dependencies in the standard
Operation Sequence Components that expecting there to be only one – remember they
are all calling the GetDefaultOrderForm() extension method. Consider using multiple
OrderGroups instead.
</p>
        <p>
 
</p>
        <p>
If you are reading this and have come up with a better solution to having multiple
OrderForms in CS 2009 or have any comments at all I would really appreciate hearing
from you :-)
</p>
        <img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=ff65ec7c-8922-4dd0-9b9c-f25f79999452" />
      </body>
      <title>Only one OrderForm in Commerce Server 2009</title>
      <guid isPermaLink="false">http://blog.brianh.dk/PermaLink,guid,ff65ec7c-8922-4dd0-9b9c-f25f79999452.aspx</guid>
      <link>http://blog.brianh.dk/2010/09/06/OnlyOneOrderFormInCommerceServer2009.aspx</link>
      <pubDate>Mon, 06 Sep 2010 06:54:00 GMT</pubDate>
      <description>&lt;p&gt;
There is a built-in restriction in the new Commerce Server 2009 Foundation API (MCCF
- Multi Channel Commerce Foundation) to only expect one OrderForm instance on the
aggregate root, being the OrderGroup. An OrderGroup is either a Basket or PurchaseOrder
(or OrderTemplate if you are using that).
&lt;/p&gt;
&lt;p&gt;
Below is a simplified diagram of the key classes in the Object Model for the Orders
System. Please notice that we have the OrderForms collection on the OrderGroup class,
where each instance of an OrderForm can be retrieved either by index or by a name
(string). 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/OnlyoneOrderForminCommerceServer2009_B453/ClassHierachy_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Orders API - class hierachy" border="0" alt="Orders API - class hierachy" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/OnlyoneOrderForminCommerceServer2009_B453/ClassHierachy_thumb.png" width="490" height="506" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
This allows us to create multiple OrderForms, each with their own data like Line Items,
Payments, Shipments etc, and share other data like Addresses, TrackingNumber and a
few more properties on the OrderGroup class. 
&lt;/p&gt;
&lt;p&gt;
In all projects I’ve been working on we don’t actually use the ability to have multiple
OrderForms. We only have one single OrderForm at all times.
&lt;/p&gt;
&lt;p&gt;
The Commerce Server 2007 code would then look something like:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;Basket basket = OrderContext.Current.GetBasket(userId,
basketName);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (basket.OrderForms.Count
== 0)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; basket.OrderForms.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; OrderForm());&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
This retrieves a named Basket from the Orders System and if the basket is new, it
will create an instance of OrderForm and add this to the OrderForms collection.
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;basket.OrderForms[0].LineItems.Add(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; LineItem(&lt;span class="str"&gt;&amp;quot;ProductCatalog&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;ProductID&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;VariantID&amp;quot;&lt;/span&gt;,
1m));&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
At some point we would then like to add a Line Item to our basket as illustrated above
where we hardcode the index-value to 0 to retrieve the one and only OrderForm we have.
&lt;/p&gt;
&lt;p&gt;
In Commerce Server 2009 though, we never deal with the actual types, instead we work
with the ICommerceEntity type. The Commerce Server 2009 code for retrieving a basket
would be something like:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;var query = &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceQuery&amp;lt;CommerceEntity&amp;gt;(&lt;span class="str"&gt;&amp;quot;Basket&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt;query.SearchCriteria.Model.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;UserId&amp;quot;&lt;/span&gt;,
userId);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt;query.SearchCriteria.Model.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;BasketType&amp;quot;&lt;/span&gt;,
0); &lt;span class="rem"&gt;// 0 = Basket, 1 = Purchase Order&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt;query.SearchCriteria.Model.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
basketName);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt;var operationServiceAgent = &lt;span class="kwrd"&gt;new&lt;/span&gt; OperationServiceAgent();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt;var response =&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; operationServiceAgent&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; .ProcessRequest(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceRequestContext&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt; Channel = &lt;span class="str"&gt;&amp;quot;DefaultChannel&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt; UserId = Guid.NewGuid().ToString(&lt;span class="str"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;),&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt; UserLocale = CultureInfo.CurrentCulture.ToString(),&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 17: &lt;/span&gt; UserUILocale = CultureInfo.CurrentUICulture.ToString(),&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 18: &lt;/span&gt; RequestId = Guid.NewGuid().ToString()&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 19: &lt;/span&gt; }, &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 20: &lt;/span&gt; query.ToRequest())&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 21: &lt;/span&gt; .OperationResponses&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 22: &lt;/span&gt; .Single() &lt;span class="kwrd"&gt;as&lt;/span&gt; CommerceQueryOperationResponse;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 23: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 24: &lt;/span&gt;var basketEntity = response.CommerceEntities.Single();&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
Effectively this will execute the &lt;strong&gt;CommerceQueryOperation_Basket&lt;/strong&gt; Operation
Sequence defined in ChannelConfiguration.config which in short will load the Basket
from the Orders System and map this to the generic ICommerceEntity type. 
&lt;/p&gt;
&lt;p&gt;
In the process of retrieving and mapping a Basket to a ICommerceEntity the following
extension method from Microsoft.Commerce.Providers.Utility.OrderGroupExtensions is
being called on the OrderGroup:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; EnsureDefaultOrderForm(&lt;span class="kwrd"&gt;this&lt;/span&gt; OrderGroup
orderGroup, &lt;span class="kwrd"&gt;string&lt;/span&gt; modelName)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; ParameterChecker.CheckForNull(orderGroup, &lt;span class="str"&gt;&amp;quot;orderGroup&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (orderGroup.OrderForms[&lt;span class="str"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;]
== &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(modelName))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; modelName = &lt;span class="str"&gt;&amp;quot;Basket&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; OrderForm orderForm = CommerceServerClassFactory.CreateInstance&amp;lt;OrderForm&amp;gt;(modelName,
2, &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[] { &lt;span class="str"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt; });&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; orderGroup.OrderForms.Add(orderForm);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&lt;span class="lnum"&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class="lnum"&gt;This method is responsible of making sure that a single OrderForm
with the name “Default” is always available in the OrderForms collection of the OrderGroup
instance.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class="lnum"&gt;Also there is an extension method to always retrieve this single
OrderForm called Microsoft.Commerce.Providers.Utility.OrderGroupExtensions.GetDefaultOrderForm.&lt;/span&gt;
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; OrderForm
GetDefaultOrderForm(&lt;span class="kwrd"&gt;this&lt;/span&gt; OrderGroup orderGroup, &lt;span class="kwrd"&gt;string&lt;/span&gt; modelName)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; ParameterChecker.CheckForNull(orderGroup, &lt;span class="str"&gt;&amp;quot;orderGroup&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (orderGroup.OrderForms[&lt;span class="str"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;]
== &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(modelName))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; modelName = &lt;span class="str"&gt;&amp;quot;Basket&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; OrderForm orderForm = CommerceServerClassFactory.CreateInstance&amp;lt;OrderForm&amp;gt;(modelName,
2, &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[] { &lt;span class="str"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt; });&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; orderGroup.OrderForms.Add(orderForm);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; orderGroup.OrderForms[&lt;span class="str"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;];&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&lt;span class="lnum"&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class="lnum"&gt;This method is used throughout the many Operation Sequence Components
in the Foundation API and if you are developing your own custom Operation Sequence
Components that works on the Orders System this method is properly something you would
like to use.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class="lnum"&gt;As mentioned earlier we’ve just been using one OrderForm in all
our Commerce Server projects, so this new limitation is not a problem for us, but
on one of my Commerce Server Training courses I had a guy telling me that they where
actually using multiple OrderForms on a CS 2007 project, so this new limitation would
be a problem for them if they were to upgrade or create a similar solution on a new
CS 2009 project.&lt;/span&gt;
&lt;/p&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&lt;strong&gt;What if we need more than OrderForm on our project, what to do?&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
In short: &lt;strong&gt;rethink&lt;/strong&gt;. A solution with multiple OrderForms in CS 2009
will be too difficult to implement because of the many dependencies in the standard
Operation Sequence Components that expecting there to be only one – remember they
are all calling the GetDefaultOrderForm() extension method. Consider using multiple
OrderGroups instead.
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
If you are reading this and have come up with a better solution to having multiple
OrderForms in CS 2009 or have any comments at all I would really appreciate hearing
from you :-)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=ff65ec7c-8922-4dd0-9b9c-f25f79999452" /&gt;</description>
      <comments>http://blog.brianh.dk/CommentView,guid,ff65ec7c-8922-4dd0-9b9c-f25f79999452.aspx</comments>
      <category>Commerce Server</category>
    </item>
    <item>
      <trackback:ping>http://blog.brianh.dk/Trackback.aspx?guid=0a3d397c-5f61-47a7-91ef-294571ef9548</trackback:ping>
      <pingback:server>http://blog.brianh.dk/pingback.aspx</pingback:server>
      <pingback:target>http://blog.brianh.dk/PermaLink,guid,0a3d397c-5f61-47a7-91ef-294571ef9548.aspx</pingback:target>
      <dc:creator>Brian Holmgård Kristensen</dc:creator>
      <wfw:comment>http://blog.brianh.dk/CommentView,guid,0a3d397c-5f61-47a7-91ef-294571ef9548.aspx</wfw:comment>
      <wfw:commentRss>http://blog.brianh.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=0a3d397c-5f61-47a7-91ef-294571ef9548</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Max Akbar’s Commerce Server 2007 training videos have yet again become available for
purchase. More than 19 hours of material can now be found on <a title="http://www.commerceservertraining.com/training-videos.aspx" href="http://www.commerceservertraining.com/training-videos.aspx">http://www.commerceservertraining.com/training-videos.aspx</a>. 
</p>
        <p>
We are working on producing and releasing new training videos targeting Commerce Server
2009.
</p>
        <img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=0a3d397c-5f61-47a7-91ef-294571ef9548" />
      </body>
      <title>Commerce Server training videos</title>
      <guid isPermaLink="false">http://blog.brianh.dk/PermaLink,guid,0a3d397c-5f61-47a7-91ef-294571ef9548.aspx</guid>
      <link>http://blog.brianh.dk/2010/09/03/CommerceServerTrainingVideos.aspx</link>
      <pubDate>Fri, 03 Sep 2010 12:27:37 GMT</pubDate>
      <description>&lt;p&gt;
Max Akbar’s Commerce Server 2007 training videos have yet again become available for
purchase. More than 19 hours of material can now be found on &lt;a title="http://www.commerceservertraining.com/training-videos.aspx" href="http://www.commerceservertraining.com/training-videos.aspx"&gt;http://www.commerceservertraining.com/training-videos.aspx&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
We are working on producing and releasing new training videos targeting Commerce Server
2009.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=0a3d397c-5f61-47a7-91ef-294571ef9548" /&gt;</description>
      <comments>http://blog.brianh.dk/CommentView,guid,0a3d397c-5f61-47a7-91ef-294571ef9548.aspx</comments>
      <category>Commerce Server</category>
      <category>Training</category>
    </item>
    <item>
      <trackback:ping>http://blog.brianh.dk/Trackback.aspx?guid=e512ace7-80d4-4ce9-aba2-21cb2487648d</trackback:ping>
      <pingback:server>http://blog.brianh.dk/pingback.aspx</pingback:server>
      <pingback:target>http://blog.brianh.dk/PermaLink,guid,e512ace7-80d4-4ce9-aba2-21cb2487648d.aspx</pingback:target>
      <dc:creator>Brian Holmgård Kristensen</dc:creator>
      <wfw:comment>http://blog.brianh.dk/CommentView,guid,e512ace7-80d4-4ce9-aba2-21cb2487648d.aspx</wfw:comment>
      <wfw:commentRss>http://blog.brianh.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=e512ace7-80d4-4ce9-aba2-21cb2487648d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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:
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoretrieveCategoryRankinCommerceServe_BE87/image_2.png" target="_blank">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoretrieveCategoryRankinCommerceServe_BE87/image_thumb.png" width="244" height="158" />
          </a>
        </p>
        <p>
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.
</p>
        <p>
          <strong>How did we do this in in Commerce Server 2007?</strong>
        </p>
        <p>
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:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">void</span> RequestUsing2007(<span class="kwrd">string</span> catalogName, <span class="kwrd">string</span> categoryName)</pre>
          <pre>
            <span class="lnum"> 2: </span>{</pre>
          <pre>
            <span class="lnum"> 3: </span> var catalogSystem = CommerceContext.Current.CatalogSystem;</pre>
          <pre>
            <span class="lnum"> 4: </span> </pre>
          <pre>
            <span class="lnum"> 5: </span> var configuration = <span class="kwrd">new</span> CategoryConfiguration</pre>
          <pre>
            <span class="lnum"> 6: </span> {</pre>
          <pre>
            <span class="lnum"> 7: </span> LoadChildCategories = <span class="kwrd">true</span>,</pre>
          <pre>
            <span class="lnum"> 8: </span> ChildCategories =</pre>
          <pre>
            <span class="lnum"> 9: </span> {</pre>
          <pre>
            <span class="lnum"> 10: </span> SearchOptions =</pre>
          <pre>
            <span class="lnum"> 11: </span> {</pre>
          <pre>
            <span class="lnum"> 12: </span> PropertiesToReturnArray = <span class="kwrd">new</span>[]
{ <span class="str">"DisplayName"</span>, <span class="str">"Rank"</span> }</pre>
          <pre>
            <span class="lnum"> 13: </span> }</pre>
          <pre>
            <span class="lnum"> 14: </span> }</pre>
          <pre>
            <span class="lnum"> 15: </span> };</pre>
          <pre>
            <span class="lnum"> 16: </span> </pre>
          <pre>
            <span class="lnum"> 17: </span> var category =</pre>
          <pre>
            <span class="lnum"> 18: </span> catalogSystem.GetCategory(catalogName, categoryName, <span class="str">"da-DK"</span>,
configuration);</pre>
          <pre>
            <span class="lnum"> 19: </span> </pre>
          <pre>
            <span class="lnum"> 20: </span>
            <span class="kwrd">foreach</span> (var childCategory <span class="kwrd">in</span> category.ChildCategories)</pre>
          <pre>
            <span class="lnum"> 21: </span> {</pre>
          <pre>
            <span class="lnum"> 22: </span> _writer.WriteLine(<span class="str">"Id={0}"</span>,
childCategory.Name);</pre>
          <pre>
            <span class="lnum"> 23: </span> _writer.WriteLine(<span class="str">"DisplayName={0}"</span>,
childCategory.DisplayName);</pre>
          <pre>
            <span class="lnum"> 24: </span> _writer.WriteLine(<span class="str">"Rank={0}"</span>,
childCategory[<span class="str">"rank"</span>]);</pre>
          <pre>
            <span class="lnum"> 25: </span> </pre>
          <pre>
            <span class="lnum"> 26: </span> _writer.WriteLine();</pre>
          <pre>
            <span class="lnum"> 27: </span> }</pre>
          <pre>
            <span class="lnum"> 28: </span>}</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
          <strong>
          </strong>
        </p>
        <p>
          <strong>And how can I do it in Commerce Server 2009?</strong>
        </p>
        <p>
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):
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">void</span> RequestUsing2009(<span class="kwrd">string</span> catalogName, <span class="kwrd">string</span> categoryName)</pre>
          <pre>
            <span class="lnum"> 2: </span>{</pre>
          <pre>
            <span class="lnum"> 3: </span> var categoryQuery = <span class="kwrd">new</span> CommerceQuery&lt;CommerceEntity&gt;(<span class="str">"Category"</span>);</pre>
          <pre>
            <span class="lnum"> 4: </span> categoryQuery.Model.Properties.Add(<span class="kwrd">new</span>[]
{ <span class="str">"Id"</span>, <span class="str">"DisplayName"</span> });</pre>
          <pre>
            <span class="lnum"> 5: </span> </pre>
          <pre>
            <span class="lnum"> 6: </span> categoryQuery.SearchCriteria.Model.SetPropertyValue(<span class="str">"CatalogId"</span>,
catalogName);</pre>
          <pre>
            <span class="lnum"> 7: </span> categoryQuery.SearchCriteria.Model.SetPropertyValue(<span class="str">"Id"</span>,
categoryName);</pre>
          <pre>
            <span class="lnum"> 8: </span> </pre>
          <pre>
            <span class="lnum"> 9: </span> var childCategoryQuery = <span class="kwrd">new</span> CommerceQueryRelatedItem&lt;CommerceEntity&gt;(<span class="str">"ChildCategories"</span>, <span class="str">"Category"</span>);</pre>
          <pre>
            <span class="lnum"> 10: </span> childCategoryQuery.Model.Properties.Add(<span class="kwrd">new</span>[]
{ <span class="str">"Id"</span>, <span class="str">"DisplayName"</span>, <span class="str">"Rank"</span> });</pre>
          <pre>
            <span class="lnum"> 11: </span> categoryQuery.RelatedOperations.Add(childCategoryQuery);</pre>
          <pre>
            <span class="lnum"> 12: </span> </pre>
          <pre>
            <span class="lnum"> 13: </span> var operationServiceAgent = <span class="kwrd">new</span> OperationServiceAgent();</pre>
          <pre>
            <span class="lnum"> 14: </span> </pre>
          <pre>
            <span class="lnum"> 15: </span> var response = </pre>
          <pre>
            <span class="lnum"> 16: </span> operationServiceAgent.ProcessRequest(</pre>
          <pre>
            <span class="lnum"> 17: </span>
            <span class="kwrd">new</span> CommerceRequestContext</pre>
          <pre>
            <span class="lnum"> 18: </span> {</pre>
          <pre>
            <span class="lnum"> 19: </span> Channel = <span class="str">"MyChannel"</span>,</pre>
          <pre>
            <span class="lnum"> 20: </span> UserLocale = <span class="str">"da-DK"</span>,</pre>
          <pre>
            <span class="lnum"> 21: </span> UserUILocale = <span class="str">"da-DK"</span>,</pre>
          <pre>
            <span class="lnum"> 22: </span> RequestId = Guid.NewGuid().ToString()</pre>
          <pre>
            <span class="lnum"> 23: </span> }, </pre>
          <pre>
            <span class="lnum"> 24: </span> categoryQuery.ToRequest());</pre>
          <pre>
            <span class="lnum"> 25: </span> </pre>
          <pre>
            <span class="lnum"> 26: </span> var operationResponse = (CommerceQueryOperationResponse)response.OperationResponses.Single();</pre>
          <pre>
            <span class="lnum"> 27: </span> </pre>
          <pre>
            <span class="lnum"> 28: </span> var entity = operationResponse.CommerceEntities.SingleOrDefault();</pre>
          <pre>
            <span class="lnum"> 29: </span> </pre>
          <pre>
            <span class="lnum"> 30: </span>
            <span class="kwrd">foreach</span> (var childCategory <span class="kwrd">in</span> entity.Properties[<span class="str">"ChildCategories"</span>] <span class="kwrd">as</span> CommerceRelationshipList)</pre>
          <pre>
            <span class="lnum"> 31: </span> {</pre>
          <pre>
            <span class="lnum"> 32: </span>
            <span class="kwrd">foreach</span> (var categoryProperty <span class="kwrd">in</span> childCategory.Target.Properties)</pre>
          <pre>
            <span class="lnum"> 33: </span> {</pre>
          <pre>
            <span class="lnum"> 34: </span> _writer.WriteLine</pre>
          <pre>
            <span class="lnum"> 35: </span> (<span class="str">"{0}={1} ({2})"</span>, </pre>
          <pre>
            <span class="lnum"> 36: </span> categoryProperty.Key, </pre>
          <pre>
            <span class="lnum"> 37: </span> categoryProperty.Value, </pre>
          <pre>
            <span class="lnum"> 38: </span> categoryProperty.Value.GetType().Name);</pre>
          <pre>
            <span class="lnum"> 39: </span> }</pre>
          <pre>
            <span class="lnum"> 40: </span> </pre>
          <pre>
            <span class="lnum"> 41: </span> _writer.WriteLine();</pre>
          <pre>
            <span class="lnum"> 42: </span> }</pre>
          <pre>
            <span class="lnum"> 43: </span>}</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
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”. 
</p>
        <p>
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”).
</p>
        <p>
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.
</p>
        <p>
To make sure that Rank is registred in MetadataDefinitions.xml verify it by follow
these steps:
</p>
        <ol>
          <li>
Open MetadataDefinitions.xml</li>
          <li>
Locate &lt;CommerceEntity name=”Category”&gt;</li>
          <li>
Make sure that there is a &lt;PropertyMapping&gt; element for property=”Rank” (&lt;PropertyMapping
property=”Rank” csProperty=”rank” /&gt;)</li>
          <li>
Make sure that there is a &lt;Property&gt; element for name=”Rank” (&lt;Property name=”Rank”
dataType=”String” /&gt;)</li>
        </ol>
        <p>
Step 3 explained:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">EntityMappings</span>
            <span class="kwrd">&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">EntityMapping</span>
          </pre>
          <pre>
            <span class="lnum"> 3: </span>
            <span class="attr">csType</span>
            <span class="kwrd">="Microsoft.CommerceServer.Catalog.Category"</span>
          </pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="attr">csAssembly</span>
            <span class="kwrd">="Microsoft.CommerceServer.Catalog,
Version=6.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"</span>
            <span class="kwrd">&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 5: </span> </pre>
          <pre>
            <span class="lnum"> 6: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">PropertyMappings</span>
            <span class="kwrd">&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 7: </span>
            <span class="rem">&lt;!-- </span>
          </pre>
          <pre>
            <span class="lnum"> 8: </span>
            <span class="rem"> The following mappings are required
here to ensure that all</span>
          </pre>
          <pre>
            <span class="lnum"> 9: </span>
            <span class="rem"> the product common properties
are represented in the Microsoft Multi-Channel Commerce Foundation </span>
          </pre>
          <pre>
            <span class="lnum"> 10: </span>
            <span class="rem"> metadata. These are not returned
by the Commerce Server</span>
          </pre>
          <pre>
            <span class="lnum"> 11: </span>
            <span class="rem"> metadata automatically as the
common properties.</span>
          </pre>
          <pre>
            <span class="lnum"> 12: </span>
            <span class="rem"> --&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 13: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">PropertyMapping</span>
            <span class="attr">property</span>
            <span class="kwrd">="BaseCatalogName"</span>
            <span class="attr">csProperty</span>
            <span class="kwrd">="BaseCatalogName"</span>
            <span class="kwrd">/&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 14: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">PropertyMapping</span>
            <span class="attr">property</span>
            <span class="kwrd">="Rank"</span>
            <span class="attr">csProperty</span>
            <span class="kwrd">="rank"</span>
            <span class="kwrd">/&gt;</span>
          </pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
Step 4 explained:
</p>
        <div class="csharpcode">
          <pre>
            <span class="lnum"> 1: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">Properties</span>
            <span class="kwrd">&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="rem">&lt;!-- </span>
          </pre>
          <pre>
            <span class="lnum"> 3: </span>
            <span class="rem"> The following property definitions
are required here to ensure that all</span>
          </pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="rem"> the product common properties
are represented in the </span>
          </pre>
          <pre>
            <span class="lnum"> 5: </span>
            <span class="rem"> metadata. These are not returned
by the Commerce Server</span>
          </pre>
          <pre>
            <span class="lnum"> 6: </span>
            <span class="rem"> metadata automatically as the
common properties.</span>
          </pre>
          <pre>
            <span class="lnum"> 7: </span>
            <span class="rem"> --&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 8: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">Property</span>
            <span class="attr">name</span>
            <span class="kwrd">="BaseCatalogName"</span>
            <span class="attr">dataType</span>
            <span class="kwrd">="String"</span>
            <span class="kwrd">&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 9: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">DisplayName</span>
            <span class="attr">value</span>
            <span class="kwrd">="Base
Catalog Name"</span>
            <span class="kwrd">/&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 10: </span>
            <span class="kwrd">&lt;/</span>
            <span class="html">Property</span>
            <span class="kwrd">&gt;</span>
          </pre>
          <pre>
            <span class="lnum"> 11: </span>
            <span class="kwrd">&lt;</span>
            <span class="html">Property</span>
            <span class="attr">name</span>
            <span class="kwrd">="Rank"</span>
            <span class="attr">dataType</span>
            <span class="kwrd">="String"</span>
            <span class="kwrd">/&gt;</span>
          </pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
        </p>
        <p>
        </p>
        <p>
That’s it! The response returned by the Foundation API should now have the actual
Rank value returned for each child category entity:
</p>
        <pre class="csharpcode">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)</pre>
        <img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=e512ace7-80d4-4ce9-aba2-21cb2487648d" />
      </body>
      <title>How to retrieve Category Rank in Commerce Server 2009</title>
      <guid isPermaLink="false">http://blog.brianh.dk/PermaLink,guid,e512ace7-80d4-4ce9-aba2-21cb2487648d.aspx</guid>
      <link>http://blog.brianh.dk/2010/04/27/HowToRetrieveCategoryRankInCommerceServer2009.aspx</link>
      <pubDate>Tue, 27 Apr 2010 11:00:00 GMT</pubDate>
      <description>&lt;p&gt;
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:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoretrieveCategoryRankinCommerceServe_BE87/image_2.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/HowtoretrieveCategoryRankinCommerceServe_BE87/image_thumb.png" width="244" height="158" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;How did we do this in in Commerce Server 2007?&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RequestUsing2007(&lt;span class="kwrd"&gt;string&lt;/span&gt; catalogName, &lt;span class="kwrd"&gt;string&lt;/span&gt; categoryName)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; var catalogSystem = CommerceContext.Current.CatalogSystem;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt; var configuration = &lt;span class="kwrd"&gt;new&lt;/span&gt; CategoryConfiguration&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; LoadChildCategories = &lt;span class="kwrd"&gt;true&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; ChildCategories =&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; SearchOptions =&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; PropertiesToReturnArray = &lt;span class="kwrd"&gt;new&lt;/span&gt;[]
{ &lt;span class="str"&gt;&amp;quot;DisplayName&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Rank&amp;quot;&lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt; };&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 17: &lt;/span&gt; var category =&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 18: &lt;/span&gt; catalogSystem.GetCategory(catalogName, categoryName, &lt;span class="str"&gt;&amp;quot;da-DK&amp;quot;&lt;/span&gt;,
configuration);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 19: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 20: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var childCategory &lt;span class="kwrd"&gt;in&lt;/span&gt; category.ChildCategories)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 21: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 22: &lt;/span&gt; _writer.WriteLine(&lt;span class="str"&gt;&amp;quot;Id={0}&amp;quot;&lt;/span&gt;,
childCategory.Name);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 23: &lt;/span&gt; _writer.WriteLine(&lt;span class="str"&gt;&amp;quot;DisplayName={0}&amp;quot;&lt;/span&gt;,
childCategory.DisplayName);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 24: &lt;/span&gt; _writer.WriteLine(&lt;span class="str"&gt;&amp;quot;Rank={0}&amp;quot;&lt;/span&gt;,
childCategory[&lt;span class="str"&gt;&amp;quot;rank&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 25: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 26: &lt;/span&gt; _writer.WriteLine();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 27: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 28: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&lt;strong&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;And how can I do it in Commerce Server 2009?&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
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):
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RequestUsing2009(&lt;span class="kwrd"&gt;string&lt;/span&gt; catalogName, &lt;span class="kwrd"&gt;string&lt;/span&gt; categoryName)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; var categoryQuery = &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceQuery&amp;lt;CommerceEntity&amp;gt;(&lt;span class="str"&gt;&amp;quot;Category&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; categoryQuery.Model.Properties.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt;[]
{ &lt;span class="str"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;DisplayName&amp;quot;&lt;/span&gt; });&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; categoryQuery.SearchCriteria.Model.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;CatalogId&amp;quot;&lt;/span&gt;,
catalogName);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; categoryQuery.SearchCriteria.Model.SetPropertyValue(&lt;span class="str"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;,
categoryName);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; var childCategoryQuery = &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceQueryRelatedItem&amp;lt;CommerceEntity&amp;gt;(&lt;span class="str"&gt;&amp;quot;ChildCategories&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Category&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; childCategoryQuery.Model.Properties.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt;[]
{ &lt;span class="str"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;DisplayName&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Rank&amp;quot;&lt;/span&gt; });&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; categoryQuery.RelatedOperations.Add(childCategoryQuery);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; var operationServiceAgent = &lt;span class="kwrd"&gt;new&lt;/span&gt; OperationServiceAgent();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt; var response = &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt; operationServiceAgent.ProcessRequest(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 17: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CommerceRequestContext&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 18: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 19: &lt;/span&gt; Channel = &lt;span class="str"&gt;&amp;quot;MyChannel&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 20: &lt;/span&gt; UserLocale = &lt;span class="str"&gt;&amp;quot;da-DK&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 21: &lt;/span&gt; UserUILocale = &lt;span class="str"&gt;&amp;quot;da-DK&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 22: &lt;/span&gt; RequestId = Guid.NewGuid().ToString()&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 23: &lt;/span&gt; }, &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 24: &lt;/span&gt; categoryQuery.ToRequest());&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 25: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 26: &lt;/span&gt; var operationResponse = (CommerceQueryOperationResponse)response.OperationResponses.Single();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 27: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 28: &lt;/span&gt; var entity = operationResponse.CommerceEntities.SingleOrDefault();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 29: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 30: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var childCategory &lt;span class="kwrd"&gt;in&lt;/span&gt; entity.Properties[&lt;span class="str"&gt;&amp;quot;ChildCategories&amp;quot;&lt;/span&gt;] &lt;span class="kwrd"&gt;as&lt;/span&gt; CommerceRelationshipList)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 31: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 32: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var categoryProperty &lt;span class="kwrd"&gt;in&lt;/span&gt; childCategory.Target.Properties)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 33: &lt;/span&gt; {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 34: &lt;/span&gt; _writer.WriteLine&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 35: &lt;/span&gt; (&lt;span class="str"&gt;&amp;quot;{0}={1} ({2})&amp;quot;&lt;/span&gt;, &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 36: &lt;/span&gt; categoryProperty.Key, &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 37: &lt;/span&gt; categoryProperty.Value, &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 38: &lt;/span&gt; categoryProperty.Value.GetType().Name);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 39: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 40: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 41: &lt;/span&gt; _writer.WriteLine();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 42: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 43: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
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”. 
&lt;/p&gt;
&lt;p&gt;
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”).
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
To make sure that Rank is registred in MetadataDefinitions.xml verify it by follow
these steps:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Open MetadataDefinitions.xml&lt;/li&gt;
&lt;li&gt;
Locate &amp;lt;CommerceEntity name=”Category”&amp;gt;&lt;/li&gt;
&lt;li&gt;
Make sure that there is a &amp;lt;PropertyMapping&amp;gt; element for property=”Rank” (&amp;lt;PropertyMapping
property=”Rank” csProperty=”rank” /&amp;gt;)&lt;/li&gt;
&lt;li&gt;
Make sure that there is a &amp;lt;Property&amp;gt; element for name=”Rank” (&amp;lt;Property name=”Rank”
dataType=”String” /&amp;gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Step 3 explained:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EntityMappings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EntityMapping&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; &lt;span class="attr"&gt;csType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.CommerceServer.Catalog.Category&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; &lt;span class="attr"&gt;csAssembly&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.CommerceServer.Catalog,
Version=6.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt;&amp;#160;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PropertyMappings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; &lt;span class="rem"&gt;&amp;lt;!-- &lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt;&lt;span class="rem"&gt; The following mappings are required
here to ensure that all&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt;&lt;span class="rem"&gt; the product common properties
are represented in the Microsoft Multi-Channel Commerce Foundation &lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt;&lt;span class="rem"&gt; metadata. These are not returned
by the Commerce Server&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt;&lt;span class="rem"&gt; metadata automatically as the
common properties.&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt;&lt;span class="rem"&gt; --&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PropertyMapping&lt;/span&gt; &lt;span class="attr"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;BaseCatalogName&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;csProperty&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;BaseCatalogName&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PropertyMapping&lt;/span&gt; &lt;span class="attr"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Rank&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;csProperty&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;rank&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
Step 4 explained:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Properties&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt; &lt;span class="rem"&gt;&amp;lt;!-- &lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt;&lt;span class="rem"&gt; The following property definitions
are required here to ensure that all&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt;&lt;span class="rem"&gt; the product common properties
are represented in the &lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt;&lt;span class="rem"&gt; metadata. These are not returned
by the Commerce Server&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt;&lt;span class="rem"&gt; metadata automatically as the
common properties.&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt;&lt;span class="rem"&gt; --&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;BaseCatalogName&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;dataType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;String&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DisplayName&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Base
Catalog Name&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Rank&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;dataType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;String&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
That’s it! The response returned by the Foundation API should now have the actual
Rank value returned for each child category entity:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;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)&lt;/pre&gt;
&lt;img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=e512ace7-80d4-4ce9-aba2-21cb2487648d" /&gt;</description>
      <comments>http://blog.brianh.dk/CommentView,guid,e512ace7-80d4-4ce9-aba2-21cb2487648d.aspx</comments>
      <category>Commerce Server</category>
    </item>
    <item>
      <trackback:ping>http://blog.brianh.dk/Trackback.aspx?guid=164f993f-6e1b-4b39-8e91-def5508a5232</trackback:ping>
      <pingback:server>http://blog.brianh.dk/pingback.aspx</pingback:server>
      <pingback:target>http://blog.brianh.dk/PermaLink,guid,164f993f-6e1b-4b39-8e91-def5508a5232.aspx</pingback:target>
      <dc:creator>Brian Holmgård Kristensen</dc:creator>
      <wfw:comment>http://blog.brianh.dk/CommentView,guid,164f993f-6e1b-4b39-8e91-def5508a5232.aspx</wfw:comment>
      <wfw:commentRss>http://blog.brianh.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=164f993f-6e1b-4b39-8e91-def5508a5232</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is a brief story of my impressions and experiences with the first couple of days
attending TechEd 2009 North America.
</p>
        <p>
So after more than 24 hours of travelling from source (Århus, Denmark) to destination
(Los Angeles, CA, USA) I finally arrived at the hotel Saturday evening. I’m staying
at a very nice hotel called Hollywood Roosevelt Hotel, just across Kodak Theatre (the
place where the Oscar Academy Award takes place every year) on Hollywood Boulevard.
</p>
        <p>
          <strong>Pre-Conference</strong>
        </p>
        <p>
I was signed up to participate in the Pre-Conference part of TechEd, joining in on
a whole-day seminar with the topic “The ASP.NET Performance Tuning Cycle”. Stuff I
was really looking forward hearing about since we are focusing a lot on performance
improvements at Vertica on our projects. The seminar was held by Richard Campbell
and Kent Alstad and man those two Canadian guys were really on fire that day. We came
around lots of different areas including how to do load-testing with Visual Studio
2008 Team System (Test Edition), load-balancing, how to analyze the response time
of a web-site and much more. Generally a whole lot of good advices on how to look
at the whole picture of optimizing a given web-site – where to put the energy basically.
On advice I would like to highlight here is to use <a href="http://www.webpagetest.org">www.webpagetest.org</a> as
an external tool to analyze your web-site.
</p>
        <p>
After a great and educational day in company with Richard and Kent I was all psyched
about the rest of the conference. I went to see the movie “Wolverine” after getting
back to the hotel.
</p>
        <p>
          <strong>Day 1 – Keynote, ASP.NET 4.0, SharePoint</strong>
        </p>
        <p>
First day of TechEd started out with the Keynote speech as one would expect. I must
admit I wasn’t that enthusiastic about this particular Keynote and as it turned out
I wasn’t proved really wrong on that hunch. The Keynote was primarily held by Bill
Veghte, Microsoft Senior Vice President on Windows Business. The topics were all about
the IT-stuff going on right know with focus on the soon to come operating systems;
Windows 7 and Windows Server 2008 R2. Not that I’m not interested in those topics
at all, I just wanted to see some developer stuff too – unfortunately there was none. 
</p>
        <p>
The first actual session I attended was about ASP.NET 4.0 and what’s coming in that
release. It was a pretty good one. Jeff King showed some examples of how you are now
able to have more fine-grained control over the markup rendered by the ASP.NET WebForms
Framework, some better support for SEO-stuff including new properties on the System.Web.Page
class for meta-keywords and –description and generally some new controls to do LINQ-based
operations (e.g. Filtering and Sorting) on your LINQ-enabled backend datasource. 
</p>
        <p>
The last two sessions I attended that day were both about SharePoint development.
The first was focusing on tooling for SharePoint development, especially with focus
on using the tool VSeWSS 1.3 (Visual Studio extensions for Windows SharePoint Services).
The last session was about how to develop Windows Workflow Foundations to use inside
WSS/MOSS applications. This session was held by Ted Pattison, SharePoint MVP and book-writer,
and now from my experience a really good presenter. I didn’t get much out of the course
technically-wise though since we’ve already been doing a lot of the stuff that he
presented. 
</p>
        <p>
Next up after first-day sessions was the Partner Expo Reception event which I attended.
It can best be described as a circus where all the audience gets magically drawn by
all the stuff and weird contests offered by the different vendors. But they had food
and <u>beer</u>, and I got a few good talks with some of the different vendors – including
a nice demo by a Red Gate Software guy on the soon-to-be-released new version of ANTS
Memory Profiler. And yeah of course I got a lot of swag too :-)
</p>
        <p>
          <strong>Day 2 – More SharePoint, C#, Commerce Server 2009, Parallels, Web Deployment</strong>
        </p>
        <p>
The second day started out with a morning session by Todd Bleeker on SharePoint Web
Part Development Best Practices. Todd had a lot of energy on the stage and that was
just really awesome! Even though the session was about Best Practices over half of
the audience was rather new to Web Part development which had the impact of Todd having
to explain a lot more of the basics taking time from the really interesting stuff.
Pretty unfortunate also was that time completely ran out for Todd so he didn’t come
around all of his points. All in all I think it was a great session mostly because
of Todd’s enthusiasm. And I did get some good advices to take me back home.
</p>
        <p>
I also attended Anders Hejlsberg’s session on “Future of C#”, which I enjoyed a lot
– mostly because I think he rocks. To be more specific and professional about it I
believe that the future “Compiler As A Service”-feature can really leverage some interesting
possibilities to the table, e.g. for an easy way stick-in additional behavior to your
code (logging, validation, pre-/post conditions, etc.) to allow cross-cutting concerns
to be addressed as secondary concerns.
</p>
        <p>
After having a brief chat with one of the guys at the Commerce Server booth he had
me convinced that I should go to their interactive session on Commerce Server 2009
Foundation Services. So I did (later to discover that I thereby missed a Scott Hanselmann
session!). Although they had a whole lot of technical problems at this session, I
got a pretty good understanding of the upcoming Commerce Server 2009 R2 version including
the support of having Commerce Server configured as a true 3-tier environment with
Commerce Server as an application server in the middle of this. I’m soon to begin
on a new Commerce Server 2009 project which I look really forward to, but seeing that
new Foundation API kind of shocks me a little – to me it is extremely verbose compared
to the CS 2007 API, and the amount of XML configuration doesn’t seem to have become
any less I’m afraid. Perhaps wrapping the new very generic API in a nice fluent and
slightly more specific API might just do the trick for me. We’ll see about that.
</p>
        <p>
Next in line was a interesting session on Parallel Computing APIs with .NET 4.0. It
gave me a good overview and examples of the possibilities with parallelism that you
can get using the new framework that will be baked into .NET 4.0.
</p>
        <p>
Last but not least this I attended a session on Web Application Deployment Packaging
and Migration – a look into some new possibilities in IIS about importing and exporting
applications and on how to package your solution to allow smooth GUI-enabled installation
on IIS. At the session, Faith Allington showed the new Web Platform Installer from
Microsoft which I personally think is a awesome tool. Both BlogEngine.NET and Umbraco
got some visual attention at this session being on the list of web-applications available
on the Web Platform Installer. Faith did really well on this presentation clearly
having a lot of knowledge of what she was talking about.
</p>
        <p>
All in all a great day with good sessions by excellent speakers.
</p>
        <img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=164f993f-6e1b-4b39-8e91-def5508a5232" />
      </body>
      <title>Midway impressions on Tech-Ed North America 2009</title>
      <guid isPermaLink="false">http://blog.brianh.dk/PermaLink,guid,164f993f-6e1b-4b39-8e91-def5508a5232.aspx</guid>
      <link>http://blog.brianh.dk/2009/05/13/MidwayImpressionsOnTechEdNorthAmerica2009.aspx</link>
      <pubDate>Wed, 13 May 2009 04:25:37 GMT</pubDate>
      <description>&lt;p&gt;
This is a brief story of my impressions and experiences with the first couple of days
attending TechEd 2009 North America.
&lt;/p&gt;
&lt;p&gt;
So after more than 24 hours of travelling from source (Århus, Denmark) to destination
(Los Angeles, CA, USA) I finally arrived at the hotel Saturday evening. I’m staying
at a very nice hotel called Hollywood Roosevelt Hotel, just across Kodak Theatre (the
place where the Oscar Academy Award takes place every year) on Hollywood Boulevard.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Pre-Conference&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
I was signed up to participate in the Pre-Conference part of TechEd, joining in on
a whole-day seminar with the topic “The ASP.NET Performance Tuning Cycle”. Stuff I
was really looking forward hearing about since we are focusing a lot on performance
improvements at Vertica on our projects. The seminar was held by Richard Campbell
and Kent Alstad and man those two Canadian guys were really on fire that day. We came
around lots of different areas including how to do load-testing with Visual Studio
2008 Team System (Test Edition), load-balancing, how to analyze the response time
of a web-site and much more. Generally a whole lot of good advices on how to look
at the whole picture of optimizing a given web-site – where to put the energy basically.
On advice I would like to highlight here is to use &lt;a href="http://www.webpagetest.org"&gt;www.webpagetest.org&lt;/a&gt; as
an external tool to analyze your web-site.
&lt;/p&gt;
&lt;p&gt;
After a great and educational day in company with Richard and Kent I was all psyched
about the rest of the conference. I went to see the movie “Wolverine” after getting
back to the hotel.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Day 1 – Keynote, ASP.NET 4.0, SharePoint&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
First day of TechEd started out with the Keynote speech as one would expect. I must
admit I wasn’t that enthusiastic about this particular Keynote and as it turned out
I wasn’t proved really wrong on that hunch. The Keynote was primarily held by Bill
Veghte, Microsoft Senior Vice President on Windows Business. The topics were all about
the IT-stuff going on right know with focus on the soon to come operating systems;
Windows 7 and Windows Server 2008 R2. Not that I’m not interested in those topics
at all, I just wanted to see some developer stuff too – unfortunately there was none. 
&lt;/p&gt;
&lt;p&gt;
The first actual session I attended was about ASP.NET 4.0 and what’s coming in that
release. It was a pretty good one. Jeff King showed some examples of how you are now
able to have more fine-grained control over the markup rendered by the ASP.NET WebForms
Framework, some better support for SEO-stuff including new properties on the System.Web.Page
class for meta-keywords and –description and generally some new controls to do LINQ-based
operations (e.g. Filtering and Sorting) on your LINQ-enabled backend datasource. 
&lt;/p&gt;
&lt;p&gt;
The last two sessions I attended that day were both about SharePoint development.
The first was focusing on tooling for SharePoint development, especially with focus
on using the tool VSeWSS 1.3 (Visual Studio extensions for Windows SharePoint Services).
The last session was about how to develop Windows Workflow Foundations to use inside
WSS/MOSS applications. This session was held by Ted Pattison, SharePoint MVP and book-writer,
and now from my experience a really good presenter. I didn’t get much out of the course
technically-wise though since we’ve already been doing a lot of the stuff that he
presented. 
&lt;/p&gt;
&lt;p&gt;
Next up after first-day sessions was the Partner Expo Reception event which I attended.
It can best be described as a circus where all the audience gets magically drawn by
all the stuff and weird contests offered by the different vendors. But they had food
and &lt;u&gt;beer&lt;/u&gt;, and I got a few good talks with some of the different vendors – including
a nice demo by a Red Gate Software guy on the soon-to-be-released new version of ANTS
Memory Profiler. And yeah of course I got a lot of swag too :-)
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Day 2 – More SharePoint, C#, Commerce Server 2009, Parallels, Web Deployment&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The second day started out with a morning session by Todd Bleeker on SharePoint Web
Part Development Best Practices. Todd had a lot of energy on the stage and that was
just really awesome! Even though the session was about Best Practices over half of
the audience was rather new to Web Part development which had the impact of Todd having
to explain a lot more of the basics taking time from the really interesting stuff.
Pretty unfortunate also was that time completely ran out for Todd so he didn’t come
around all of his points. All in all I think it was a great session mostly because
of Todd’s enthusiasm. And I did get some good advices to take me back home.
&lt;/p&gt;
&lt;p&gt;
I also attended Anders Hejlsberg’s session on “Future of C#”, which I enjoyed a lot
– mostly because I think he rocks. To be more specific and professional about it I
believe that the future “Compiler As A Service”-feature can really leverage some interesting
possibilities to the table, e.g. for an easy way stick-in additional behavior to your
code (logging, validation, pre-/post conditions, etc.) to allow cross-cutting concerns
to be addressed as secondary concerns.
&lt;/p&gt;
&lt;p&gt;
After having a brief chat with one of the guys at the Commerce Server booth he had
me convinced that I should go to their interactive session on Commerce Server 2009
Foundation Services. So I did (later to discover that I thereby missed a Scott Hanselmann
session!). Although they had a whole lot of technical problems at this session, I
got a pretty good understanding of the upcoming Commerce Server 2009 R2 version including
the support of having Commerce Server configured as a true 3-tier environment with
Commerce Server as an application server in the middle of this. I’m soon to begin
on a new Commerce Server 2009 project which I look really forward to, but seeing that
new Foundation API kind of shocks me a little – to me it is extremely verbose compared
to the CS 2007 API, and the amount of XML configuration doesn’t seem to have become
any less I’m afraid. Perhaps wrapping the new very generic API in a nice fluent and
slightly more specific API might just do the trick for me. We’ll see about that.
&lt;/p&gt;
&lt;p&gt;
Next in line was a interesting session on Parallel Computing APIs with .NET 4.0. It
gave me a good overview and examples of the possibilities with parallelism that you
can get using the new framework that will be baked into .NET 4.0.
&lt;/p&gt;
&lt;p&gt;
Last but not least this I attended a session on Web Application Deployment Packaging
and Migration – a look into some new possibilities in IIS about importing and exporting
applications and on how to package your solution to allow smooth GUI-enabled installation
on IIS. At the session, Faith Allington showed the new Web Platform Installer from
Microsoft which I personally think is a awesome tool. Both BlogEngine.NET and Umbraco
got some visual attention at this session being on the list of web-applications available
on the Web Platform Installer. Faith did really well on this presentation clearly
having a lot of knowledge of what she was talking about.
&lt;/p&gt;
&lt;p&gt;
All in all a great day with good sessions by excellent speakers.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=164f993f-6e1b-4b39-8e91-def5508a5232" /&gt;</description>
      <comments>http://blog.brianh.dk/CommentView,guid,164f993f-6e1b-4b39-8e91-def5508a5232.aspx</comments>
      <category>TechEd</category>
    </item>
    <item>
      <trackback:ping>http://blog.brianh.dk/Trackback.aspx?guid=a976771f-747f-4a65-b9ce-b69d99e0896c</trackback:ping>
      <pingback:server>http://blog.brianh.dk/pingback.aspx</pingback:server>
      <pingback:target>http://blog.brianh.dk/PermaLink,guid,a976771f-747f-4a65-b9ce-b69d99e0896c.aspx</pingback:target>
      <dc:creator>Brian Holmgård Kristensen</dc:creator>
      <wfw:comment>http://blog.brianh.dk/CommentView,guid,a976771f-747f-4a65-b9ce-b69d99e0896c.aspx</wfw:comment>
      <wfw:commentRss>http://blog.brianh.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=a976771f-747f-4a65-b9ce-b69d99e0896c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Jeg fik desværre ikke chancen for at arbejde videre med Umbraco sidst på ugen, forrige
uge, pga. F#-arrangement i vores .NET brugergruppe i Århus, samt egen forberedelse
til en præsentation og demo af et lille samspil mellem SharePoint 2007, InfoPath Forms
og Windows Workflow Foundation.
</p>
        <p>
Derudover kan jeg nævne at jeg i går var til TechTalk hos Microsoft med Anders Hejlsberg,
chefarkitekt hos Microsoft på bl.a. C#, samt Steve Ballmer, CEO hos Microsoft. Det
var hele køreturen fra Århus til Vedbæk værd, selvom arrangementet kun varede et par
timer. 
</p>
        <p>
Tilbage til Umbraco. Som nævnt i min <a href="http://blog.brianh.dk/2008/09/23/InstallationAfUmbracoStep1.aspx">forrige
post</a>, ramte jeg en lille "mur" i forbindelse med installationen, da jeg ikke havde
konfigureret File Permissions for mit Umbraco-website. Jeg Googlede mig vej til en
post, som beskriver de foldere og filer som kræver opsætning. Desværre var det ikke
helt nok for mig. Jeg måtte sætte Full Control på hele Umbraco-mappen for at få Umbraco
til at "æde den". Jeg skal nok vende tilbage med en mere "sikker" løsning, når jeg
får tid til at smide lidt tid efter det. Da det her installeres lokalt uden mulighed
for at tilgå sitet udefra, kan jeg godt leve med risikoen.
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/file-permission-error_2.gif">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="file-permission-error" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/file-permission-error_thumb.gif" width="244" border="0" />
          </a>
        </p>
        <p>
Som det kan ses havde jeg problemer med ACL på mit Umbraco-website. En hurtig quick-fix
var at sætte "Full Control" på hele mappen til kontoen "Network Service", som er den
konto som afvikler websitet i IIS'en. Dette anbefales ikke til enhver form for produktionsmiljø.
</p>
        <p>
Videre i installationen kom jeg, men allerede ved næste step kaster Umbraco en Exception
i hovedet på mig. Se nedenstående skærmbilleder.
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/db-installation_2.gif">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="db-installation" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/db-installation_thumb.gif" width="244" border="0" />
          </a>
        </p>
        <p>
Ved klik på "Install", kaster Umbraco følgende Exception:
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/exception-db-install_2.gif">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="exception-db-install" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/exception-db-install_thumb.gif" width="244" border="0" />
          </a>
        </p>
        <p>
Kedeligt. Hvad kan man gøre ved det? Jeg vælger at kigge lidt på den kode som smider
den Exception, med anvendelse af mit yndlingstool til decompilering af .NET kode: <a href="http://www.aisto.com">Lutz
Roeders</a><a href="http://www.red-gate.com/products/reflector/index.htm">Reflector</a>.
Reflector er i øvrigt nu overtaget af softwarehuset <a href="http://www.red-gate.com/">Red
Gate</a>, som har en væld af yderst interessante tools til .NET og SQL i deres produktportefølje,
herunder <a href="http://www.red-gate.com/products/ants_profiler/index.htm">Ants Profiler</a> og <a href="http://www.red-gate.com/products/SQL_Compare/index.htm">SQL
Compare</a>. Et hurtigt kig i koden hjælper imidlertid ingenting - så jeg må overveje
andre alternativer. Èt af dem er at prøve igen. Jeg klikker på "Tilbage"-knappen i
browseren, og klikker på Install-knappen endnu en gang. Det hjalp :-)
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/yay-db-install-went-well_2.gif">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="yay-db-install-went-well" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/yay-db-install-went-well_thumb.gif" width="244" border="0" />
          </a>
        </p>
        <p>
Videre i installationen - lækkert. Umbraco tjekker opsætningen af mine filrettigheder,
og fortæller mig at det er perfekt sat op, hvilket også er fair nok, på trods af at
jeg har sat Full Control på hele mappen. Så helt perfekt er det ikke - men det må
jeg kigge på senere.
</p>
        <p>
Igen fortsætter installationen, og nu står jeg på step 5/5 - hvor jeg skal vælge om
jeg vil installere <strong>Boost</strong>. Boost er et nyt begreb i Umbraco 4, og
er i følge screencastet af Niels Hartvig, et helt skrabet web-site som overholder
en række Umbraco-konventioner (som jeg stadig ikke kender), og som lukker op for en
anden feature: <strong>Nitros</strong>. Igen kan jeg kun trygt læne mig op af Niels
Hartvigs definition af Nitros, som dækker over en afgrænset specifik funktionalitet,
som f.eks. TopNavigation, standard SiteMap. Jeg har erfaring med WSS/MOSS (SharePoint)
udvikling, og umiddelbart minder det rigtig meget om det vi her kender som "<a href="http://sharepoint.microsoft.com/blogs/mike/Lists/Posts/Post.aspx?ID=7">Features</a>".
Det lyder meget lovende - og mon ikke jeg burde prøve at lave min egen lille Nitro
i forbindelse med det her projekt. Jeg følger Niels' guidelines, og installerer Boost
med de Nitros som installationen finder.
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/install-boost_2.gif">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="install-boost" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/install-boost_thumb.gif" width="244" border="0" />
          </a>
        </p>
        <p>
Et klik på "Install Boost"-knappen bekræfter at jeg har brugt for meget tid på at
skrive den her post (og i øvrigt lave en masse andet), end at rent faktisk gennemføre
selve installationen af Umbraco, for jeg får straks smidt følgende Exception i hovedet:
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/user-time-out_2.gif">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="user-time-out" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/user-time-out_thumb.gif" width="244" border="0" />
          </a>
        </p>
        <p>
Min bruger har simpelthen fået et timeout af Umbraco/ASP.NET. Helt forståeligt. Løsningen
var ret simpel; jeg besøgte "http://localhost/umbraco" som er adressen til selve administrationsdelen
af Umbraco. Her loggede jeg ind med den bruger som blev oprettet i forbindelse med
installationen. 
</p>
        <p>
Tilbage til installationen, og et klik på "Install Boost", får mig videre til næste
side (se nedenstående skærmbillede), hvor jeg kan vælge de Nitros som skal installeres
med sitet. Jeg vælger at installere dem alle. 
</p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/nitros-installation_2.gif">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="nitros-installation" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/nitros-installation_thumb.gif" width="244" border="0" />
          </a>
        </p>
        <p>
          <a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/done-installation_2.gif">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="done-installation" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/done-installation_thumb.gif" width="244" border="0" />
          </a>
        </p>
        <p>
Hermed er Umbraco 4 installeret på Windows Server 2008 med SQL Server 2008. I Rock!
</p>
        <img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=a976771f-747f-4a65-b9ce-b69d99e0896c" />
      </body>
      <title>Installation af Umbraco - step 2</title>
      <guid isPermaLink="false">http://blog.brianh.dk/PermaLink,guid,a976771f-747f-4a65-b9ce-b69d99e0896c.aspx</guid>
      <link>http://blog.brianh.dk/2008/09/29/InstallationAfUmbracoStep2.aspx</link>
      <pubDate>Mon, 29 Sep 2008 17:37:57 GMT</pubDate>
      <description>&lt;p&gt;
Jeg fik desværre ikke chancen for at arbejde videre med Umbraco sidst på ugen, forrige
uge, pga. F#-arrangement i vores .NET brugergruppe i Århus, samt egen forberedelse
til en præsentation og demo af et lille samspil mellem SharePoint 2007, InfoPath Forms
og Windows Workflow Foundation.
&lt;/p&gt;
&lt;p&gt;
Derudover kan jeg nævne at jeg i går var til TechTalk hos Microsoft med Anders Hejlsberg,
chefarkitekt hos Microsoft på bl.a. C#, samt Steve Ballmer, CEO hos Microsoft. Det
var hele køreturen fra Århus til Vedbæk værd, selvom arrangementet kun varede et par
timer. 
&lt;/p&gt;
&lt;p&gt;
Tilbage til Umbraco. Som nævnt i min &lt;a href="http://blog.brianh.dk/2008/09/23/InstallationAfUmbracoStep1.aspx"&gt;forrige
post&lt;/a&gt;, ramte jeg en lille "mur" i forbindelse med installationen, da jeg ikke havde
konfigureret File Permissions for mit Umbraco-website. Jeg Googlede mig vej til en
post, som beskriver de foldere og filer som kræver opsætning. Desværre var det ikke
helt nok for mig. Jeg måtte sætte Full Control på hele Umbraco-mappen for at få Umbraco
til at "æde den". Jeg skal nok vende tilbage med en mere "sikker" løsning, når jeg
får tid til at smide lidt tid efter det. Da det her installeres lokalt uden mulighed
for at tilgå sitet udefra, kan jeg godt leve med risikoen.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/file-permission-error_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="file-permission-error" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/file-permission-error_thumb.gif" width="244" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Som det kan ses havde jeg problemer med ACL på mit Umbraco-website. En hurtig quick-fix
var at sætte "Full Control" på hele mappen til kontoen "Network Service", som er den
konto som afvikler websitet i IIS'en. Dette anbefales ikke til enhver form for produktionsmiljø.
&lt;/p&gt;
&lt;p&gt;
Videre i installationen kom jeg, men allerede ved næste step kaster Umbraco en Exception
i hovedet på mig. Se nedenstående skærmbilleder.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/db-installation_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="db-installation" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/db-installation_thumb.gif" width="244" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Ved klik på "Install", kaster Umbraco følgende Exception:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/exception-db-install_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="exception-db-install" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/exception-db-install_thumb.gif" width="244" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Kedeligt. Hvad kan man gøre ved det? Jeg vælger at kigge lidt på den kode som smider
den Exception, med anvendelse af mit yndlingstool til decompilering af .NET kode: &lt;a href="http://www.aisto.com"&gt;Lutz
Roeders&lt;/a&gt; &lt;a href="http://www.red-gate.com/products/reflector/index.htm"&gt;Reflector&lt;/a&gt;.
Reflector er i øvrigt nu overtaget af softwarehuset &lt;a href="http://www.red-gate.com/"&gt;Red
Gate&lt;/a&gt;, som har en væld af yderst interessante tools til .NET og SQL i deres produktportefølje,
herunder &lt;a href="http://www.red-gate.com/products/ants_profiler/index.htm"&gt;Ants Profiler&lt;/a&gt; og &lt;a href="http://www.red-gate.com/products/SQL_Compare/index.htm"&gt;SQL
Compare&lt;/a&gt;. Et hurtigt kig i koden hjælper imidlertid ingenting - så jeg må overveje
andre alternativer. Èt af dem er at prøve igen. Jeg klikker på "Tilbage"-knappen i
browseren, og klikker på Install-knappen endnu en gang. Det hjalp :-)
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/yay-db-install-went-well_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="yay-db-install-went-well" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/yay-db-install-went-well_thumb.gif" width="244" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Videre i installationen - lækkert. Umbraco tjekker opsætningen af mine filrettigheder,
og fortæller mig at det er perfekt sat op, hvilket også er fair nok, på trods af at
jeg har sat Full Control på hele mappen. Så helt perfekt er det ikke - men det må
jeg kigge på senere.
&lt;/p&gt;
&lt;p&gt;
Igen fortsætter installationen, og nu står jeg på step 5/5 - hvor jeg skal vælge om
jeg vil installere &lt;strong&gt;Boost&lt;/strong&gt;. Boost er et nyt begreb i Umbraco 4, og
er i følge screencastet af Niels Hartvig, et helt skrabet web-site som overholder
en række Umbraco-konventioner (som jeg stadig ikke kender), og som lukker op for en
anden feature: &lt;strong&gt;Nitros&lt;/strong&gt;. Igen kan jeg kun trygt læne mig op af Niels
Hartvigs definition af Nitros, som dækker over en afgrænset specifik funktionalitet,
som f.eks. TopNavigation, standard SiteMap. Jeg har erfaring med WSS/MOSS (SharePoint)
udvikling, og umiddelbart minder det rigtig meget om det vi her kender som "&lt;a href="http://sharepoint.microsoft.com/blogs/mike/Lists/Posts/Post.aspx?ID=7"&gt;Features&lt;/a&gt;".
Det lyder meget lovende - og mon ikke jeg burde prøve at lave min egen lille Nitro
i forbindelse med det her projekt. Jeg følger Niels' guidelines, og installerer Boost
med de Nitros som installationen finder.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/install-boost_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="install-boost" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/install-boost_thumb.gif" width="244" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Et klik på "Install Boost"-knappen bekræfter at jeg har brugt for meget tid på at
skrive den her post (og i øvrigt lave en masse andet), end at rent faktisk gennemføre
selve installationen af Umbraco, for jeg får straks smidt følgende Exception i hovedet:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/user-time-out_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="user-time-out" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/user-time-out_thumb.gif" width="244" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Min bruger har simpelthen fået et timeout af Umbraco/ASP.NET. Helt forståeligt. Løsningen
var ret simpel; jeg besøgte "http://localhost/umbraco" som er adressen til selve administrationsdelen
af Umbraco. Her loggede jeg ind med den bruger som blev oprettet i forbindelse med
installationen. 
&lt;/p&gt;
&lt;p&gt;
Tilbage til installationen, og et klik på "Install Boost", får mig videre til næste
side (se nedenstående skærmbillede), hvor jeg kan vælge de Nitros som skal installeres
med sitet. Jeg vælger at installere dem alle. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/nitros-installation_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="nitros-installation" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/nitros-installation_thumb.gif" width="244" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/done-installation_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="177" alt="done-installation" src="http://blog.brianh.dk/content/binary/WindowsLiveWriter/InstallationafUmbracostep2_1303D/done-installation_thumb.gif" width="244" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Hermed er Umbraco 4 installeret på Windows Server 2008 med SQL Server 2008. I Rock!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.brianh.dk/aggbug.ashx?id=a976771f-747f-4a65-b9ce-b69d99e0896c" /&gt;</description>
      <comments>http://blog.brianh.dk/CommentView,guid,a976771f-747f-4a65-b9ce-b69d99e0896c.aspx</comments>
      <category>ActiveDeveloper</category>
      <category>Umbraco</category>
    </item>
  </channel>
</rss>