使用STA线程修改SharePoint页面时检测到DisconnectedContext
本文关键字:检测 DisconnectedContext STA 线程 修改 SharePoint 使用 | 更新日期: 2023-09-27 18:07:04
背景信息:我在SharePoint 2010中使用ItemCheckedIn接收器,目标是。net 3.5框架。接收方的目标是:
- 确保页面的属性(列)与页面上的内容编辑器web部件中的数据匹配,以便在使用过滤器web部件的搜索中找到该页面。这些页面是自动生成的,所以除非出现任何错误,它们都保证符合预期的格式。
- 如果存在不匹配,检查页面,修复属性,然后将其检入。
我已经让接收者避免陷入无限的签入/签出循环,尽管现在这是一个非常笨拙的修复,我正在努力工作。然而,现在我不能对它工作,因为每当我点击UpdatePage函数时,我都会得到DisconnectedContext错误:
public override void ItemCheckedIn(SPItemEventProperties properties)
{
// If the main page or machine information is being checked in, do nothing
if (properties.AfterUrl.Contains("home") || properties.AfterUrl.Contains("machines")) return;
// Otherwise make sure that the page properties reflect any changes that may have been made
using (SPSite site = new SPSite("http://san1web.net.jbtc.com/sites/depts/VPC/"))
using (SPWeb web = site.OpenWeb())
{
SPFile page = web.GetFile(properties.AfterUrl);
// Make sure the event receiver doesn't get called infinitely by checking version history
...
UpdatePage(page);
}
}
private static void UpdatePage(SPFile page)
{
bool checkOut = false;
var th = new Thread(() =>
{
using (WebBrowser wb = new WebBrowser())
using (SPLimitedWebPartManager manager = page.GetLimitedWebPartManager(PersonalizationScope.Shared))
{
// Get web part's contents into HtmlDocument
ContentEditorWebPart cewp = (ContentEditorWebPart)manager.WebParts[0];
HtmlDocument htmlDoc;
wb.Navigate("about:blank");
htmlDoc = wb.Document;
htmlDoc.OpenNew(true);
htmlDoc.Write(cewp.Content.InnerText);
foreach (var prop in props)
{
// Check that each property matches the information on the page
string element;
try
{
element = htmlDoc.GetElementById(prop).InnerText;
}
catch (NullReferenceException)
{
break;
}
if (!element.Equals(page.GetProperty(prop).ToString()))
{
if (!prop.Contains("Request"))
{
checkOut = true;
break;
}
else if (!element.Equals(page.GetProperty(prop).ToString().Split(' ')[0]))
{
checkOut = true;
break;
}
}
}
if (!checkOut) return;
// If there was a mismatch, check the page out and fix the properties
page.CheckOut();
foreach (var prop in props)
{
page.SetProperty(prop, htmlDoc.GetElementById(prop).InnerText);
page.Item[prop] = htmlDoc.GetElementById(prop).InnerText;
try
{
page.Update();
}
catch
{
page.SetProperty(prop, Convert.ToDateTime(htmlDoc.GetElementById(prop).InnerText).AddDays(1));
page.Item[prop] = Convert.ToDateTime(htmlDoc.GetElementById(prop).InnerText).AddDays(1);
page.Update();
}
}
page.CheckIn("");
}
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
据我所知,在这个版本的。net中,使用WebBrowser是填充HtmlDocument的唯一方法,所以这就是为什么我必须使用这个线程。
此外,我已经做了一些阅读,看起来DisconnectedContext错误与线程和COM有关,这是我几乎一无所知的主题。我能做些什么来防止/修复这个错误?
编辑
@Yevgeniy。Chernobrivets在评论中指出,我可以插入一个绑定到页面列的可编辑字段,而不用担心解析任何html,但由于当前页面布局在Content Editor WebPart中使用html表,因此这种字段无法正常工作,我需要创建一个新的页面布局并从下往上重新构建我的解决方案,这是我真的宁愿避免的。
我也想避免下载任何东西,因为我工作的公司通常不允许使用未经批准的软件。
你不应该用WebBrowser类做html解析,这是Windows窗体的一部分,不适合web以及纯html解析。尝试使用一些html解析器,如htmllagilitypack。