Add choice to SPFieldChoice from an Eventreceiver in sandboxed
-
07-12-2019 - |
Pergunta
I am trying to make a sandboxed solution that adds a couple of itemeventreceivers to a list, that add the items to the choices of a choicefield. The result would be something like a lookup field, without the referential integrity.
The code below works perfectly in a regular solution - the choice gets added to the field as expected, but in a sandboxed solution I get no results. The event receiver does fire, no exceptions occur and and all code is reached when stepping through, but the item just isn't added. I think I'm doing nothing here that is impossible in a sandboxed solution. Is there something I need to do differently because this code runs sandboxed?
public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);
string itemTitle = properties.AfterProperties["Title"].ToString();
SPField _field = properties.Web.Fields["Klant"];
if (_field == null)
{
properties.Cancel = true;
return;
}
SPFieldChoice KlantField = (SPFieldChoice)_field;
foreach (string choice in KlantField.Choices)
{
if (itemTitle.ToLower() == choice.ToLower())
{
properties.Cancel = true;
return;
}
}
KlantField.Choices.Add(itemTitle);
KlantField.Update(true);
properties.Web.Update();
}
Background: I am running VS2010 to debug, I have a Sharepoint Foundation Server to test on, and I also tried the sandboxed solution on Office365, the environment where we want to use this solution. The sandboxed and non-sandboxed solutions I'm talking about are separate solutions, and not changed afterwards. They are identical except for the description and GUIDs and that one was made as a sandboxed solution and the other as a farm solution one.
Solução
All credit goes to Xiang Zeng for providing the answer, many thanks!
This is a bug in Sharepoint. However, there is a workaround.
Directly modifying the SchemaXml property to change the choices is allowed:
public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);
string itemTitle = properties.AfterProperties["Title"].ToString();
SPField _field = properties.Web.Fields["Klant"];
if (_field == null)
{
properties.Cancel = true;
return;
}
SPFieldChoice KlantField = (SPFieldChoice)_field;
foreach (string choice in KlantField.Choices)
{
if (itemTitle.ToLower() == choice.ToLower())
{
properties.Cancel = true;
return;
}
}
string originalXml = KlantField.SchemaXml;
string newXml = originalXml.Replace("</CHOICES>", String.Format("<CHOICE>{0}</CHOICE></CHOICES>", itemTitle));
KlantField.SchemaXml = newXml;
}
Note that calling the Update method is not necessary: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfield.schemaxml.aspx
ItemUpdating and ItemDeleting can be done in the same way. I tested it both on my own server and in office365, and it works like a charm!