Quelqu'un peut-il expliquer pourquoi Server.Execute() exige que mes UserControls rendus contiennent des balises <form>
(ou bien, ce que je fais de mal à faire le serveur. Execute() nécessite des balises de formulaire dans mes UserControls)?Problèmes de rendu UserControl à l'aide de Server.Execute() dans un service Web ASMX
j'ai créé un service ASMX pour charger dynamiquement UserControls via JQuery + JSON comme suit:
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);
}
}
je charge le contrôle en une page via le bit suivant de JQuery qui remplace a avec l'id ContentPlaceholder par le code HTML renvoyé par le service:
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>
Cela fonctionne avec une mise en garde énorme. Si je ne définit pas une forme à l'intérieur du balisage de contrôle .ascx puis HttpContext.Current.Server.Execute() renvoie une HttpException avec le message suivant:
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"/>
Lorsque j'ajoutais une balise de formulaire au contrôle ascx pour contourner ce problème, le formulaire restituait, mais le rendu réécritait la balise de formulaire dans le contrôle afin qu'il renvoie au service ASMX au lieu du formulaire défini dans la page ASPX.
J'ai fait un tour d'adresse et découvert l'excellent exemple ViewManager de Scott Guthrie. Je ne vois rien de fondamentalement différent de ce qu'il a fait là-bas, ce qui me porte à croire que ce que je fais doit fonctionner.
Je penche pour accepter cette réponse, car elle sonne vrai, mais je veux l'essayer d'abord (ce qui ne sera pas pour quelques jours). –