3

我正在尝试制作一个 greps 用户评论并将其存储在自定义列表中的 Web 部件,我编写了此代码以在 Web 部件添加到页面后将列表添加到站点,

[Guid("c314a0e8-0210-4064-b79e-bfd3594c6083")]
public class CommentWriteSpace : System.Web.UI.WebControls.WebParts.WebPart
{
    SPSite site = null;
    SPWeb web = null;

    public CommentWriteSpace()
    {
        SPSecurity.CodeToRunElevated foo = new SPSecurity.CodeToRunElevated(doit);

        SPSecurity.RunWithElevatedPrivileges(foo);
        SPListCollection listCollection = web.Lists;

        Guid listGuid = listCollection.Add("Comments List", "A list of user comments", SPListTemplateType.GenericList);
        listCollection[listGuid].Fields.Add("User", SPFieldType.User, true);
        listCollection[listGuid].Fields.Add("Comment", SPFieldType.Text, true);
        listCollection[listGuid].OnQuickLaunch = true;
        listCollection[listGuid].Update();
        //this.Page.Request.Url.ToString()
    }

    public void doit()
    {
        site = SPContext.Current.Site;
        web = site.OpenWeb();
    }
}

但是该方法抛出异常,我猜是权限问题,该异常与在没有提升权限的情况下RunWithElevatedPrivileges执行方法时出现的异常相同。site.OpenWeb();

可能是什么问题呢?

4

4 回答 4

4

您会看到许多问题:

  1. SPSite对象权限是在创建时确定的,因此SPContext.Current.Site即使您在RWEP.
  2. 将 SP 对象从块中传递出去RWEP是不受支持的并且通常很危险。如果您确实需要使用 RWEP,那么在该上下文中创建的所有对象(及其子对象)都应该SPSite在.SPWebCodeToRunElevated
  3. 每次调用listCollection[listGuid]都会创建一个新SPList对象,这可能会导致意外行为。

正如 Dan 所建议的那样,RWEP 不是您想要完成的工作的首选方法。使用他引用的链接中的扩展名,我将重写为如下所示:

[Guid("c314a0e8-0210-4064-b79e-bfd3594c6083")]
public class CommentWriteSpace : System.Web.UI.WebControls.WebParts.WebPart
{
    public CommentWriteSpace()
    {
        SPContext.Current.Site.RunAsSystem(UpdateSite);
        //this.Page.Request.Url.ToString()
    }

    public void UpdateSite(SPSite site)
    {
        SPWeb web = site.RootWeb;

        SPListCollection listCollection = web.Lists;
        Guid listGuid = listCollection.Add("Comments List", "A list of user comments", SPListTemplateType.GenericList);
        SPList list = listCollection[listGuid];

        list.Fields.Add("User", SPFieldType.User, true);
        list.Fields.Add("Comment", SPFieldType.Text, true);
        list.OnQuickLaunch = true;
        list.Update();
    }
}
于 2009-03-12T22:45:17.397 回答
2

您无需以提升的权限运行 SPContext.Current.Site。事实上,我认为这就是你得到例外的原因。此外,您还可以使用 SPContext.Current.Web 代替 site.OpenWeb()。后者创建一个新的 SPWeb 对象,您将负责再次处理该对象。当 HTTP 请求完成时,会自动释放来自 SPContext 的 SPSite 和 SPWeb 对象。

于 2009-03-12T17:38:53.233 回答
1

我建议在与 SharePoint 对象交互时避免使用 RunWithElevatedPrivileges(只要可能,就像在您的示例中一样)。您应该将其使用限制在需要访问 SharePoint 外部资源(例如数据库、文件共享等)时才使用。

这是一篇优秀的文章,它提供了一种在 SharePoint 上下文中获得提升权限的非常优雅的方法:http: //solutionizing.net/2009/01/06/elegant-spsite-elevation/

于 2009-03-12T18:20:55.503 回答
0

唔。在匿名委托中运行大部分代码会更容易吗?

SPSecurity.RunWithElevatedPrivileges(delegate()
{
  // Your code here
}

最好创建一个 SPList 对象,而不是重复访问该集合。其中一些集合的行为有点奇怪 - 我认为它是 SPViewCollection 每次您通过 guid/index 访问它时都会创建一个新对象!

所有这些问题,我同意 Lars - 使用 SPContext.Current.Web

于 2009-03-12T17:49:41.680 回答