Asp.net从WebMethod创建usercontrol时出错

时间:2009-06-16 12:23:45

标签: asp.net user-controls

我引用了article reference

动态创建UserControl并通过jQuery将其传递回页面。

当我在UserControl“Hello World”中做一个简单的文本时,一切都很好......但是,当我尝试在控件上放置交互式控件时,我在WebMethod中得到以下消息(所以jQuery调用的东西是无关紧要)(进一步测试显示文本框和按钮导致问题,但不是标签)

执行处理程序'System.Web.UI.Page'

的子请求时出错

这是网络方法:

[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();
}

在Server.Execute调用期间发生异常。

解决方案可能无法实现,我只想知道为什么交互式控件会导致这种情况。

编辑: 根据下面的建议,我看得更深,发现内部异常表示它必须位于标记为runat =“server”的表单标记内,而我在表单标记内的aspx页面上显示此控件...我的猜测是,必须有某种“asp.net魔法”连接才能使控件运行......无论如何,知道如何渲染带有控件的页面总是很好(即使它在这种情况下无法使用)

所以我看了上面代码的输出和那些好奇的人:

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

因此,控件在页面上正确呈现(仅使用标签id ='lbl1'),但是,控件本身已呈现,页面内容根本不存在...有没有办法生成页面来源也是? (我不能理解Server.Execute函数的工作方式)

3 个答案:

答案 0 :(得分: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的子控件。

答案 1 :(得分: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...
    }
}

答案 2 :(得分:0)

我会尝试渲染控件并将该字符串发回...

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

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