I have several classes that are derived from SPPersistedObject. One of them is my top level class that then contains a collection of other derived SPPersistedObjects. Here is a rough outline of my code:
[System.Runtime.InteropServices.GuidAttribute("9BEDC353-F0AC-40FA-A28B-E18FB22EA9CA")
internal class FolderSettings : SPPersistedObject
{
[Persisted]
Guid _folderId;
[Persisted]
string _folderName;
public FolderSettings() : base() {}
protected FolderSettings(Guid folderId, string folderName) : base()
{
_folderId = folderId;
_folderName = folderName;
}
}
[System.Runtime.InteropServices.GuidAttribute("329DE509-76E6-4FA5-A9C1-2543F0A6B5D3")]
internal class EnhancedFolderSettings : FolderSettings
{
[Persisted]
string _outputLocation;
public EnhancedFolderSettings() : base() {}
public EnhancedFolderSettings(Guid folderId, string folderName,
string outputLocation) : base(folderId, folderName)
{
_outputLocation = outputLocation;
}
}
[System.Runtime.InteropServices.GuidAttribute("62FA87FB-2BB4-4AC6-A82A-737E8BEC0219")]
internal class EnhancedFolderSettingsCollection : SPPersistedObject,
IDictionary<Guid, EnhancedFolderSetrtings>
{
[Persisted]
Dictionary<Guid, EnhancedFolderSettings> _collection =
Dictionary<Guid, EnhancedFolderSettings>();
public EnhancedFolderSettingsCollection() : base() {}
// Implementation of IDictionary Interface here
// Implementation of ICollection Interface here
// Implementation of IEnumerable Interface here
}
[System.Runtime.InteropServices.GuidAttribute("F080ED50-85DF-4821-884B-97B05995F8F1")]
internal class FeatureSettings : SPPersistedObject
{
[Persisted]
string _workingFolder;
[Persisted]
string _serviceIpAddress;
public FeatureSettings() : base() {}
public FeatureSettings(string name, SPPersistedObject parent)
: base(name, parent)
{
}
protected override bool HasAdditionalUpdateAccess()
{
return true;
}
}
[System.Runtime.InteropServices.GuidAttribute("C54B006A-69D4-4315-A9FF-F7998A985935")]
internal class EnhancedFeatureSettings : FeatureSettings
{
const string _SETTINGS_NAME = "EnhancedSettingsName";
[Persisted]
Dictionary<Guid, EnhancedFolderSettingsCollection> _siteFeatureSettings;
public EnhancedFeatureSettings() : base() {}
public EnhancedFeatureSettings(SPPersistedObject parent)
: base(_SETTINGS_NAME, parent)
{
}
public static EnhancedFeatureSettings GetSettings(bool createNew)
{
EnhancedFeatureSettings settings =
SPFarm.Local.GetChild<EnhancedFeatureSettings>(_SETTINGS_NAME);
if (settings == null && createNew)
{
settings = new EnhancedFeatureSettings(SPFarm.Local);
}
return settings;
}
internal EnhancedFolderSettingsCollection GetSiteSettings(Guid siteId)
{
EnhancedFolderSettingsCollection collection = null;
_siteFeatureSettings.TryGetValue(siteId, out collection);
return collection;
}
internal Dictionar<Guid, EnhancedFolderSettingsCollection> FolderSettings
{
get
{
return _siteFeatureSettings;
}
}
}
That is all of the settings classes, now here is some sample code trying to update the settings and causing the error. It should be noted that this is running in an administrative context (from a CentralAdmin configuration window) so I don’t think this is permissions related:
public void UpdateSettings(Guid siteId, Guid folderId,
EnhancedFolderSettings currentSettings)
{
var settings = EnhancedFeatureSettings.GetSettings(true);
var siteSettings = settings.GetSiteSettings(siteId);
if (siteSettings == null)
{
siteSettings = new EnhancedFolderSettingsCollection();
}
siteSettings[folderId] = currentSettings;
settings.FolderSettings[siteId] = siteSettings;
settings.Update() // This is the line that is causing the exception
}
Any help would be appreciated. The exception is:
System.ArgumentException: The value is not a valid guid.
The stack trace points to the settings.Update() line.
I am answering my own question since I have had no answers yet and have now received new information. You can see a related question that I posted on SharePoint.SE. I found that there were some missing pieces in this code, but even after getting some of those things handled I was still having issues. After trying to hire a consultant to help with this issue, I received back a response that basically said “Don’t do that”. The
SPPersistedObjectframework can be flaky (several posts about this on the Internet) and is not really designed to do what I am trying to do. It was recommended to redesign the settings framework to use hidden lists.