c# - 在 ASMX Web 服务中使用 Server.Execute() 呈现 UserControl 的问题

标签 c# asp.net user-controls asmx

谁能解释为什么 Server.Execute() 要求我呈现的 UserControls 包含 <form>标签(或者,我做错了什么让 Server.Execute() 在我的 UserControls 中需要表单标签)?

我创建了一个 ASMX 服务来通过 JQuery+JSON 动态加载 UserControls,如下所示:

控制服务.asmx

<%@ WebService Language="C#" CodeBehind="ControlService.asmx.cs" Class="ManagementConcepts.WebServices.ControlService" %>

控制服务.cs

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class ControlService : System.Web.Services.WebService
{
    private string GetControl(String controlName, String ClassId)
    {
        Page page = new Page();
        UserControl ctl = (UserControl)page.LoadControl(controlName);

        page.Controls.Add(ctl);
        StringWriter writer = new StringWriter();
        HttpContext.Current.Server.Execute(page, writer, false);
        return writer.ToString();
    }
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public string GetSimpleControl(string ClassId)
    {
        return GetControl("SimpleControl.ascx", ClassId);
    }
}

我通过以下 JQuery 将控件加载到页面中,它将 ID ContentPlaceholder 替换为从服务返回的 HTML:

JQueryControlLoadExample.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="JQueryControlLoadExample.aspx.cs" Inherits="ControlService_Prototype._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>ControlService Prototype</title>
</head>
<body>
    <form id="theForm" runat="server" action="JQueryControlLoadExample.aspx">
        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" >
            <Scripts>
                <asp:ScriptReference NotifyScriptLoaded="true" Path="~/Scripts/jquery-1.3.2.js" />
            </Scripts>
        </asp:ScriptManager>
        <div>
        <asp:HiddenField runat="server" ID="hdncourse"/>
        <asp:HiddenField runat="server" ID="hdnTargetContent" Value="GetSimpleControl"/>
        <div runat="server" id="ContentPlaceholder" class="loading"></div>
        </div>
        <script type="text/javascript">
            $(document).ready(function() {
                var servicemethod = document.getElementById("hdnTargetContent").value;
                $.ajax({
                type: "POST",
                    url: "ControlService.asmx/" + servicemethod,
                    data: "{'ClassId':'"+document.getElementById("hdncourse").value+"'}",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function(msg) {
                        $('#ContentPlaceholder').html(msg.d);
                    }
                });
            });
        </script>
    </form>
</body>
</html>

这有一个巨大的警告。如果我没有在 .ascx 控件的标记内定义表单,则 HttpContext.Current.Server.Execute() 会抛出一个 HttpException 并显示以下消息:

Control 'hdnspecialoffer' of type 'HiddenField' must be placed inside a form tag with runat=server.

简单控件.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SimpleControl.ascx.cs" Inherits="ControlService_Prototype.UserControls.SimpleControl" %>
    <asp:HiddenField runat="server" ID="hdnspecialoffer"/>

当我将表单标签添加到 ascx 控件以解决此问题时,表单会呈现,但呈现器会重写控件中的表单标签,以便它 POST 回 ASMX 服务而不是 aspx 中定义的表单页面。

我四处搜索并发现了 Scott Guthrie 的出色 ViewManager例子。我看不出与他在那里所做的有任何根本的不同,这让我相信我正在做的事情应该奏效。

最佳答案

看起来答案隐藏在 ViewManager 的评论中

您需要一个继承自 Page 的类并覆盖对不在表单中的服务器控件的检查

public class FormlessPage : Page
{
    public override void VerifyRenderingInServerForm(Control control)
    {
    }
}

然后当你渲染控件时,使用

Page page = new FormlessPage();
UserControl ctl = (UserControl)page.LoadControl(controlName);
//etc

我假设您将失去从以这种方式呈现的任何控件触发事件的能力。

关于c# - 在 ASMX Web 服务中使用 Server.Execute() 呈现 UserControl 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/976524/

相关文章:

c# - 同时使用 Readline() 和 ReadKey()

ASP.NET MVC 2 - 成员资格提供程序 - ValidateUser() - 返回登录错误消息

.net - WinForm 用户控件 - 拖放

c# - 代码覆盖 xml 生成错误

c# - ASP MVC 即使未提供任何参数也创建参数模型

c# - 如何从 ASP.NET Web API ValueProvider 中的 HTTP POST 请求检索正文值?

asp.net - IronPython 和 ASP.NET

class - VBA 隐藏用户表单但保留输入的数据

WPF 控件设计指南 - 时间线

c# - 动画状态..无法播放是因为找不到?