Wednesday, September 30, 2009

Tech Ed 2009 - Visual Studio 2008 IDE Tips [DEV301]

I was watching Tech Ed Online - Visual Studio 2008 IDE Tips [DEV301] and thought I'd record the tips I was interested in.

Extracted from http://blogs.msdn.com/saraford/archive/2009/09/09/teched-australia-25-visual-studio-2008-ide-tips.aspx

5. You can use a reg hack for customizing search results
HKCU\Software\Microsoft\VisualStudio\9.0\Find String Find=$f$e($l,$c):$t\r\n

6. How not to accidentally copy a blank line
Tools – Options – Text Editor – All Languages – General, Uncheck Apply cut or copy to blank lines

22. You can use tracepoints to log stuff in your code
Right-click in indicator margin, select breakpoints, select Insert Tracepoint

Bidirectional data connection between Sitecore (CMS) and Salesforce (CRM)

I've been working a product called (S4S) that provides a number of ways to integrate Sitecore and Salesforce. This parallels the Sitecore (Microsoft) CRM Membership Provider but with Salesforce rather than Microsoft CRM.

One part (the Security Connector) provides custom ASP.NET Security Providers (Membership, Role and Profile) that uses the Salesforce Partner API to expose Contacts and Accounts as Users and Roles in Sitecore respectively. This is useful for companies who want to provide extranet logins in Sitecore for their Salesforce contacts. Using the standard ASP.NET providers makes the integration seemless for sitecore admins. I.e. You can use Salesforce derived users and roles within Sitecore in the same way you would use a native user and/or role. You use the same admin tools from the Sitecore Shell. The profile connection can be used to expose Salesforce Contact fields to Sitecore.

Some other goodness (the Data connector) makes bidirectional data transfer easier. At its core it is a entity based .NET wrapper around the Salesforce partner and metadata API's. This makes strongly typed CRUD (Create, Retrieve, Update, Delete) operations really simple. Internally we handles compressing the outbound and inbound API calls and caching the meta data to improve performance. There is also query building to produce dynamic SOQL. I've done some quick demos with standard ASP.NET GridViews and FormViews round tripping Salesforce data through Sitecore (remember to set typesThatShouldNotBeExpanded in the web.config first!). The is also a Generic entity service that can accommodate any Salesforce object. This is useful if the field definition is unknown or likely to change.

Finally there is the Report and Dashboard Connector that provides .NET API access to Salesforce Reports and Dashboards. With reports you can pull out the HTML or have it converted to a DataSet. By surfacing the graphs and charts from Salesforce rather than using static content keeps everything up to date with changes in the Salesforce data.

Tuesday, September 29, 2009

Sitecore CMS 6 - IndexOutOfRangeException from Sitecore.Shell.Applications.Security.UserManager

Something odd has occurred to my Sitecore 6 install. I've started getting the following exception from the Security Tools > User Manager:

Exception: System.IndexOutOfRangeException
Message: Index was outside the bounds of the array.
Source: ComponentArt.Web.UI
   at ComponentArt.Web.UI.GridItem.set_Item(Object obj, Object value)
   at Sitecore.Shell.Applications.Security.UserManager.UserManager.Users_ItemDataBound(Object sender, GridItemDataBoundEventArgs e)
   at ComponentArt.Web.UI.Grid.ItemDataBoundEventHandler.Invoke(Object sender, GridItemDataBoundEventArgs e)
   at ComponentArt.Web.UI.Grid.LoadGridItems(GridItemCollection arItems, Object[] arObjects, Int32 iLevel)
   at ComponentArt.Web.UI.Grid.DataBindToEnumerable(IEnumerable arList)
   at ComponentArt.Web.UI.Grid.DataBind()
   at Sitecore.Web.UI.Grids.ComponentArtGridHandler`1.DataBind()
   at Sitecore.Web.UI.Grids.ComponentArtGridHandler`1.InitializeGrid(Boolean dataBind)
   at Sitecore.Web.UI.Grids.ComponentArtGridHandler`1..ctor(Grid grid, IGridSource`1 source, Boolean dataBind)
   at Sitecore.Web.UI.Grids.ComponentArtGridHandler`1.Manage(Grid grid, IGridSource`1 source, Boolean dataBind)
   at Sitecore.Shell.Applications.Security.UserManager.UserManager.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Using reflector I found the code in question:

private void Users_ItemDataBound(object sender, GridItemDataBoundEventArgs e)
{
    e.Item["Profile.PortraitFullPath"] = Themes.MapTheme((e.DataItem as User).Profile.Portrait);
}

There appears to be an issue with the Portrait profile profile property not existing for the GridItem.


Turns out the issue was caused by the aspx files under \sitecore\ in the web site being out of sync with the Sitecore DLLS. In particular, I had Sitecore.Client.dll (6.0.1.2906) and an out of date version of \sitecore\shell\Applications\Security\UserManager\UserManager.aspx. I believe this can about by trying to keep Sitecore under TFS source control. At some point an update package was installed but the changes to the sitecore folder never found their way into source control.

Monday, September 28, 2009

Adding FLV files to the TFS build output

I have several flash videos that I need to include in an ASP.NET web site. From the build servers perspective they should be static content.

For some reason the TFS build server wasn't copying them over to the Binary drop location as part of the _CopyWebApplication target but the SWF files were.

Turned out to be a simple fix. The SWF files were set as "Build Action" "Content" while the FLV files were "Build Action" "None". Changing them to content fixed the problem.


On a side note. I needed to add the MIME type for FLV files to IIS.
.flv   video/x-flv

Friday, September 25, 2009

Arggg - websites with broken email address validation

Gmail offers a handy feature for adding email address aliases by appending a '+' and a term to the end of your email address. See Using an address alias and Wikipedia:Sub-addressing

The issue I keep running into is incorrect email address validation preventing the use of characters that should be valid according to RFC 5322 and RFC 3696.

What annoys me most is that there often isn't an easy way to tell a site that there is a bug. Some problematic sites I've come across:

From some quick Googling it may be that RegEx just won't cut it for email address validation.

Monday, September 21, 2009

Finding missing SATA hard drive after upgrading to Windows 7

I recently upgraded to Windows 7 buy adding an additional SATA hard drive and doing a fresh install. After logging in I found the older existing drive wasn't appearing in Windows 7.

I found I needed to bring up Disk manager (diskmgmt.msc) and map it to a drive letter.

Lake Wanaka - Island within an island within an island (Mou Waho Island)

Caught a bit of South on TV last night and thought I'd find the location they found with a small island sitting inside a larger island in Lake Wanaka. Turns out the island is called Mou Waho Island and the smaller "island" is in the "Arethusa Pool".


View Larger Map