2012-11-24 20 views
5

Utworzono zadanie czasomierza (SPJobDefintion), które zostało poprawnie zarejestrowane i działa w środowisku Sharepoint 2010.SharePoint TimerJob: Używanie SPListItem.Update() w instancji klasy/metody statycznej

W sposobie Timer Job Execute jestem w stanie użyć następującego kodu, który określa pole szczególnego SPListItem. To działa dobrze.

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(); 
    } 
} 

Ze względów konstrukcyjnych chciałbym umieścić ten kod w osobnej metodzie oddzielnej klasy. Stworzyłem więc następujące klasy:

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(); 
     } 
     } 
    } 
    } 
} 

Właściwie Spodziewam się, że wywołanie tej następujący kod w Execute metodę pracy zegara powinna zakończyć się w tym samym rezultatem.

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

Niestety ja otrzymuję następujący wyjątek:

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: 

Kiedy kładę setField() metody bezpośrednio w klasie, gdzie Execute metodą jest metoda będzie działać poprawnie . Jeśli deklaruję tę metodę jako statyczną, nastąpi ten sam wyjątek.

że również próbował wykonać SPListItem.Update(), gdzie występuje wyjątek, ze zwiększoną uprawnieniami (nie powinna być powodem, ponieważ kod powinien być prowadzony w kontekście OWSTIMER). Próbowałem również grać z allowUnsafeUpdates() na SPSite i SPWeb. Oba bez sukcesu.

W Internecie znalazłem tylko jeden opis tego problemu http://codekicker.de/fragen/sharepoint-2010-Sharepoint-2010-TimerJob-wirft-Fehler-timer (w języku niemieckim), niestety bez żadnego rozwiązania.

Co jeszcze może być przyczyną, że ta konstelacja nie zadziała? Dowolny pomysł?

+1

nie widzę niczego złego w kodzie, a nie ma nic szczególnego w pracy timera to oznacza, że ​​nie można wywołać kodu podobnego w innej klasie. Obawiam się, że twój stos wywołań - podstawową metodą jest 'myNamespace.myClass. <> C__DisplayClass1. b__0() 'gdy, z przykładu kodu trasy, oczekiwałbym, że będzie to po prostu' myNamespace.myClass.setField() '. Czy dzieje się tu coś bardziej skomplikowanego? – Rawling

+0

W Twoim przykładowym kodzie brakuje linii, w których przekazujesz/ustawiasz identyfikator strony/strony. Nie jestem pewien, czy jest to problem, czy nie, ale rozważ dostarczenie próbek, które pokazują wszystkie interesujące części ... Uwaga boczna: nie ma prawdziwej daty posiadania "mojego" przedrostka dla parametrów/elementów, nawet w próbkach. –

+0

Czy klasa nie powinna być "publiczna"? Możesz także debugować zadania timera (dołącz do owstimer.exe) i swój kod, gdzie dokładnie ma miejsce wyjątek? Chyba tutaj: 'myItem.Update();'? –

Odpowiedz

1

Zdecydowanie potrzebuje myWeb.AllowUnsafeUpdates = true; przed aktualizacją dowolnego elementu listy. nie zapomnij zresetować go do wartości false po aktualizacji.

Jedną z rzeczy, którą upewnię się, jest upewnienie się, że użytkownik, który uruchamia kod, ma pełne prawa do aktualizacji elementu. Proponuję zalogować się jako administrator witryny i spróbować uruchomić kod ze zdarzenia kliknięcia przycisku (a nie z timera) lub innego zdarzenia, aby upewnić się, że nie jest to problem uprawnień użytkownika.

Dzięki

Senthil S

+0

uważaj z AllowUnsafeUpdates! zwykle musisz tego unikać – devi

Powiązane problemy