Congratulations Micki Tubbs & Michelle Tomallo of Fit Technologies

I wanted to take an opportunity to congratulate the owners of the company I work for on receiving the Ernst & Young Entrepreneur of the Year award for technology in the Northeast Ohio region last night.  I was fortunate enough to take part in the event and must say that it was a great experience made even better by a victory by our company (Fittechnologies / SchoolOne).

Working with Multi-value fields in Commerce Server 2007 Profile System

One of the challenges I have run into working with Commerce Server is utilizing the multi-value key fields in the profile system.  I am finding that they are a bit clunky.  It would be nice if the Commerce Server team would implement some additional functionality to make simple procedures like adding an address to a user profile easier.  Using the UserObject profile as an example, the way it currently works is that if you add an Address profile and want to link it to a specific user, you need to add the AddressID (a GUID) to the address_list property in the UserObject profile.  This is stored in the database as a string field and just delimits the GUIDs with a semi-colon.  When you retrieve the address_list property from the profile system, it returns you an object array of the GUIDs.  You can then just manipulate the array to add a new value or iterate through it to retrieve the appropriate address profiles.  The problem is that I found very little documentation regarding the use of these fields.  I have included the method I am using below to add a new address to the User profile.  I’m sure there are better ways to do this and if anyone can point me in the right direction I would be thrilled.

 

public static void InsertIntoUserAddressList(AddressInfo newAddress, string userEmail)
        {
            Profile user = CommerceContext.Current.ProfileSystem.GetProfile("GeneralInfo.email_address", userEmail, "UserObject");
            ArrayList addresses = new ArrayList();
            if (user.Properties["GeneralInfo.address_list"].Value != null)
            {
                object[] addr = (object[])user.Properties["GeneralInfo.address_list"].Value;
                foreach(object objAddress in addr)
                {
                    addresses.Add(objAddress);
                }
            }
            addresses.Add(newAddress.AddressID.ToString());
            user.Properties["GeneralInfo.address_list"].Value = addresses.ToArray();
            user.Update();
        }

Commerce Server 2007 & IIS 6.0 SelfSSL

When trying to run the Commerce Server Customer & Orders Manager, I was receiving an error stating that the orders webservice was unavailable.  I looked at the connection settings for the orders webservice and realized that it was calling the webservice using https.  For the purpose of testing on my development machine, I simply tried to change the url to use http instead.  I then another error and found that you are required to use https for the webservice.  I then downloaded the IIS 6.0 Resource Kit Tools (download here).  You can use the SelfSSL 1.0 utility to generate a self-signed certificate to enable ssl for testing purposes.  It’s a command line tool that takes a few parameters and automatically installs the generated cert for you.

Additionally, I had to disable anonymous access in IIS for the webservices and now everything works correctly.

Commerce Server Catalog Web Service Permission Error

As promised I am going to begin blogging on my experiences with Commerce Server 2007.  I started yesterday by getting the environment setup.  I didn’t run through the step-by-step guides I just followed the prompts and a little advice from one of my co-workers who has been playing with CS for about a month now.  Everything seemed to go as planned.  I walked through the configuration wizard, unpacked the CSharpSite and compiled all the projects which got everything going.  The part I missed from doing it this way was configuring security correctly.  One thing I’ve noticed is that CS seems to be locked down very heavily out of the box.

I installed and launched the CS Catalog Manager.  It would not connect and just gave me a generic error prompt that the webservice was not available.  I poked around in IIS for a minute only to find that everything seemed to be good.  I then tried to navigate to the webservice with IE which worked fine.  I thought it was interesting that I could get there with IE but not the Catalog Manager.  So I tried to invoke one of the methods in IE and I finally found the problem.  I got the following error:

System.Web.Services.Protocols.SoapExceptions:  The Catalog Web service does not have write access to the authorizationPolicyPath.  Verify that the file exists and that it has the appropriate permissions. 

I looked around for a solution and what I finally found by piecing together different sources was that essentially I needed to assign write permissions on CatalogAuthorizationStore.xml to the account running the AppPool in which it resides. 

To do this you need to identify the account running your AppPool by going to IIS open up Application Pools and find the AppPool the CatalogWebService is running in.  You then can right click on that AppPool and select Properities.  Go to the Identity tab on the properties dialog and there you can see which account you are using.  Once you have this information, then you can navigate to the CatalogAuthorizationStore.xml file which is in the same directory as CatalogWebService.asmx.  In my case, it is set up at C:\Inetpub\wwwroot\CatalogWebService.  You then right click on the xml file and select Properties >> Security.  Here you add the account and be sure that it has write permissions.  Once I completed this, I tried again to launch the Catalog Manager.  This time it worked, or at least it seemed to.  It was now able to load and talk to the webservice, but the task pane was empty.  I couldn’t actually do anything with catalogs. 

I did some more searching to try to resolve this issue and found that although I could now access the CatalogAuthoriztionStore, I had no accounts configured within it.  So now I have to add my user account.  To accomplish this you do the following:

Open the Authorization Manager (Start > Run > Azman.msc)
Right Click the Authorization Manager node
Click on Open Authorization Store
Browse to the CatalogAuthorizationStore.xml file where we found it earlier
Open the CatalogAuthorizationStore Node
Open the CatalogandInventorySystem Node
Open Role Assignments
Right Click on the roles you wish to manage and choose "Assign Windows Users or Groups"
You can then use the dialog to select your user account or other appropriate users and groups

Once again I tried to launch the Catalog Manager and this time was able to manage catalogs as expected.

Adventures in Commerce Server

Well, I’m no Wade Wegner, but I am going to get my shot at developing in Commerce Server and I intend to share my experiences here.  I’m sure Wade will have ample opportunities to laugh at my foolish mistakes and offer a better approach, but I figure that is the way that I’m going to learn and hopefully provide all of you some useful information along the way.  So Wade, I know you are looking to put all that knowledge you’ve compiled for your book to good use, are you up to the challenge of guiding a Commerce Server novice through some of the pitfalls?

How to drive a client away in one easy step!

Step 1 - Make Assumptions

Result - No more pesky client! 

For those of you who have known me for a while or have followed my blog for any length of time, you should know that I am rather adamant about customer service.  I believe that it is the one aspect of our industry that is in desperate need of serious attention.  There is one skill that all of us who ever have to deal with clients (or managers, or peers, or direct reports, or spouses, or friends, or - well you get the idea) need to master.  It’s the art of listening.  let me give you an example of how important it can be. 

I was recently involved in helping a friend try to win a project for his struggling consulting business.  He was one of two finalists for the contract and was asked to come in and present his solution for their application.  The problem was that the RFP for the work was very vague.  It gave a general idea of what the client was looking for but left out some critical pieces of information he needed to give a good presentation on the matter.  Having lived the life of an independent contractor, he asked me if I had any advice for him.  I told him the best presentation that he could give them was one that he didn’t prepare.  As it turns out, I was right.  My friend was up against a big company for the work and believed he had no chance of winning it, so, even though he thought I was crazy, he took my advice and went in without a prepared presentation but rather armed with a few simple questions about their business need and processes.  This started a dialog and allowed them to see his problem solving skills in action.  The other company took the RFP, made a list of assumptions and went in pitching a solution that in the end completely missed the mark of what the client was looking for.  End result, my friend has a new contract that should keep him busy for the next year or two.

Chalk another one up to good customer service!

Link to a Document Content Type SharePoint 2007

One of the questions that often comes up with Sharepoint regarding document libraries is "how do I link to a document stored in one library in others?"  Unfortunately, there was no way to do this prior to the 2007 version without actually duplicating the document and uploading it into each library independent of each other.  This obviously has ramifications by creating separate versions which will soon be out of sync.  Changes made to one document won't be represented in the others.

To resolve this, SharePoint introduced a feature known as the Lint to a Document Content Type.  If you aren't yet familiar with the concept of Content Types in SharePoint, you need to research this.  I will attempt to post more on this subject later, but for now just understand that it is a way of defining the contents of a library beyond the document type that it was created as (.doc, .xls, etc...).  The Link to a Document content type is a predefined type that creates a record in the library that will point you to another library.  In order to use this feature you must first enable the use of content types within your library.  To do this, you go to the settings tab of your document library and click the Advanced Settings link.  Select Yes for Allow management of content types and click OK.

LinkToDocument1 

Now that you have enabled the ability to use content types, you must associate the content types you wish to use within this library.  Back on the Document Library Settings page, you will now see a list of content types that are currently associated.  By default Document will be enabled.  Click the Add from existing site content types.

LinktoDocument2

Choose the Link to a Document selection from the List Box and click Add >.  Once you've done this you will now be able to go to your document library and click the new button and you will now see Link to a Document in the menu.  Click this to provide a name and url for the document.

LinkToDocument3

Although this may seem like a small thing, it gives us the ability to maintain a single copy of a document with all the features like versioning, workflows, and approvals that we chose SharePoint for in the first place while still allowing us to gain access to it in multiple places throughout the application.

Target your Audience with MOSS 2007

As I'm delving into the world of MOSS 2007 I'm finding lots of cool features and well thought out ideas that Microsoft has brought to the table.  One such feature is known as the Audience.  The audience provides a more dynamic way to target specific content to users for which it is appropriate.  An audience is created by specifying rules from the data contained in the user profile data store.  Because an audience is closely related to user profiles the administration interface to control them is found in the Shared Services Administration site.

To create a new audience, you start by specifying a name, description and an owner.  You then select whether you want the audience to be composed of people that satisfy all of the rules, or any of them.

audience1

On the next screen we begin adding rules to the audience.  We will create a collection of rules that will be evaluated to compile the membership in this audience.  In the following screen capture, you can see that I have selected to base my rule on a Property. 

 Audience2

Selecting property allows me to target any of the fields specified in a users profile to validate that my rule has been satisfied.  In this case I'm looking for anyone who listed SharePoint as one of their skills in their user profile.  This rule on it's own would not limit the scope of my audience significantly enough though.  I want this audience to target SharePoint developers and at this point I'm pulling in everyone that lists sharepoint in their skills profile.  This could include administrators, designers, or general business users as well.  So how do I narrow the scope?  By specifying more rules.  So now I go back and add an additional rule to the collection.

Audience3

We will repeat the steps we did earlier in adding our first rule but I will choose User this time.  When I select User, the drop down for Operator has two options.  First up is "Reports Under".  This allows us to specify a user in the value field that all users must be below in the organizational hierarchy.  This feature is dependant on a well populated Active Directory though.  The second option is  "Member Of".  This allows us to provide a security group or distribution list in our value field.  So for my example I would select Member Of and choose my Software Developers security group. 

Once I have specified all the rules I wish to list for this audience, I can then compile it.  Compiling it sets SharePoint loose to go analyze the users in my system and comparing them against the rules that I have specified to determine membership in this audience.  Changes in our user base would necessitate re-compilation of the audience, so you can set a timer job to re-compile on a schedule.

Now that I have built my audience, I can use it to filter visibility to specific content within my site.  For the sake of this example lets assume that I have added a SharePoint Developers Announcements List to my site.  I then drop the list on the homepage.  I go to edit mode on the web part and expand the Advanced section in the tool panel. I then scroll down to the bottom and click the browse button next to the field for Target Audiences.  I then get the following dialog that allows me to select my newly created audience.

 Audience4

After selecting my Audience with the dialog, and applying it to my web part, I then can add announcements that will only show up for users who meet the specified criteria.  This is a really slick way to target content specific to users.  The nice thing is that it eliminates the need to create additional security groups that need managed for this type of customization and can mine the information provided by users themselves about their profiles (if you are using this feature). 

Where I think Microsoft went wrong with this feature is that the creation of audiences can only be done in the Shared Services Provider site.  This means that Tier 1 administrators (those with rights to Central Admin and Shared Services Provider) are the only ones who can create them.  It would have been nice to allow site owners to create and manage their own audiences.  I believe this will be an under-utilized feature for this reason, but that said I think it's one that deserves a look.

Welcome Edward Buatois to TheRuntime

It is with great pleasure that I get the honor of welcoming Edward Buatois to TheRuntime.com as one of our newest bloggers.  As many of you may know, I am a Software Development Manager in Cleveland, Ohio and am fortunate to have Edward on my team.  He is one of my Senior Developers and certainly deserves accolades for the work he does here.  Edward has been blogging for a while now on DevAuthority.com and we felt it was time to extend him an invitation to join us here.  Edward has a passion for .net development and architecture.  It has been fun working with him and blogging with him on DevAuthority, so look forward seeing what he will bring to the discussion here in the future.  Please join me in welcoming him to the community!

Best Practices?

Jay Kimble has posted a very thoughtful article that you should read before you continue [Find It Here].  I have been thinking about some of these same things myself lately and particularly echo the sediments of his "fanboy" point. 

If there is one thing that I've learned in life, let alone in my career as a developer, it would be that there is no one solution to every problem.  There is no silver bullet to take care of every possible scenario.  Unfortunately, "Best Practices" are often packaged and presented in this fashion by zealous fanboys.  Saying that you should use some specific pattern to build every website or application you are given is ludicrous to me.  Developers who adopt a mentality like this deny the nature of what it is we do.  At the core of our profession, we are analysts.  Our job is to take a problem and find the best solution.  Sometimes that problem lends itself well to some specific pattern or methodology, other times it may not.  We need to consider things like budget, timelines, integrations with other systems, and hardware requirements (just to name a few).

So what about Best Practices?  Are they useful?  Are they important?  Certainly!  I contend that we need to use the best solution we can find for any given problem.  People will gravitate to patterns that they prefer and as is natural they will often become advocates of such.  What we need to guard against is becoming close minded.  We need to understand WHY a certain pattern is our best solution.  If I can't tell you why I chose the solution I did, as well as why some of the others didn't make the cut, then I have to conclude that I did not do my due diligence in analyzing the problem.