El monstruito no soy yo, es el SharePoint

El Blog de Luis Mañez, dedicado a tecnologías MS, principalmente SharePoint y Office 365

Office 365: Añadir opciones a un campo SPFieldChoice, no es tan evidente con la Sandbox!!

Hoy me he encontrado que algo tan “sencillo”, como añadir “options” a un campo de tipo SPFieldChoice, no es tan sencillo cuando lo hacemos en SharePoint online.

Si queremos añadir una opción más a un campo dado, el código sería tan sencillo como:

   1: try
   2: {
   3:     SPList list = SPContext.Current.Web.Lists.TryGetList("Products");
   4:  
   5:     if (list == null)
   6:     {
   7:         throw new SPException("List not found");
   8:     }
   9:  
  10:     SPFieldChoice fieldChoice = list.Fields.GetField("ChoiceColumn") as SPFieldChoice;
  11:     fieldChoice.Choices.Add("New option");
  12:  
  13:     fieldChoice.Update();
  14: }
  15: catch (Exception ex)
  16: {
  17:     TextBox1.Text = ex.ToString();
  18: }

Si eso mismo, lo desplegamos en una solución de granja, funciona perfectamente.

Sin embargo, si lo hacemos en una solución sandbox, no obtendremos ningún error, pero la opción nunca se añadirá al SPFieldChoice.

En principio, la clase SPFieldChoice es perfectamente válida en Sandboxed solutions, su propiedad Choices también lo es.

El motivo lo desconozco por completo, y además, me parece rarísimo, ya que he revisado con Reflector el código del método UpdateInternal, y me parece de lo más sencillo, así que no me explico que puede haber diferente en la dll de la Sandbox, para que no funcione.

Por suerte, sí tenemos solución, y es tan “sencilla”, como editar la propiedad SchemaXml, y añadirle el XML necesario para la nueva Opción. Aquí podemos ver un ejemplo:

   1: <Field Type="Choice" DisplayName="ChoiceColumn" Required="FALSE" EnforceUniqueValues="FALSE" Indexed="FALSE" Format="Dropdown" FillInChoice="FALSE" ID="{5a7765f4-07c7-4dd9-8237-1f73174bede0}" SourceID="{e71844c7-9724-47c7-92d1-6c279e3ad8a0}" StaticName="ChoiceColumn" Name="ChoiceColumn" ColName="nvarchar3" RowOrdinal="0" Version="3">
   2:   <Default>Option 1</Default>
   3:   <CHOICES>
   4:     <CHOICE>Option 1</CHOICE>
   5:     <CHOICE>Option 2</CHOICE>
   6:     <CHOICE>Option 3</CHOICE>
   7:     <CHOICE>New option</CHOICE>
   8:   </CHOICES>
   9: </Field>

Esto lo podemos hacer bien sencillo con LINQ to XML:

   1: //Get SPFieldChoice from desired List
   2: SPFieldChoice fieldChoice = GetChoiceColumn();
   3:  
   4: //Parse SchemaXml property as XElement
   5: XElement fieldXml = XElement.Parse(fieldChoice.SchemaXml);
   6:  
   7: //Create XElement node: <CHOICE>now</CHOICE>
   8: XElement choice = new XElement("CHOICE");
   9: choice.SetValue("Added_" + DateTime.Now.ToString());
  10: //Get CHOICES node and Add new CHOICE node
  11: fieldXml.Element("CHOICES").Add(choice);
  12: //Update SchemaXml and Field
  13: fieldChoice.SchemaXml = fieldXml.ToString();
  14: fieldChoice.Update();

Y así, podemos añadir una nueva opción a nuestro campo SPFieldChoice en soluciones Sandbox.

Saludos!!

Posted: 1/3/2012 15:36 por Luis Mañez | con no comments
Comparte este post: