在SharePoint计时器作业中创建发布页面会抛出MissingMethodException

时间:2010-09-21 14:43:46

标签: c# sharepoint sharepoint-2007 moss timer-jobs

我正在使用每隔几分钟运行一次的计时器作业为sharepoint站点做一个简单的新闻导入程序。如果我在Web部件中运行它,但在以计时器作业的Execute方法运行时抛出MissingMethodException,则下面的代码运行正常。

完整的例外:

System.MissingMethodException was unhandled by user code
  Message="No parameterless constructor defined for this object."
  Source="mscorlib"
  StackTrace:
       at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)
       at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache)
       at System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache)
       at System.Activator.CreateInstance(Type type, Boolean nonPublic)
       at System.Activator.CreateInstance(Type type)
       at Microsoft.SharePoint.WebPartPages.SPWebPartSerializer.get_DefaultControl()
       at Microsoft.SharePoint.WebPartPages.BinaryWebPartSerializer.Serialize(PersonalizationScope scope)
       at Microsoft.SharePoint.WebPartPages.BinaryWebPartSerializer.get_Links()
       at Microsoft.SharePoint.WebPartPages.SPWebPartManager.AddWebPartToStore(WebPart webPart, Int32 viewId, String viewGuid)
       at Microsoft.SharePoint.WebPartPages.SPWebPartManager.AddWebPartInternal(SPSupersetWebPart superset, Boolean throwIfLocked)
       at Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager.AddWebPartInternal(WebPart webPart, String zoneId, Int32 zoneIndex, Boolean throwIfLocked)
       at Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager.AddWebPart(WebPart webPart, String zoneId, Int32 zoneIndex)
       at Microsoft.SharePoint.Publishing.PublishingPage.CopyAllWebParts(String destinationPageUrlServerRelative, SPWeb destinationPageWeb, String sourcePageUrlServerRelative, SPWeb sourcePageWeb, Boolean shouldOverwriteDestinationWebParts)
       at Microsoft.SharePoint.Publishing.PublishingPageCollection.<>c__DisplayClass5.<Add>b__0()
       at Microsoft.Office.Server.Diagnostics.FirstChanceHandler.ExceptionFilter(Boolean fRethrowException, TryBlock tryBlock, FilterBlock filter, CatchBlock catchBlock, FinallyBlock finallyBlock)
       at Microsoft.Office.Server.Diagnostics.ULS.SendWatsonOnExceptionTag(ULSTagID tagID, ULSCat categoryID, String output, Boolean fRethrowException, TryBlock tryBlock, CatchBlock catchBlock, FinallyBlock finallyBlock)
       at Microsoft.SharePoint.Publishing.PublishingPageCollection.Add(String name, PageLayout layout)
       at Virtua.SharePoint.Mercator.NewsImportJob.Execute(Guid contentDbId)
       at Microsoft.SharePoint.Administration.SPTimerJobInvoke.Invoke(TimerJobExecuteData& data, Int32& result)
  InnerException: 

代码:

var SPWebUri = new Uri("http://.../News/");
using (SPSite site = new SPSite(SPWebUri.AbsoluteUri))
{
    using (SPWeb web = site.OpenWeb(SPWebUri.AbsolutePath)) // tried 0x29A's anwser, but it didn't work
    // using (SPWeb web = site.OpenWeb())
    {
        web.AllowUnsafeUpdates = true;

        PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);
        SPContentTypeId contentTypeId = new SPContentTypeId("...");

        PageLayout layout = publishingWeb.GetAvailablePageLayouts(contentTypeId).First(l => l.Name == "....aspx");
        PublishingPageCollection pages = publishingWeb.GetPublishingPages();

        var spFilename = "testing";

        // error line below
        var newPage = pages.Add(String.Format("{0}.aspx", spFilename), layout);

        // set newPage's fields

        // check-in and publish page
    }
}

2 个答案:

答案 0 :(得分:1)

不确定但是可能需要为site.OpenWeb()提供url参数如果url参数为空,则必须打开顶级站点。这可以解释为什么它可以在Web部件中工作,但不能在计时器工作中工作。有关详细信息,请参阅MSDN - Site.OpenWeb Method

此致

答案 1 :(得分:0)

问题是我的页面布局上有错误的Web部件。我在构造函数中使用SPContext.Current...。现在,显然,SPContext在执行计时器作业代码时并不存在(不是那么令人惊讶)。

由于未处理错误,因此Web部件经理尝试用ErrorWebPart(通常告诉用户出错的那个)替换我的部分。出于某种原因,这在浏览器中显示页面时工作正常。但是在计时器作业中,SharePoint尝试使用无参数构造函数通过反射创建ErrorWebPart未在ErrorWebPart中定义,整个事情就会崩溃MissingMethodException

将违规代码移至CreateChildControls方法(我有错误处理)解决了这个问题。