Debugging Sharepoint Applications in IIS7

on Friday, December 19, 2008

We all know how to debug classic ASP.NET application using the famous "Attach to Process" tool in our favourite IDE. However, when debugging sharepoint applications, you need to attach to the w3wp.exe thread. You will notice that you may have multiple w3wp.exe thread showing up in your Attach to Process window.

How do you know which process to attach to. One dirty and long way to do is to set a breakpoint, and then attach each process one by one. If the breakpoint is a solid red, then you know that you got the right process. However, this is not the recommended way as there may be other reason why you may get a hollow red breakpoint icon. The symbols may not have been loaded yet, you may have missed a dll or two while GAC'ing between builds, etc.

A better way to pinpoint which w3wp.exe process to attach to, use the following dos command:

%windir%\system32\inetsrv\appcmd.exe list wp

This is what the output would look like on a console:


You can even throw this inside a batch file which gets called at the end of the a post-build event.

Note that this is only applicable for servers running IIS7. Previous IIS versions had a different tool called iisapp.vbs which is no longer available with IIS7.

Sorting Profile in Commerce Server 2007 and Mojave

At the time of this writing sorting is not supported by Mojave on the Profile entity. As a matter of fact, if you write and execute a Mojave query, the sortProperties attribute will only have any effect if you are dealing with one of the following entities:

  • Catalog
  • CatalogEntity
  • Category
  • Product
  • Variant
The CommerceSortProperty will simply be ignored for any other entities including Profile.

So how exactly do you sort one of these entities? Well, not surprisingly, you will have to do it yourself. For example, if you run a query to get the credit cards from the user profile, the returned list will be random at best. Typically, you will store this result inside a Collection object of some sort. The DefaultSite that ships with CTP4, uses a generic Collection object called Collection. Before you return this unsorted list to your caller, you can send this object to the following method which will sort it for you.

private static ICollection SortCreditCardsCollectionByDateCreated(Collection creditCardsCollection)
{
List listCreditCards = new List(creditCardsCollection);
listCreditCards.Sort(
delegate(CreditCard x, CreditCard y)
{ return DateTime.Compare(x.DateCreated, y.DateCreated); }
);
return (new Collection(listCreditCards));
}

The above method sorts the list on the DateCreated attribute. You can take it one step further and generalize this method to actually pass in the attribute on which you wish to sort, and place it in a MojaveUtilities class if you wish.

And now, you can sort profile or any other entity you wish to sort in Commerce Server 2007 using Mojave API.

Refreshing Cache from Mojave API

My last post was regarding how to refresh CS07 cache concerning the web services. It is important to note however that when you are dealing with Mojave code, such as working on the Default Site that ships with CTP4 (or upcoming CTP5), that the code does not use these web services. These web services are used by integration applications (e.g. Biztalk) or the management application MMCs (e.g. Customers and Orders Manager, Catalog Manager, etc.).

One example would be when you a user adds a credit card to his profile. A new credit card entry is created which includes all the information e.g. credit card number, expiry date, etc. However, it does not include the DateCreated i.e. the time stamp at which the user created the credit card entry on the site. This attribute is filled in on the Commerce Server/Sql Server side. Therefore your local cached copy of the newly created credit card will not have DateCreated attribute in the cache. Why is this a problem? Well, if you want to sort the credit cards by DateCreated attribute, this is a problem. You will not be able to do a meaningful sort until and unless the CS07 cache refreshes. An iisreset, for example, will clear the cache for you. Note that resetting the cache from the management applications or changing the settings in the Commerce Server web services' web.config will have no effect. Remember, you are making Mojave calls which are going straight to CS07 (Microsoft.CommerceServer.* libraries). The web services are simply not in the play here.

So, how do you refresh Commerce Server 2007 cache from Mojave API? There are two ways:

1. Directly Using CommerceUpdate

CommerceUpdate updateCache = new CommerceUpdate();
updateCache.SearchCriteria.Model.Name = "ProfileCache";

CommerceResponse response = OperationService.ProcessRequest(GetCurrentRequestContext(), updateCache.ToRequest());

2. When a CommerceQuery is done. If the search criteria contains the last modified date, it will be evaluated against the retrieved user profile and if different, the CS2007 cache will be refreshed.

CommerceQuery query = new CommerceQuery();
query.SearchCriteria.Model.DateModified = DateTime.UtcNow;
query.SearchCriteria.Model.Email = email;

Refreshing Cache in Commerce Server 2007

on Wednesday, December 17, 2008

Commerce Server heavily reiles on caching to keep the application flowing nice and tidy. During development, there may be cases where you want the application to go and fetch data right from the source and bypass the cache. There are a couple of things you can do:

  1. From the management applications, e.g. Commerce Server Customers and Order manager, you can click on the Profiles or Payment Methods, and then click "Refresh Site Cache" from the task pane.Commerce Server - Refresh Cache

  2. You can browse to the following URL: http://webserver:webservicesPort/OrdersWebService/SiteCacheRefresh.axd?CacheToRefresh=ProfileCache (replace ProfileCache with whichever cache you are trying to refresh).

  3. If you get an access denied error, then you need to add the owner of your application pool to the appropriate section in the web.config of the web services. Look for "SiteCacheRefresh.axd" in your web service's web.config and it will have "". In that section allow access to your application pool owner, or (for development box only) change "deny" to "allow" in the above tag giving everyone free access.
Here is a great link on How to Control the Profile Cache in Commerce Server: http://blogs.msdn.com/maxakbar/archive/2007/02/07/how-to-control-the-profile-cache.aspx

Tree-To-Flat Copy Using XCopy

on Tuesday, December 16, 2008

If you have a tree folder as follows:

%BRANCHPATH%\UserControls
%BRANCHPATH%\UserControls\ChangePassword\
%BRANCHPATH%\UserControls\MyProfile\
%BRANCHPATH%\UserControls\RegistrationWizard\


and you try to do a XCOPY as follows using the recursive option (/S), it copies entire folder structure into the target hive.

XCOPY %BRANCHPATH%\*.ascx "%HIVE%" /Y /R /S

However, if we just want to drop the files individually the above doesn’t work. The above will copy entire folders that contain the ascx files in the HIVE. This will cause problems. There is no way to do a tree-to-flat copy using any XCopy option.

One easy but cumbersome way to avoid this is to use full paths to each folder as follows:

XCOPY %BRANCHPATH%\UserControls\*.ascx "%HIVE%" /Y /R
XCOPY %BRANCHPATH%\UserControls\ChangePassword\*.ascx "%HIVE%" /Y /R
XCOPY %BRANCHPATH%\UserControls\MyProfile\*.ascx "%HIVE%" /Y /R
XCOPY %BRANCHPATH%\UserControls\RegistrationWizard\*.ascx "%HIVE%" /Y /R


The above will work, but you will have to specify each folder, and there may be a folder you end up missing. However, the following snippet is generic enough in that it will first create a list of all the folders and subfolders, create a temporary list of folders in a text file, go through each folder, grab the .ascx files in each folder and copy it to the HIVE. At the end delete the temporary text file:

dir %BRANCHPATH%\UserControls /A:D /B /S > tempListOfDirs.txt
For /F %%A IN (tempListOfDirs.txt) Do (
If Exist %%A* (
XCOPY %%A\*.ascx "%HIVE%" /Y /R
)
)
del tempListOfDirs.txt

Automatic TFS Sign-in on Microsoft Server 2008

on Monday, December 15, 2008

Do the following so VS doesn’t bother you each time for logging in when you fire it up. Note that if you want to log on using another ID, you will have to go back here and remove the cached password from the entry. These are instructions for Microsoft Server 2008.

Control Panel > User Accounts > Manage Your Network Passwords

Click Add

Enter information as below with your username and password. Note that you won’t have the options grayed out – mine are grayed out because I am trying to edit an existing property. You will be able to type in the log on box (enter your tfs server name e.g. tfs.companyname.com) and choose the radio button.

Welcome to Commerce Server Guy

on Tuesday, December 9, 2008

I am a Microsoft Commerce Server newbie. I will be working with the latest MS offering codenamed Mojave at my current place of employment. As I get more familiar with this product, the purpose of this blog is to share any development experiences and other teething pains to hopefully help someone else out there get up to speed quickly.