部署步骤发生错误'撤回解决方案';不能反序列化,因为它没有公共默认构造函数

本文关键字:因为 构造函数 默认 反序列化 解决方案 错误 部署 不能 | 更新日期: 2023-09-27 18:18:00

我以本教程为例创建一个计时器作业。

这是我的定时器工作代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
namespace CalcAnnualConsumptionTotals
{
    public class GroupAnnualConsumption : SPJobDefinition
    {
        public GroupAnnualConsumption() : base() {} // <-- public default constructor
        public GroupAnnualConsumption(string jobName, SPService service, 
               SPServer server, SPJobLockType lockType)
               : base(jobName, service, server, lockType)
        {
            this.Title = "Group Annual Consumption";
        }
        public GroupAnnualConsumption(string jobName, SPWebApplication webapp)
            : base(jobName, webapp, null, SPJobLockType.ContentDatabase)
        {
            this.Title = "Group Annual Consumption";
        }
        public override void Execute(Guid targetInstanceId)
        {
            .....
        }
    }
}

你可以看到我有默认的公共构造函数但是当我试图部署它时它显示了错误:

在部署步骤"撤回解决方案"中发生错误:CalcAnnualConsumptionTotals。GroupAnnualConsumption不能为反序列化,因为它没有公共默认构造函数

当我第一次得到这个错误时,我有实际上忘记添加默认构造函数。但即使在添加之后,它还是显示了错误。我认为我最初的尝试会部分成功,从而导致部署。但是我甚至通过中央管理或Get-SPTimerJob都找不到。

知道为什么会出现这个错误吗

部署步骤发生错误'撤回解决方案';不能反序列化,因为它没有公共默认构造函数

问题就在这里。正如我在问题中已经提到的

…当我第一次得到这个错误时,我实际上忘记了添加默认构造函数....

所以发生的事情是,解决方案被部署在SharePoint上,但错误也是第一次出现(不能回忆是否相同的错误)。下次当我纠正错误并尝试部署时,它显示了错误:

在部署步骤'撤回解决方案'中发生错误:CalcAnnualConsumptionTotals。GroupAnnualConsumption不能为反序列化,因为它没有公共默认构造函数

Retract Solution是这里的关键字。当SharePoint试图部署更新的解决方案时,由于(旧)解决方案中的错误,它不得不撤回旧的解决方案。

所以我去Central Administration中的Manage Farm Solutions并删除解决方案。然后当我部署时,它工作了。

上面的方法对我不起作用,但我确实找到了一个解决方案,并想把它贴在这里,以防其他人遇到同样的情况。

在我的情况下,我不能卸载通过管理农场解决方案页面,至少,不是最初。

我必须首先通过添加默认构造函数来修复代码。然后我必须使用gacutil GAC文件。然后使用iisreset/restart重置IIS。只有这样,我才能在"管理农场解决方案"页面中请求撤回解决方案。

不幸的是,它只是坐在那里。所以,为了解决这个问题,我做了:

  1. stsadm -o enumdeployment
  2. stsadm -o canceldeployment -id "步骤1中显示的guid值"
  3. 通过powershell: remove-spsolution -Identity解决方案名称。wsp force
  4. iisreset/restart(您可能会在重新部署期间得到一个错误,解决方案仍然安装,除非您手动反弹iis)

然后我可以重新部署并重新开始工作。

从这里:

您还需要调用web服务关联构造函数或来自的服务应用程序关联构造函数计时器作业定义的构造函数之一。记住,计时器作业必须与这两个实体之一相关联。唯一一次类上的构造函数可以创建关联SPJobDefinition类,因此您的一个构造函数必须是与对适当基构造函数的下调用相关联。

似乎需要从默认构造函数中设置这两个属性中的一个。如果您可以将值传递给其他构造函数之一,则会更简单。

Edit:澄清一下,我认为将jobname参数传递给基构造函数就足够了。如果你无法访问该值(它是硬编码的,还是在配置文件中?),你可能不得不重新构建东西。

也就是说,我从来没有使用过Sharepoint,所以我可能会偏离基础。

看起来SharePoint Job的"旧版本"还在运行。

部署SharePoint Job时,需要重新启动SharePoint Timer服务。

如何通过PowerShell重新启动SharePoint Timer服务

function Restart-SPTimerV4()
{
  [array]$servers= Get-SPServer | ? {$_.Role -eq "Application"}            
  $farm = Get-SPFarm            
  foreach ($server in $servers)            
  {            
     Write-Host "Restarting Timer Job on $server"                                      
     $Service = Get-WmiObject -Computer $server.name Win32_Service -Filter "Name='SPTimerV4'"                        
     if ($Service -ne $null)                         
     {                             
        $Service.InvokeMethod('StopService',$null)            
        Start-Sleep -s 7            
        $service.InvokeMethod('StartService',$null)                             
        Start-Sleep -s 7            
        Write-Host "Timer Job successfully restarted on $server"                        
     }             
     else            
     {            
        write-host -ForegroundColor Yellow "Could not find SharePoint 2010 Timer Service on $server"            
     }            
  }
}