none
Problema Update SPListItem RRS feed

  • Pregunta

  • Hola a todos,

    tengo un pequeño problema cuando quiero añadir un item a una lista.

    Esta sería mi estructura a la hora de acceder a mi mlista en cuestión

    protected
     SPSite miSitio;
    protected
     SPWeb miWeb;
    protected
     SPListCollection coleccionListas;
    protected
     SPList listaObjetivos;
    protected
     SPListItemCollection coleccionItems;
        
    miSitio = SPControl.GetContextSite(Context);
    miSitio.AllowUnsafeUpdates = true
    ;
    miWeb = miSitio.OpenWeb();
    miWeb.AllowUnsafeUpdates = true
    ;
    
    coleccionListas = miWeb.Lists;
    listaObjetivos = coleccionListas["Mi Lista"
    ];
    coleccionItems = listaObjetivos.Items;
    
    

    Creo un nuevo item y añado el titulo del nombre a mi item, hasta ahí todo bien.

    SPListItem newItem = coleccionItems.Add();
    newItem["Title"
    ] = tbNombre.Text;
    newItem.Update();
    

    El problema viene con la linea del Update del item que da el siguiente error: No se puede completar esta acción. Vuelva a intentarlo.

    ¿Alguna ayuda?

    Saludos y gracias.
    Jaime.
    • Editado jaime35740 jueves, 27 de agosto de 2009 13:44
    jueves, 27 de agosto de 2009 13:43

Respuestas

  • Ten en cuenta que todo código de SharePoint que no se ejecuta desde la interfaz de usuario (es decir, que no tiene un control FormDigest integrado) necesita usar AllowUnsafeUpdates=true . Los que no lo necesitan son webparts y páginas ASPX de SharePoint.

    Saludos,

    -- Edin http://edinkapic.blogspot.com
    lunes, 31 de agosto de 2009 7:12
    Moderador
  • He conseguido solucinarlo.

    Básicamente lo que he hecho antes del hacer el Update, justo antes, poner la propiedad AllowUnsafeUpdates = true y justo despues volverla a darle el valor false.

    Saludos a todos y gracias.
    viernes, 28 de agosto de 2009 12:50
  • Hola Jaime,

    ¿Puedes poner toda la pila de la excepción para ver justo donde falla?

    Dos recomendaciones:

    1. El uso de listaObjetivos.Items no es muy eficiente. Cuando se ejecuta, obtiene una copia de todos los elementos de la lista. Con listas de pocos elementos no se nota, pero a medida que aumente el número de elementos el rendimiento disminuirá bastante. Una posible alternativa es esta: http://mo.notono.us/2009/03/beware-of-splistitemsadd.html , aunque yo no la he probado.

    2. Si ejecutas miWeb = miSitio.OpenWeb(); es necesario realizar un Dispose el objeto miWeb

    Un saludo
    lunes, 14 de septiembre de 2009 12:14
  • Hola Borja,

    pues si esta en un webpart, mejor dicho en un webpart llamado SmartPart que se le añaden controles ascx. Encontre esta solución para poder diseñar mi control como si fuera un control ascx, pienso que es una forma mucho más facil e intuitiva que estar metiendo los controles a pelo a nível de código en un webpart.

    itemobj es de tipo string, se lo pasaba por parámentro al método.

    Después de no tocar ayer el código, decidí probar esto esta mañana:

    try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite mySite = new SPSite("http://unibonau:48699"))
                    {
                        mySite.AllowUnsafeUpdates = true;
                        using (SPWeb myWeb = mySite.OpenWeb())
                        {
                            myWeb.AllowUnsafeUpdates = true;
                            SPListCollection myLists = myWeb.Lists;
                            
                            SPList myList = myLists["Lista de Objetivos - Sitio Sede"];
                            SPListItemCollection myItems = myList.Items;
                            SPListItem myItem = myItems.Add();
                            myItem["Title"] = tbNombre.Text;
                            myItem["Descripcion"] = tbDescripcion.Text;
                            myItem["ValorObj"] = tbValorObj.Text;
                            myItem["Perspectiva"] = PerspObj;
                            myItem.Update();
                          
                            SPList myList2 = myLists["Lista de Indicadores KPI - Sitio Sede"];
                            SPListItemCollection myItems2 = myList2.Items;
                            SPListItem myItem2 = myItems2.Add();
                            myItem2["Title"] = "KPI - " + tbNombre.Text;
                            myItem2["IdObjetivo"] = tbNombre.Text;
                            myItem2["WS"] = "webservice";
                            myItem2.Update();
    
                            myWeb.AllowUnsafeUpdates = false;
                        }
                        mySite.AllowUnsafeUpdates = false;
                    }
                });            
            }
            catch (SPException ex)
            {
                Error.Text = ex.Message + "<br>" + ex.StackTrace; 
            }

    Y funciono en primera instancia. Básicamente he añadido el item en la segunda lista dentro del mismo procedimiento por si acaso la parte de los permisos entre en conflicto, cosa que creo que debería dar igual.

    Bueno tras desplegar la solución al hacer unos cambios en otra parte del código (básicamente quitar unos chivatos para las trazas), vuelta a empezar con el problema. Vuelve a saltar la excepción y la verdad que no tengo ni idea de que hacer ya.


    Saludos y muchas gracias!
    jueves, 17 de septiembre de 2009 9:11
  • Hola!

    he conseguido dar con el problema, no se si será nombre reservado o que pero el problema venía en el nombre campo de la lista "WS". Lo he cambiado por "WebService" y tira bien. Al fin!!! jejeje

    No se si será por lo que dije antes de que sea un nombre de campo reservado o no se.

    Muchas gracias Borja!!!

    PD: Estaré atento a tu blog que seguro que publicas cosas interesentas.
    jueves, 17 de septiembre de 2009 11:43

Todas las respuestas

  • Hola Jaime, creo que el problema está en esta instrucción:

    SPListItem newItem = coleccionItems.Add();

    ¿No debería ser?

    SPListItem newItem =  listaObjetivos.Add();

    Saludos,

    Juan Pablo.
    http://surpoint.blogspot.com/
    jueves, 27 de agosto de 2009 17:09
  • Hola Juan Pablo,

    que yo sepa una SPList no tiene el método Add no? El problema creo que es en el Update, a lo mejor me falta algún paso o propiedad.

    Saludos y gracias por tu atención.

    Jaime.
    viernes, 28 de agosto de 2009 8:25
  • He conseguido solucinarlo.

    Básicamente lo que he hecho antes del hacer el Update, justo antes, poner la propiedad AllowUnsafeUpdates = true y justo despues volverla a darle el valor false.

    Saludos a todos y gracias.
    viernes, 28 de agosto de 2009 12:50
  • Saludos Jaime!
    viernes, 28 de agosto de 2009 18:34
  • Ten en cuenta que todo código de SharePoint que no se ejecuta desde la interfaz de usuario (es decir, que no tiene un control FormDigest integrado) necesita usar AllowUnsafeUpdates=true . Los que no lo necesitan son webparts y páginas ASPX de SharePoint.

    Saludos,

    -- Edin http://edinkapic.blogspot.com
    lunes, 31 de agosto de 2009 7:12
    Moderador
  • Hola de nuevo a todos,

    estoy volviendo a tener de nuevo el problema con el Update al añadir un elemento a otra lista personalizada. La verdad que no tengo ni idea porque esta dando este error.

    La excepción que me da es el siguiente: No se puede completar esta acción. Vuelva a intertarlo

    Mi código para añadir el nuevo item a la lista es el siguiente:

    try
            {
                SPListItem Item = coleccionItemsKPI.Add();
                miWeb.AllowUnsafeUpdates = true;
                Item["Title"] = "KPI-" + itemObj;
                Item["IdObjetivo"] = itemObj;
                Item["WS"] = "webservice";
                Item.Update();
                miWeb.AllowUnsafeUpdates = false;
            }
    catch (SPException ex)
    {
           Error.Text = ex.Message;
    }

    Alguna ayuda?

    Gracias a todos y saludos.
    lunes, 14 de septiembre de 2009 11:01
  • Hola Jaime,

    ¿Puedes poner toda la pila de la excepción para ver justo donde falla?

    Dos recomendaciones:

    1. El uso de listaObjetivos.Items no es muy eficiente. Cuando se ejecuta, obtiene una copia de todos los elementos de la lista. Con listas de pocos elementos no se nota, pero a medida que aumente el número de elementos el rendimiento disminuirá bastante. Una posible alternativa es esta: http://mo.notono.us/2009/03/beware-of-splistitemsadd.html , aunque yo no la he probado.

    2. Si ejecutas miWeb = miSitio.OpenWeb(); es necesario realizar un Dispose el objeto miWeb

    Un saludo
    lunes, 14 de septiembre de 2009 12:14
  • Ahi va la stacktrace de la excepción.

    Excepción de HRESULT: 0x80040E07
    en Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bMigration, Boolean bPublish) en Microsoft.SharePoint.SPListItem.AddOrUpdateItem(Boolean bAdd, Boolean bSystem, Boolean bPreserveItemVersion, Boolean bNoVersion, Boolean bMigration, Boolean bPublish, Boolean bCheckOut, Boolean bCheckin, Guid newGuidOnAdd, Int32& ulID, Object& objAttachmentNames, Object& objAttachmentContents, Boolean suppressAfterEvents) en Microsoft.SharePoint.SPListItem.UpdateInternal(Boolean bSystem, Boolean bPreserveItemVersion, Guid newGuidOnAdd, Boolean bMigration, Boolean bPublish, Boolean bNoVersion, Boolean bCheckOut, Boolean bCheckin, Boolean suppressAfterEvents) en Microsoft.SharePoint.SPListItem.Update() en DMObjetivos.CrearKPI(String itemObj) en c:\Inetpub\wwwroot\CtrlMac\DMObjetivos.ascx.cs:línea 163


    He añadido unas nuevas lineas de codigo que he estado "googleando" más, y he encontrado que hay más gente que se ha encontrado con problemas parecidos.

    try
    {
       SPSecurity.RunWithElevatedPrivileges(delegate()
       {
          using (miSitio) { miWeb = miSitio.RootWeb; }  
       }); 
       SPListItem Item = coleccionItemsKPI.Add();
       miWeb.AllowUnsafeUpdates = true;
       Item["Title"] = "KPI-" + itemObj;
       Item["IdObjetivo"] = itemObj;
       Item["WS"] = "webservice";
       Item.Update();  
    }
    catch (SPException ex)
    {
       Error.Text = ex.Message + "<br>" + ex.StackTrace;
    }
    No entiendo muy bien el motivo de hacer el Dispose del SPWeb

    Muchas gracias de nuevo Borja.
     

    lunes, 14 de septiembre de 2009 12:42

  • Has probado este código:

       SPSecurity.RunWithElevatedPrivileges(delegate()
       {
          miWeb = miSitio.RootWeb;  
          SPListItem Item = coleccionItemsKPI.Add();
          miWeb.AllowUnsafeUpdates = true;
          Item["Title"] = "KPI-" + itemObj;
          Item["IdObjetivo"] = itemObj;
          Item["WS"] = "webservice";
          Item.Update();
       });

    Lo que te comentaba del Dispose es si obtenias el web mediante OpenWeb (como en tu primer mensaje).

    Al obtener el SPSite del contexto, no es necesario meterlo en un using.

    Saludos
    lunes, 14 de septiembre de 2009 13:15
  • Si, si obtengo el web mediante el OpenWeb. ¿No es recomendable?

    No tira bien, sale con esta excepción:

    Excepción de HRESULT: 0x80040E07
    en Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bMigration, Boolean bPublish) en Microsoft.SharePoint.SPListItem.AddOrUpdateItem(Boolean bAdd, Boolean bSystem, Boolean bPreserveItemVersion, Boolean bNoVersion, Boolean bMigration, Boolean bPublish, Boolean bCheckOut, Boolean bCheckin, Guid newGuidOnAdd, Int32& ulID, Object& objAttachmentNames, Object& objAttachmentContents, Boolean suppressAfterEvents) en Microsoft.SharePoint.SPListItem.UpdateInternal(Boolean bSystem, Boolean bPreserveItemVersion, Guid newGuidOnAdd, Boolean bMigration, Boolean bPublish, Boolean bNoVersion, Boolean bCheckOut, Boolean bCheckin, Boolean suppressAfterEvents) en Microsoft.SharePoint.SPListItem.Update() en DMObjetivos.<>c__DisplayClass2.b__0() en Microsoft.SharePoint.SPSecurity.CodeToRunElevatedWrapper(Object state) en Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.b__2() en Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode) en Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode, Object param) en Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode) en DMObjetivos.CrearKPI(String itemObj)

    Gracias y saludos. A ver si puedo encontrar el problema o ver que estoy haciendo mal.
    lunes, 14 de septiembre de 2009 13:36
  • Respecto al uso a los objetos SPWeb y SPSite, dependiendo de como se hayan creado es necesario realizar el Dispose de estos para evitar problemas de liberación de memoria. En este enlace te explica como funciona: http://msdn.microsoft.com/en-us/library/aa973248.aspx

    Se me ocurre que pruebes el siguiente código:

    SPSecurity.RunWithElevatedPrivileges(delegate()
       {
          miSitio.AllowUnsafeUpdates = true;
          miWeb = miSitio.RootWeb;  
          miWeb.AllowUnsafeUpdates = true;
          SPListItem Item = coleccionItemsKPI.Add();
          Item["Title"] = "KPI-" + itemObj;
          Item["IdObjetivo"] = itemObj;
          Item["WS"] = "webservice";
          Item.Update();
       });

    Sobre el uso de AllowUnsafeUpdates te mira este enlace: http://blogs.renacimiento.com/aarias/archive/2009/08/18/[moss]-la-propiedad-allowunsafeupdates.aspx

    Saludos
    martes, 15 de septiembre de 2009 6:51
  • Lo he probado, y sigue habiendo el mismo problema con el update.

    Me miraré bien los dos artículos que has puesto, parecen bastante interesantes. La verdad que no entiendo muy bien sigue saltando la excepción, se supone que ya por tema de permisos no debería de ser.

    Muchas Gracias Borja.
    martes, 15 de septiembre de 2009 7:37
  • He cambiado parte del código y he utilizado using para el tema que me comentaste anteriormente, así se encarga automáticamente de realizar los dispose.

    Con una de mis listas no tengo problemas al realizar el update

    try
            {
                this.CrearKPI(tbNombre.Text);
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite mySite = new SPSite("http://unibonau:48699"))
                    {
                        mySite.AllowUnsafeUpdates = true;
                        using (SPWeb myWeb = mySite.OpenWeb())
                        {
                            myWeb.AllowUnsafeUpdates = true;
                            SPListCollection myLists = myWeb.Lists;
                            SPList myList = myLists["Lista de Objetivos - Sitio Sede"];
                            SPListItemCollection myItems = myList.Items;
                            SPListItem myItem = myItems.Add();
                            myItem["Title"] = tbNombre.Text;
                            myItem["Descripcion"] = tbDescripcion.Text;
                            myItem["ValorObj"] = tbValorObj.Text;
                            myItem["Perspectiva"] = PerspObj;
                            myItem.Update(); 
                            
                            ttPerspectiva.Visible = false;
                            gvObjetivos.Visible = true;
                            ttNewObj.Visible = false;
                            btNewObj.Visible = true;
                            tbNombre.Text = "";
                            tbDescripcion.Text = "";
                            gvObjetivos.DataSource = getObjetivos();
                            gvObjetivos.DataBind();
    
                            myWeb.AllowUnsafeUpdates = false;
                        }
                        mySite.AllowUnsafeUpdates = false;
                    }
                });            
            }
            catch (SPException ex)
            {
                Error.Text = ex.Message + "<br>" + ex.StackTrace; 
            }
    con este no hay ningun problema pero en el metodo CrearKPI(tb) es básicamente lo mismo y me salta la excepción del Update. La verdad que no se que pensar.

    try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite mySite = new SPSite("http://unibonau:48699"))
                    {
                        mySite.AllowUnsafeUpdates = true;
                        using (SPWeb myWeb = mySite.OpenWeb())
                        {
                            myWeb.AllowUnsafeUpdates = true;
                            SPListCollection myLists = myWeb.Lists;
                            SPList myList = myLists["Lista de Indicadores KPI - Sitio Sede"];
                            SPListItemCollection myItems = myList.Items;
                            SPListItem myItem = myItems.Add();
                            myItem["Title"] = "KPI - " + itemObj;
                            myItem["IdObjetivo"] = itemObj;
                            myItem["WS"] = "webservice";
                            myItem.Update();
    
                            myWeb.AllowUnsafeUpdates = false;
                        }
                        mySite.AllowUnsafeUpdates = false;
                    }
                });
            }
            catch (SPException ex)
            {
                Error.Text = "KPI" + "<br>" +  ex.Message + "<br>" + ex.StackTrace;
            }
    Las listas las he hecho mediante una plantilla con VSEWSS, y funcionan correctamente si lo realizo a través del navegador directamente en SharePoint.

    Tambien he probado a realizar esa operación con las lista que da problemas a través de una aplicación de consola y da el mismo efecto, salta la excepción.

    Alguna ayuda??

    Gracias y Saludos a todos.

    miércoles, 16 de septiembre de 2009 11:30
  • Puedes verificar que los valores que estas asignando a las columnas tienen valores permitidos por estas columnas (¿de qué tipo es itemObj?).

    Este código, ¿se encuentra en un WebPart?
     
    Por cierto, respecto a lo que te comentaba en otro mensaje sobre hacer la inserción mediante Items.Add, olvidalo. He estado haciendo pruebas y no afecta al rendimiento: http://blogs.renacimiento.com/bvalle/archive/2009/09/16/[moss]-análisis-y-rendimiento-de-splist-items-add.aspx

    Un saludo
    borja
    http://blogs.renacimiento.com/bvalle
    miércoles, 16 de septiembre de 2009 16:14
  • Hola Borja,

    pues si esta en un webpart, mejor dicho en un webpart llamado SmartPart que se le añaden controles ascx. Encontre esta solución para poder diseñar mi control como si fuera un control ascx, pienso que es una forma mucho más facil e intuitiva que estar metiendo los controles a pelo a nível de código en un webpart.

    itemobj es de tipo string, se lo pasaba por parámentro al método.

    Después de no tocar ayer el código, decidí probar esto esta mañana:

    try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite mySite = new SPSite("http://unibonau:48699"))
                    {
                        mySite.AllowUnsafeUpdates = true;
                        using (SPWeb myWeb = mySite.OpenWeb())
                        {
                            myWeb.AllowUnsafeUpdates = true;
                            SPListCollection myLists = myWeb.Lists;
                            
                            SPList myList = myLists["Lista de Objetivos - Sitio Sede"];
                            SPListItemCollection myItems = myList.Items;
                            SPListItem myItem = myItems.Add();
                            myItem["Title"] = tbNombre.Text;
                            myItem["Descripcion"] = tbDescripcion.Text;
                            myItem["ValorObj"] = tbValorObj.Text;
                            myItem["Perspectiva"] = PerspObj;
                            myItem.Update();
                          
                            SPList myList2 = myLists["Lista de Indicadores KPI - Sitio Sede"];
                            SPListItemCollection myItems2 = myList2.Items;
                            SPListItem myItem2 = myItems2.Add();
                            myItem2["Title"] = "KPI - " + tbNombre.Text;
                            myItem2["IdObjetivo"] = tbNombre.Text;
                            myItem2["WS"] = "webservice";
                            myItem2.Update();
    
                            myWeb.AllowUnsafeUpdates = false;
                        }
                        mySite.AllowUnsafeUpdates = false;
                    }
                });            
            }
            catch (SPException ex)
            {
                Error.Text = ex.Message + "<br>" + ex.StackTrace; 
            }

    Y funciono en primera instancia. Básicamente he añadido el item en la segunda lista dentro del mismo procedimiento por si acaso la parte de los permisos entre en conflicto, cosa que creo que debería dar igual.

    Bueno tras desplegar la solución al hacer unos cambios en otra parte del código (básicamente quitar unos chivatos para las trazas), vuelta a empezar con el problema. Vuelve a saltar la excepción y la verdad que no tengo ni idea de que hacer ya.


    Saludos y muchas gracias!
    jueves, 17 de septiembre de 2009 9:11
  • Buenas,

    el campo IdObjetivo, ¿es de tipo cadena? Puedes utilizar la aplicacion SharePoint Manager (http://www.codeplex.com/spm) para ver el schema de la lista.

    Solo se me ocurre investigar por ahi.

    Un saludo
    borja
    jueves, 17 de septiembre de 2009 11:36
  • Hola!

    he conseguido dar con el problema, no se si será nombre reservado o que pero el problema venía en el nombre campo de la lista "WS". Lo he cambiado por "WebService" y tira bien. Al fin!!! jejeje

    No se si será por lo que dije antes de que sea un nombre de campo reservado o no se.

    Muchas gracias Borja!!!

    PD: Estaré atento a tu blog que seguro que publicas cosas interesentas.
    jueves, 17 de septiembre de 2009 11:43