动态创建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函数的工作方式)
答案 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();