2011-05-01 67 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