2012-11-24 17 views
5

Ho creato un processo timer (SPJobDefintion) che è registrato correttamente e funziona in un ambiente di SharePoint 2010.SharePoint TimerJob: Utilizzo di SPListItem.Update() in un'istanza di una classe/metodo statico

Nel metodo Execute del processo timer sono in grado di utilizzare il seguente codice, che definisce un campo di uno specifico SPListItem. Funziona bene

using (SPSite mySite = new SPSite(mySiteId)) 
{ 
    using (SPWeb myWeb = mySite.OpenWeb(myWebId))) 
    { 
    SPList myList= myWeb.Lists[myListId]; 
    SPListItem myItem = myList.GetItemById(myItemId); 

    myItem["myField"] = myValue; 
    myItem.Update(); 
    } 
} 

Per motivi di progettazione, desidero inserire tale codice in un metodo separato di una classe separata. Così ho creato la seguente classe:

namespace myNamespace 
{ 
    class myClass 
    { 

    [...some stuff...]   

    public myClass() 
    { 
     [...more stuff...] 
    } 

    public void setField() 
    { 
     using (SPSite mySite = new SPSite(mySiteId)) 
     { 
     using (SPWeb myWeb = mySite.OpenWeb(myWebId))) 
     { 
      SPList myList = myWeb.Lists[myListId]; 
      SPListItem myItem = myList.GetItemById(myItemId); 

      myItem["myField"] = myValue; 
      myItem.Update(); 
     } 
     } 
    } 
    } 
} 

In realtà mi si aspetterebbe che chiamare questa seguente codice nella Execute metodo del processo timer dovrebbe finire lo stesso risultato.

MyClass myClassInstance = new myClass(); 
myClassInstance.setField(); 

Purtroppo vado a prendere la seguente eccezione:

Microsoft.SharePoint.SPException was unhandled by user code 
    Message="" 
    Source=Microsoft.SharePoint 
    ErrorCode=-2147418113 
    NativeErrorMessage=FAILED hr detected (hr = 0x8000ffff) 

    NativeStackTrace="" 
    StackTrace: 
     bei Microsoft.SharePoint.SPGlobal.HandleComException(COMException comEx) 
     bei Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, [...]) 
     bei Microsoft.SharePoint.SPListItem.AddOrUpdateItem(Boolean bAdd, Boolean bSystem, [...]) 
     bei Microsoft.SharePoint.SPListItem.UpdateInternal(Boolean bSystem, [...]) 
     bei Microsoft.SharePoint.SPListItem.Update() 
     bei myNamespace.myClass.<>c__DisplayClass1.<setField>b__0() 
    InnerException: System.Runtime.InteropServices.COMException 
     Message=<nativehr>0x8000ffff</nativehr><nativestack></nativestack> 
     Source="" 
     ErrorCode=-2147418113 
     StackTrace: 
      bei Microsoft.SharePoint.Library.SPRequestInternalClass.AddOrUpdateItem(String bstrUrl, [...]) 
      bei Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, [...]) 
     InnerException: 

Quando ho messo il setField() metodo direttamente nella classe dove il Execute metodo è, il metodo funziona correttamente . Se dichiaro questo metodo come statico, si verificherà la stessa eccezione.

Ho anche cercato di eseguire il SPListItem.Update(), in cui si verifica l'eccezione, con privilegi elevati (non dovrebbe essere la ragione, perché il codice deve essere eseguito nel contesto OWSTIMER). Ho anche provato a giocare con allowUnsafeUpdates() su SPSite e SPWeb. Entrambi senza successo.

Nel web ho trovato solo una descrizione di questo problema http://codekicker.de/fragen/sharepoint-2010-Sharepoint-2010-TimerJob-wirft-Fehler-timer (in tedesco), purtroppo senza alcuna soluzione.

Cos'altro potrebbe essere la ragione per cui questa costellazione non funzionerà? Qualche idea?

+1

non riesco a vedere niente di sbagliato con il codice, e non c'è niente di speciale in un processo timer che significa che non si può chiamare il codice come questo in una classe diversa. Sono preoccupato per lo stack delle chiamate: il metodo base è 'myNamespace.myClass. <> C__DisplayClass1. b__0() 'quando, dall'esempio del codice del tour, mi sarei aspettato che fosse semplicemente' myNamespace.myClass.setField() '. Hai qualcosa di più complicato da fare qui? – Rawling

+0

Il codice di esempio mancante di righe in cui si passa/imposta l'ID sito/Web. Non sono sicuro se sia un problema o meno, ma prendi in considerazione la possibilità di fornire campioni che mostrino tutte le parti interessanti ... Nota a margine: non esiste un vero walue che abbia il prefisso "mio" per parametri/membri, anche in campioni. –

+0

La classe non dovrebbe essere "pubblica"? Inoltre è possibile eseguire il debug di processi timer (allegare a owstimer.exe) e del proprio codice in modo che si verifichi esattamente l'eccezione? Immagino qui: 'myItem.Update();'? –

risposta

1

Ha sicuramente bisogno di myWeb.AllowUnsafeUpdates = true; prima di aggiornare qualsiasi elemento della lista. non dimenticare di reimpostarlo su false dopo averlo aggiornato.

Una cosa che farei è assicurarsi che l'utente che il codice è in esecuzione abbia pieno diritto di aggiornare l'articolo. Suggerirei di accedere come amministratore del sito e provare a eseguire il codice da un evento clic del pulsante (anziché da un processo timer) o qualche altro evento solo per assicurarsi che non si tratti di un problema di autorizzazione dell'utente.

Grazie

Senthil S

+0

fai attenzione con AllowUnsafeUpdates! di solito devi evitare di usarlo – devi