为什么RunWithElevatedPrivileges无法执行?

时间:2009-03-12 12:00:56

标签: sharepoint web-parts

我正在尝试创建一个用户注释并将其存储在自定义列表中的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 个答案:

答案 0 :(得分:4)

你看到了很多问题:

  1. SPSite对象权限在创建时确定,因此即使您在SPContext.Current.Site中获得引用,RWEP也将拥有当前用户的权限。
  2. 不支持将SP对象从RWEP块中传出,并且通常很危险。如果您确实需要使用RWEP,则应在{1}}中使用并处置在该上下文中创建的所有SPSiteSPWeb个对象(及其子项)。
  3. 每次调用CodeToRunElevated都会创建一个新的listCollection[listGuid]对象,这可能会导致意外行为。
  4. 正如丹所说,RWEP并不是你想要完成的首选方法。使用他引用的link的扩展名,我会重写看起来像这样:

    SPList

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

嗯。在匿名委托中运行大部分代码可能更容易吗?

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

创建SPList对象可能更好,而不是重复访问该集合。有些收藏品表现得有些奇怪 - 我认为每次通过guid / index访问时,SPViewCollection都会创建一个新对象!

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