2009-06-16 38 views
1

創建用戶控件我引用article referenceAsp.net錯誤從的WebMethod

要動態創建一個用戶控件,並通過jQuery傳回的頁面。

當我在UserControl「Hello World」中做一個簡單的文本時,一切都很好......但是,當我嘗試在控件上放置交互控件時,我的WebMethod中收到以下消息(所以jQuery調用了一些東西是無關緊要的)(進一步的測試表明,文本框和按鈕造成的問題,而不是標籤)

錯誤執行的處理子請求「System.Web.UI.Page」

這裏將WebMethod:

[WebMethod] 
public static string GetCtrl(string cname) 
{ 
    StringWriter sw = new StringWriter(); 

    Page p = new Page(); 
    Control c = p.LoadControl("~/Controls/" + cname); 
    p.Controls.Add(c); 

    try 
    { 
     HttpContext.Current.Server.Execute(p, sw, false); 
    } 
    catch (Exception err) 
    { 
     return err.Message; 
    } 
    sw.Close(); 

    return sw.ToString(); 
} 

該excep在Server.Execute調用期間正在發生。

解決方案可能不可行,我只想知道爲什麼交互式控件會導致這種情況。

編輯: 以低於我的建議看起來更深,發現內部異常說事,它必須是標有RUNAT =「服務器」表單標籤內的效果,而我顯示aspx頁面上的這個控制在表單標籤內...我的猜測是,必須有某種'asp.net魔術'連接才能讓控件操作...無論如何,很高興知道如何使用控件呈現頁面它無論如何(即使它不是在這種情況下可用)

所以,我看着上面的代碼的輸出,併爲那些好奇:

<span id="ctl00_lbl1">abc: </span>

因此,控件在頁面上正確呈現(只有標籤id ='lbl1'),但是,控件本身呈現,並且頁面內容根本就不存在......是否有辦法生成頁面源代碼? (我不能明白使用Server.Execute功能的工作方式)

+0

經過一個建議,我在調試信息檢查更深,並發現了以下內部異常: 內的異常情況如下(略比我以前有更多的幫助):控制「ctl00_btn1」類型'Button'必須放置在runat = server的form標籤中。 因爲這是在一個頁面對象上呈現的......我想知道是否有一些「前期工作」,我需要做的是使頁面成爲一個合適的aspx頁面......因爲我基本上是動態地構建它(我們甚至不會談論在另一個頁面上嵌入整個事件的不當性) – 2009-06-16 17:08:11

回答

3

我想通過縮小的問題開始。舉例來說,如果你離開關

p.Controls.Add(c); 

,如果你正確地實現一個using聲明中會發生什麼,會發生什麼?

using (StringWriter sw = new StringWriter()) { 
    // ... 
    HttpContext.Current.Server.Execute(p, sw, false); 
    return sw.ToString(); 
} 

如果您離開try/catch,會發生什麼?除了Message屬性之外,它會將所有信息花費在異常中,所以爲什麼不把它關閉呢?呼叫方可能在任何情況下期待HTML,所以如果你保留它,你可能會(後下)要換行輸出:

return "<p>" + ex.ToString() + "</p>"; 

漸漸地,取出的東西,直到問題消失。


根據你來自的InnerException獲悉,我建議你添加一個HtmlForm控件的頁面,然後添加您加載控件作爲HtmlForm控件的子控件。

0

我會嘗試渲染控制和發送該字符串回來......

Control ctrl; 
StringBuilder sb = new StringBuilder(); 
StringWriter tw = new StringWriter(sb); 
HtmlTextWriter hw = new HtmlTextWriter(tw); 

ctrl.RenderControl(hw); 
return sb.ToString(); 
+0

@George,你是否也實現了使用語句,考慮到你創建的大多數對象實現IDisposable? – 2009-06-16 12:43:35

+0

使用RenderControl方法的好主意,不幸的是,這不會導致控件通過頁面生命週期(因此,例如Page_Load事件不會被調用) – 2009-06-16 16:58:51

1

Using Scott Gu's blog as a reference,我也遇到了同樣的問題,我的公司的儀表板中的加載服務器控件(例如GridView和RadTreeView控件會導致相同的錯誤)。按照John Saunders的提示,我添加了一個HTML表單控件和腳本管理器控件(用於RadTreeView控件),並解決了問題。現在我的用戶控件呈現爲純HTML。 w00t!

[WebMethod] 
public static string[] LoadWidget(string widgetID, string widgetPath) 
{ 
    try 
    { 
     var pageHolder = new Page(); 
     var form = new HtmlForm(); 
     var viewControl = (UserControl)pageHolder.LoadControl(widgetPath); 
     var scriptManager = new ScriptManager(); 
     form.Controls.Add(scriptManager); 
     form.Controls.Add(viewControl); 
     pageHolder.Controls.Add(form); 

     var output = new StringWriter(); 
     HttpContext.Current.Server.Execute(pageHolder, output, false); 

     return new string[] 
     { 
      widgetID, output.ToString() 
     }; 
    } 
    catch (Exception e) 
    { 
     // handle error... 
    } 
}