Anyone who has done any configuration in SharePoint knows the frustration involved with attempting to determine the actual fieldname within a SharePoint list. The following table shows how a column defined as a Site Column at a top level site can be aliased at the Site Column, Site Content Type, Web Content Type and List levels.
| Name/Alias |
Source |
Level1 |
Level2 |
Level3 |
| Team |
Site Column |
- |
- |
- |
| Team Name |
Site Column |
Site Content Type |
- |
- |
| Fav Team Name |
Site Column |
Site Content Type |
Web Content Type |
|
| My Fav Team Name |
Site Column |
Site Content Type |
Web Content Type |
List |
Regardless of what I aliased the field name along the way to present to users, if I want to reference this field in a Content Query Web Part or custom code such as an Event Receiver, I need to reference it by the name “Team”.
There are a lot of posts about how to hack the CQWP to get it to show you all of the underlying field names, or to use the URL of the edit field page to show you the internal name of a field, but both of these are cumbersome and tedious, especially if I have access to a physical Development or Test server. With PowerShell, I can write a very simple script to spit this information out:
cls
$siteUrl = “http://marcs-lt”
$webName = “SiteDirectory”
$listName = “Sites”
$s = Get-SPSite $siteUrl
$w = $s.OpenWeb($webName)
$l = $w.Lists[$listName]
$l.Fields | Where-Object { $_.Hidden -eq $false } | Format-Table Title, InternalName –AutoSize
For those of you needing to do the same thing with 2007:
$siteUrl = “http://marcs-lt”
$webName = “SiteDirectory”
$listName = “Sites”
[System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint”)
$site = New-Object “Microsoft.SharePoint.SPSite” -ArgumentList $siteUrl
$web = $site.OpenWeb($webName)
$list = $web.Lists[$listName]
$list.Fields | Where-Object { $_.Hidden -eq $false } | Format-Table Title, InternalName -AutoSize
$web.Dispose()
$site.Dispose()
Yeah, that’s great, but not too terribly useful
What I want to do is have a strongly typed domain object which will mimic the structure of the list so that I can use it without having to index the SPListItemCollection/SPListItem. Good News, I can use this same script to generate a struct of fieldname which I can then use in building a domain object. Here’s how:
$siteUrl = “http://marcs-lt”
$webName = “SiteDirectory”
$listName = “Sites”
$s = Get-SPSite $siteUrl
$w = $s.OpenWeb($webName)
$l = $w.Lists[$listName]
$l.Fields | Where-Object { $_.Hidden -eq $false } | ForEach-Object {
#using regular expression to replace ‘#’ with ‘Number’ and remove all bad chars
$fieldName = $_.Title -replace “#”, “Number” -replace “[!@#$%\&'\s()<>?:]“, “”
“public const string $($fieldName) = “”$($_.InternalName)”";”
}
Now my domain class could take an SPListItem as a paramerter into the constructor and build out my class like:
public class MyListItem
{
protected string teamName = “”;
protected string status = “”;
public MyListItem(SPListItem listItem)
{
if(listItem[Common.FieldNames.MyList.TeamFieldName] != null)
{
this.teamName = (string)listItem[Common.FieldNames.MyList.TeamFieldName];
}
if(listItem[Common.FieldNames.MyList.Status] != null)
{
this.status = (string)listItem[Common.FieldNames.MyList.Status];
}
. . .
}
public string TeamName
{
get{ return teamName; }
set{ teamName = value; }
}
public string Status
{
get{ return status; }
set{ status = value; } }
}