1

昇格された権限で実行する2つのアプローチのうち、どちらが優先されますか?

最初のアプローチ:

SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite curSite = new SPSite(SPContext.Current.Site.ID))
                    {
                        using (SPWeb web = curSite.OpenWeb(SPContext.Current.Web.ID))
                        {
                            try
                            {
                                web.AllowUnsafeUpdates = true;
                                \\ do your stuff
                            }
                            catch (Exception e)
                            {

                            }
                            finally
                            {
                                web.AllowUnsafeUpdates = false;
                                web.Dispose();
                            }
                        }
                    }
                });

2 番目のアプローチ:

SPSite oSite = SPContext.Current.Site;
SPWeb oWeb = SPContext.Current.Web;
SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite curSite = new SPSite(oSite.ID))
                    {
                        using (SPWeb web = curSite.OpenWeb(oWeb.ID))
                        {
                            try
                            {
                                web.AllowUnsafeUpdates = true;
                                \\ do your stuff
                            }
                            catch (Exception e)
                            {

                            }
                            finally
                            {
                                web.AllowUnsafeUpdates = false;
                                web.Dispose();
                                oWeb.Dispose();
                                oSite.Dispose();
                            }
                        }
                    }
                });

「更新中のウェブは外部プロセスによって変更されました」という例外をスローする疑いがありますか?

4

2 に答える 2

6

まず 、コードを昇格させる前にSPWeb.ValidateFormDigest()orを呼び出す必要があります。SPUtility.ValidateFormDigest()これにより、GET リクエストで許可されていない安全でない更新が取り除かれ、AllowUnsafeUpdate プロパティを設定する必要がなくなります。

次に、Nigel Whatling が述べたように、2 番目のコードでコンテキスト オブジェクトを破棄しています。それらを処分する必要はありません。簡単にするために、自分でインスタンス化するオブジェクトのみを破棄します。あなたのようなコードは、他の SharePoint コンポーネントが SPContext.Current.XX オブジェクトへのアクセスを必要とする場合があるため、副作用を引き起こす可能性があります。これはおそらくあなたの問題の根本です。

第 3 に、using コンストラクトを使用しているため、using ヘッダーで設定した変数に対して .Dispose() を呼び出す必要はありません。実際、using コンストラクトの役割 (および実際の利点) は、オブジェクトを破棄する必要がないことです。ブロック コードが終了するとすぐに、例外が発生した場合でも、オブジェクトに対して .Dispose() メソッドが呼び出されます。

結論として、コードを次のように変更する必要があります。

SPUtility.ValidateFormDigest();
SPSecurity.RunWithElevatedPrivileges(delegate()
{
    using (SPSite curSite = new SPSite(SPContext.Current.Site.ID))
    {
        using (SPWeb web = curSite.OpenWeb(SPContext.Current.Web.ID))
        {
              // Do stuff here
        }
    }
});

補足: コードを昇格させるには、2 つのオプションがあります。ここで使用するもの ( を呼び出すSPSecurity.RunWithElevatedPrivileges) または SystemAccount トークンを使用して新しい SPSite をインスタンス化するもの:

using (SPSite curSite = new SPSite(
    SPContext.Current.Site.ID, 
    SPContext.Current.Site.SystemAccount.UserToken
))
{
    using (SPWeb web = curSite.OpenWeb(SPContext.Current.Web.ID))
    {
          // Do stuff here
    }
}

これにより、昇格したコードを Web アプリケーションの外部で実行できます。

また、ユーティリティ コードを使用して、このような操作をより機能的な方法でラップすることも検討する必要があります。私はこのようなコードを使用することに慣れています:

public static void RunWithElevatedPrivileges(this SPWeb web, Action<SPSite, SPWeb> codeToRunElevated)
{
    if (CheckIfElevated(web))
    {
        codeToRunElevated(web.Site, web);
    }
    else
    {
        using (var elevatedSite = new SPSite(web.Site.ID, web.AllUsers["SHAREPOINT\\system"].UserToken))
        {
            using (var elevatedWeb = elevatedSite.OpenWeb(web.ID))
            {
                codeToRunElevated(elevatedSite, elevatedWeb);
            }
        }
    }
}

/// <summary>
/// Indicates whether the context has been elevated
/// </summary>
public static bool CheckIfElevated(SPWeb web)
{
    return web.CurrentUser.LoginName == "SHAREPOINT\\system";
}

このようなコードを使用すると、コードのどこかで簡単に実行できます。

SPContext.Current.Web.RunWithElevatedPrivileges((elevatedSite, elevatedWeb)=>{
     // do something will all privileges
});
于 2012-07-24T12:16:01.707 に答える
1

どちらのアプローチもほぼ同じです。2 番目のアプローチを除いて、現在のコンテキストの SPWeb および SPSite オブジェクトも破棄します。これは、行うべきではありません。例外は web.Update() 呼び出しでスローされますか? 問題は ' do your stuff ' コードのどこかにありますか?

于 2012-07-24T11:37:38.633 に答える