Kann mir jemand erklären, warum Server.Execute() meine gerenderten UserControls benötigt, um <form>
Tags zu enthalten (oder alternativ, was ich falsch mache, was Server macht. Execute() erfordern Formular-Tags in meinen UserControls)?Probleme beim Rendern von UserControl mit Server.Execute() in einem ASMX-Webdienst
Ich habe eine ASMX Dienst erstellt dynamisch Benutzersteuerelemente über JQuery + JSON geladen werden, wie folgt:
ControlService.asmx
<%@ WebService Language="C#" CodeBehind="ControlService.asmx.cs" Class="ManagementConcepts.WebServices.ControlService" %>
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);
}
}
I die Steuerung laden eine Seite über das folgende Bit von JQuery, das ein mit dem ID ContentPlaceholder mit dem HTML ersetzt, das von dem Dienst zurückgegeben wird:
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>
Das funktioniert mit einem großen Nachteil. Wenn ich nicht eine Form innerhalb der ASCX Kontrolle Markup definieren dann HttpContext.Current.Server.Execute() löst eine Httpexception mit der folgenden Meldung:
Control 'hdnspecialoffer' of type 'HiddenField' must be placed inside a form tag with runat=server.
SimpleControl.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SimpleControl.ascx.cs" Inherits="ControlService_Prototype.UserControls.SimpleControl" %>
<asp:HiddenField runat="server" ID="hdnspecialoffer"/>
Wenn ich dem ascx-Steuerelement ein form-Tag hinzufügte, um dieses Problem zu umgehen, würde das Formular gerendert, aber der Renderer schreibt das form-Tag im Steuerelement neu, so dass es an den ASMX-Dienst zurückgesendet wird und nicht auf der ASPX-Seite.
Ich googelte herum und entdeckte Scott Guthries exzellentes ViewManager Beispiel. Ich sehe nichts grundsätzlich anders als das, was er dort getan hat, was mich zu der Überzeugung bringt, dass das, was ich tue, funktionieren sollte.
Ich neige dazu, diese Antwort zu akzeptieren, wie es wahr klingt, aber ich möchte es zuerst ausprobieren (was nicht für ein paar Tage sein wird). –