2011-05-01 71 views
0

背景:我创建了一个自定义的HttpHandler,它根据用户发布的参数执行特定的命令。由于JQuery Ajax在我的网站中大量使用,我采用了内容页面方法,在该方法中,我执行一个aspx页面,其中包含用户正在查看的容器页面的内容。 截至目前我正在使用Godaddy共享主机,因为该网站还处于初级阶段,所以我不能去专用/虚拟服务器。PageParser.GetCompiledPageInstance抛出一个SecurityException - 如何解决这个问题?

一切工作正常在我的电脑上,但不是在服务器上。 我得到这个错误:

 
[SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' 
failed.] 
    System.Web.UI.PageParser.GetCompiledPageInstance(String virtualPath, String inputFile, HttpContext context) +46 
    SL.Controller.Commands.CommandHelper.ExecutePage(SLActionInfo actionInfo, String url) +95 
    SL.Controller.Commands.ProductCommand.Execute(SLActionInfo actionInfo) +32 
    SL.Controller.CommandFactory.ExecuteCommand(HttpContext context) +224 
    SL.Controller.DefaultHttpHandler.ProcessRequest(HttpContext context) +20 
    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181 
.... 

奇怪的事情:使用Server.Execute(字符串virtualUrl)工作,但PageParser.GetCompiledPageInstance不是。

为什么我使用PageParser.GetCompiledPageInstance而不是Server.Execute(字符串url)?因为下面的代码:

 
public static string ExecutePage(SLActionInfo actionInfo, string url) 
     { 
      var context = actionInfo.Context; 
         var sw = new System.IO.StringWriter(); 
      HtmlTextWriter htw = new HtmlTextWriter(sw); 
      IHttpHandler handler = PageParser.GetCompiledPageInstance(url, context.Server.MapPath(url), context); 
      if (handler is SL.UI.SLPageBase) 
       ((SL.UI.SLPageBase)handler).ActionInfo = actionInfo; 
      context.Server.Execute(handler, htw, true); 
      return sw.ToString(); 
     } 

由于我的内容页面从SLPageBase(页的子类)推导出有一个属性ActionInfo这需要在这ExecutePage方法进行设置,我使用PageParser方法。

我不知道如何摆脱这个错误,而不会破坏我的PageParser方法。

任何帮助将不胜感激。

回答

0

我已经为上述问题提出了解决方法。看来这个问题的读者还没有面对这个问题,因此不能提出一个可能的解决方案。由于使用共享主机的人可能会遇到此问题并可能寻找解决方案,因此他们可以利用此解决方法。

编辑:我决定不立即接受我的答案。我期待着对这个答案的评论,并会在几天内做出相应决定。

这打破了我的PageParser.GetCompiledPageInstance方法,但影响非常小,我可以在托管完全信任环境时轻松切换到原始方法。

的变化是在两个地方:

1)在ExecutePage方法:

public static string ExecutePage(SLActionInfo actionInfo, string url) 
{ 
    var context = actionInfo.Context; 
    var sw = new System.IO.StringWriter(); 
    HtmlTextWriter htw = new HtmlTextWriter(sw); 
    // The original approach is commented out. 
    // IHttpHandler handler = PageParser.GetCompiledPageInstance(url, context.Server.MapPath(url), context); 
    // if (handler is SL.UI.SLPageBase) 
    // ((SL.UI.SLPageBase)handler).ActionInfo = actionInfo; 
    // context.Server.Execute(handler, htw, true); 

    // The new approach: 
    // Add actionInfo to the Items collection so that any page executing in the context of this request can read it. 
    Context.Items.Add("SLActionInfo", actionInfo); 
    // Now execute the page by providing its url. 
    context.Server.Execute(url, htw, true); 

    return sw.ToString(); 
} 

2)另一个变化是SLPageBase.ActionInfo属性中:

public SLActionInfo ActionInfo 
{ 
    get 
    { 
     return (SLActionInfo)Context.Items["SLActionInfo"]; 
     // Commented out the old approach. 
     // return _actionInfo; 
    } 
} 

你可以看到,如果我想恢复到旧的(和最喜欢的)方法是多么容易。只要在这里注释几行,然后评论几行就可以做到。系统的其余部分将保持不受影响。

+0

正如MSDN所说,不要使用PageParser.GetCompiledPageInstance方法。改为测试'BuildManager.CreateInstanceFromVirtualPath'。 – 2011-05-09 12:49:47

+0

@Mehdi我没有意识到,有一些名为BuildManager.CreateInstanceFromVirtualPath。感谢它,我会尝试一下,看它是否在部分信任下的共享主机中工作。 – 2011-05-10 04:07:47