2015-03-04 3 views
1

Я создал задание таймера с помощью следующего кода:При удалении задания таймера он выдает сообщение об ошибке «Ссылка на объект не указывает на экземпляр объекта»

namespace EmployeeDemo 
{ 
    class DeleteEmployees : SPJobDefinition 
    { 
     public DeleteEmployees() : base() { } 

     public DeleteEmployees(string jobName, SPWebApplication webapp) 
      : base(jobName, webapp, null, SPJobLockType.ContentDatabase) 
     { 
      this.Title = "Delete Employees Timer Job"; 
     } 

     public override void Execute(Guid targetInstanceId) 
     { 
      // Code 
     } 
    } 
} 

Затем я создал сайта контекстными функцию. В своем случае приемник, при деактивации, у меня есть следующий код:

const string timerJobName = "Delete Employees Timer Job"; 
public override void FeatureDeactivating(SPFeatureReceiverProperties properties) 
{ 
    DeleteJob(properties.Feature.Parent as SPSite); 
} 
private void DeleteJob(SPSite site) 
{ 
    foreach (SPJobDefinition job in site.WebApplication.JobDefinitions) 
    { 
     if (job.Name == timerJobName) 
     { 
      job.Delete(); 
     } 
    } 
} 

Но это меня выбрасывает. От отладки я понимаю, что ошибка выносится на строку job.Delete();. Ошибка:

Ссылка на объект не установлена ​​в экземпляр объекта.

Это меня смущает, поскольку инструкция job.Name безупречно выполняет и даже дает мне правильный объект задания таймера. Но при попытке удалить задание это порождает мне ошибку.

Я нашел this question с аналогичной проблемой, как у меня, но предложения не помогли мне. От this discussion Я попытался написать код удаления в SPSecurity.RunWithElevatedPrivileges, но он все еще не работал для меня.

Кто-нибудь знает, почему это происходит и как это разрешить?

Update 1

Немного больше подробностей.

NullReferenceException был необработанное кодом пользователя

объекта не задана ссылка на экземпляр объекта.

Вот трассировки стека

at Microsoft.SharePoint.Administration.SPConfigurationDatabase.DeleteObject(Guid id) 
    at Microsoft.SharePoint.Administration.SPConfigurationDatabase.Microsoft.SharePoint.Administration.ISPPersistedStoreProvider.DeleteObject(SPPersistedObject persistedObject) 
    at Microsoft.SharePoint.Administration.SPPersistedObject.Delete() 
    at Microsoft.SharePoint.Administration.SPJobDefinition.Delete() 
    at EmployeeDemo.Features.DeleteEmpFeature.DeleteEmpFeatureEventReceiver.DeleteJob(SPSite site) 
    at EmployeeDemo.Features.DeleteEmpFeature.DeleteEmpFeatureEventReceiver.FeatureDeactivating(SPFeatureReceiverProperties properties) 
    at Microsoft.SharePoint.SPFeature.DoActivationCallout(Boolean fActivate, Boolean fForce) 
+0

Если исключение действительно выбрано 'job.Delete()', то оно должно быть выбрано где-то внутри метода 'Delete'. Просто потому, что если 'job' равно null - исключение будет выбрано по одной строке раньше, в' job.Name'. Поэтому вам нужно изучить метод «Удалить», который вы нам не показали. –

+0

@AndyKorneyev: Метод 'Delete()' относится к классу ['SPJobDefinition'] (https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spjobdefinition_members.aspx). Это из SharePoint API, поэтому я полагаю, что я не могу увидеть исходный код для него, или я могу? – Naveen

+1

Ну, на самом деле вы можете. Например, с помощью .NET Reflector или другого подобного инструмента. Но прежде чем исследовать этот источник - убедитесь, что это точно 'job.Delete' генерирует исключение, а не некоторую строку раньше (возможно, часть' site.WebApplication.JobDefinitions'?). Для меня очень маловероятно, что какой-то метод Microsoft API будет генерировать исключение NullReferenceException без какой-либо заметной причины. –

ответ

0

Чтобы удалить использование задания PowerShell:

$jobToDelete = Get-SPTimerJob -WebApplication "http://intranet" -Identity "YourJobName" 
$jobToDelete.Delete() 

затем запустить:

iisreset /noforce 

В базе данных конфигурации необходимо предоставить те разрешение на удаление:

use [Sharepoint_Config] 
GO 
GRANT EXECUTE ON [dbo].[proc_putObjectTVP] TO [WSS_Content_Application_Pools] 
GRANT EXECUTE ON [dbo].[proc_putObject] TO [WSS_Content_Application_Pools] 
GRANT EXECUTE ON [dbo].[proc_putDependency] TO [WSS_Content_Application_Pools] 
GRANT EXECUTE ON [dbo].[proc_putClass] TO [WSS_Content_Application_Pools] 
GRANT EXECUTE ON [dbo].[proc_getNewObjects] TO [WSS_Content_Application_Pools] 
GRANT EXECUTE ON [dbo].[proc_dropObject] TO [WSS_Content_Application_Pools] 
GO