If you are creating your own pipeline components and your site is international and you need more than the four languages that is out of the box German, French, Japanese and US English for Commerce Server then you need to create your own resource for other languages. How to create a new resource is what this post is all about.

What is Messagemanager?

Messagemanager is an object that handling the localization of messages inside your pipeline competents. When you unpack the CSharpSite you will get CommerceMessageManager.dll and four folders representing a language mentioned above.

What are these messages that Messagemanager use? The table below has the messages that Commerce Server uses internally. If you introducing a new language then you need to localize this table.

Message Key Message Value
pur_discount_changed One or more discounts have changed.
pur_badhandling Unable to complete order: cannot compute handling cost.
pur_badsku Please note that one or more items were removed from your order because the product is no longer sold.
pur_badtax Unable to complete order: cannot compute tax.
pur_badplacedprice Please note that prices of products in your order have been updated.
pur_badcc The credit-card number you provided is not valid. Please verify your payment information or use a different card.
pur_badshipping Unable to complete order: cannot compute shipping cost.
unknown_shipping_method The selected shipping method is not currently available.  Please choose another shipping method.
pur_badpayment There was a problem authorizing your credit. Please verify your payment information or use a different card.
pur_out_of_stock At least one item is out of stock.
pur_noitems An order must have at least one item.
pur_badverify Changes to the data require your review. Please review and re-submit.
pur_discount_removed One or more discounts no longer apply.
L_Language_DisplayName English (en-US)

OK I have localized the messages now what?

You need to take the localized messages and create an assembly. There are many methods the following help file link should help. Once you create an assembly then you need to add it into your bin folder, take care to create the language folder then add the assembly there.

Can I add my own messages?

Yes, but the help files do note that the messagemanager is obsolete (I wonder why then Commerce Server uses it? If you find the answer let me know :))?

How to use Messagemanager inside of Pipeline Components?

If you have created your own messages and want to use it inside your custom pipeline components the following code will accomplish that.

// using message manager inside pipeline component
IMessageManager messageManager = null;
IDictionary dict = (IDictionary) pContext;
messageManager = (IMessageManager) dic["MessageManager"];
object message = messageManager.GetMessage("your string key", language);

In order for the pipeline to use the specific language you must execute the Pipeline by passing the language code in the PipelineInfo object. If the language parameter is not specified, or is NULL, the message is returned for the message set identified by the DefaultLanguage property of the MessageManager object. This value is retrieved from the web.config under the messageManager element.

Are we there yet?

Once you have done all the above you will need to add the language in the web.config of your site. Why do I need to do this? We need to tell Commerce Server's Pipeline processor that we have a new language so when Commerce Server pipelines encounter an error they retrieve the message correctly.

        <messageManager>
            <cultures default="en-US" baseName="CommerceMessageManager" assembly="CommerceMessageManager">
                 <culture id="en-US"/>
                <culture id="fr-fr"/>
                <culture id="ja-JP"/>
                <culture id="de-DE"/>
                <culture id="your new language"/>
            </cultures>
            <resources>
                <resource id="pur_badsku"/>
                <resource id="pur_badplacedprice"/>
                <resource id="pur_discount_changed"/>
                <resource id="pur_discount_removed"/>
                <resource id="pur_noitems"/>
                <resource id="pur_badshipping"/>
                <resource id="pur_badhandling"/>
                <resource id="pur_badtax"/>
                <resource id="pur_badcc"/>
                <resource id="pur_badpayment"/>
                <resource id="pur_badverify"/>
                <resource id="pur_out_of_stock"/>
                <resource id="unknown_shipping_method"/>
            </resources>
        </messageManager>

Will my custom component also work automagically? No, see the code above about messagemanager and notice that we are passing the language and since you set this value in the PipelineInfo object it will be accessible through the pipeline via the context (pdispContext) parameter.

OK, I think we are done now.