沙箱环境是一种受限的执行环境,它允许程序仅访问特定的资源,并防止沙箱中发生的问题影响到服务器环境的其他部分。实时应用程序将在沙箱环境中托管和执行,但完全在沙箱执行范围内完成项目是不现实的。在许多情况下,可能需要创建文件、访问文件系统或以Farm Admin身份执行某些操作。
为了演示这种情况,创建了一个沙箱解决方案,其中包含一个简单的Web部件,该Web部件有一个简单的按钮。以下是Web部件的代码:
namespace SandboxTest.TestWebpart {
[ToolboxItemAttribute(false)]
public class TestWebpart : WebPart {
protected override void CreateChildControls() {
Button objBtn = new Button { Text = "Submit", ID = "btnSubmit" };
objBtn.Click += new EventHandler(btnSubmit_Click);
this.Controls.Add(objBtn);
}
protected void btnSubmit_Click(object sender, EventArgs e) {
((Button)sender).Text = FullTrustMethod("Pratap", 100);
}
protected string FullTrustMethod(string strParameter, int intParameter) {
string strReturnValue = "";
SPSecurity.RunWithElevatedPrivileges(delegate() {
strReturnValue = strReturnValue + "String Parameter = " + strParameter + "; Integer Parameter = " + intParameter.ToString();
});
return strReturnValue;
}
}
}
按钮点击事件将调用一个FullTrustMethod()方法,该方法以提升的权限执行代码,并在按钮上显示简单文本,如下所示。但如果尝试执行这段代码,将得到一个错误,提示在部分信任环境中尝试执行全信任代码。
这就是代理类发挥作用的地方。实现并注册代理以从沙箱解决方案执行全信任代码涉及几个步骤。
步骤1:创建一个单独的SharePoint解决方案,以农场解决方案模式运行。将把沙箱解决方案中的全信任代码移动到这个农场解决方案中。
步骤2:创建一个代理类,其中嵌入了全信任方法。代理类应该继承自SPProxyOperation基类。
namespace SandboxProxyTest {
public class ProxyFullTrustClass : SPProxyOperation {
public override object Execute(SPProxyOperationArgs args) {
var proxyargs = args as SandboxProxyArgs;
return FullTrustMethod(proxyargs.strParameter, proxyargs.intParameter);
}
protected string FullTrustMethod(string strParameter, int intParameter) {
string strReturnValue = "";
SPSecurity.RunWithElevatedPrivileges(delegate() {
strReturnValue = strReturnValue + "String Parameter = " + strParameter + "; Integer Parameter = " + intParameter.ToString();
});
return strReturnValue;
}
}
}
步骤3:创建一个类,列出特定全信任方法所需的所有参数。这个类应该继承自SPProxyOperationArgs基类。
namespace SandboxProxyTest {
[Serializable]
public class SandboxProxyArgs : SPProxyOperationArgs {
public string strParameter { get; set; }
public int intParameter { get; set; }
public static string ProxyOperationTypeName {
get { return "SandboxProxyTest.ProxyFullTrustMethod"; }
}
public static string ProxyAssemblyName {
get { return "SandboxProxyTest, Version=3.0.0.0, Culture=neutral, PublicKeyToken=104629d871066b35"; }
}
}
}
为代理操作类添加只读属性,包括类型名称和程序集名称。类型名称应该是完全限定的,程序集名称应该是程序集的四部分强名称。
步骤4:在AssemblyInfo.cs中进行一些更改。根据在ProxyAssemblyName属性中分配的值更改版本号。
[assembly: AssemblyVersion("3.0.0.0")]
[assembly: AssemblyFileVersion("3.0.0.0")]
[assembly: AllowPartiallyTrustedCallers]
添加以下属性,使程序集可以从沙箱解决方案调用。
步骤5:为农场解决方案添加一个功能和一个接收器。现在,需要使用UserCode服务注册代理操作和代理参数,以使代理方法对所有沙箱调用者可用。将使用功能激活方法来实现这一点。
[Guid("36d1494b-decd-45b9-bc6e-6ad06536f81a")]
public class SandboxProxyFeatureEventReceiver : SPFeatureReceiver {
public override void FeatureActivated(SPFeatureReceiverProperties properties) {
SPUserCodeService userCodeService = SPUserCodeService.Local;
var FullTrustOperation = new SPProxyOperationType(
SandboxProxyArgs.ProxyAssemblyName,
SandboxProxyArgs.ProxyOperationTypeName);
userCodeService.ProxyOperationTypes.Add(FullTrustOperation);
userCodeService.Update();
}
}
完成代理创建后,部署项目并激活添加的功能。仅作为验证,请转到GAC并验证程序集,其名称、文化、版本和公钥令牌详细信息是否在步骤3中正确提及。
步骤6:回到沙箱解决方案,注释掉webpart.cs类中的fulltrust方法。将代理解决方案的引用,即SandboxProxyTest.dll,添加到沙箱项目中。
现在修改btnSubmit_Click()方法,以调用注册的代理方法,而不是Full-Trust方法本身。
protected void btnSubmit_Click(object sender, EventArgs e) {
var proxyargs = new SandboxProxyTest.SandboxProxyArgs();
proxyargs.strParameter = "Pratap";
proxyargs.intParameter = 100;
var result = SPUtility.ExecuteRegisteredProxyOperation(SandboxProxyTest.SandboxProxyArgs.ProxyAssemblyName,
SandboxProxyTest.SandboxProxyArgs.ProxyOperationTypeName, proxyargs);
((Button)sender).Text = result.ToString();
}
部署沙箱项目并验证Web部件的按钮执行。
最终!使用代理从沙箱项目中执行了全信任代码(GAC部署)程序集。