2010-04-28 4 views
1

J'essaie de prendre un groupe existant de code qui était précédemment sur une page .aspx complète, et faire la même chose dans un gestionnaire.Utilisation de la génération de code de contrôle serveur ASP.Net à partir de .ashx

Le code a créé un objet HtmlTable, ajouté des lignes et des cellules à ces lignes, puis ajouté que html table la collection de contrôles .aspx, puis l'a ajouté à un div qui était déjà sur la page. J'essaie de garder le code intact, mais au lieu de placer le contrôle dans un div, je génère le code HTML et je vais le retourner dans un gros morceau de texte qui peut être appelé via le client AJAX.

HtmlTable des erreurs lorsque j'essaie d'utiliser la propriété InnerHtml (dit qu'il n'est pas supporté), et quand j'essaye RenderControl, après avoir fait d'abord un TextWriter et ensuite un objet HtmlTextWriter, j'ai l'erreur que Page ne peut pas être nulle .

Quelqu'un at-il déjà fait cela? Aucune suggestion?

Répondre

2

* le plus récent est ci-dessus.

OK, même après la mise à jour de Matt, il existe une solution;)

Tout d'abord, nous devons utiliser une page avec form intérieur. Sinon, nous ne serons pas en mesure d'ajouter un contrôle ScriptManager. Encore une chose: le contrôle ScriptManager devrait être le premier contrôle dans le formulaire. En outre est plus facile:

Page page = new Page(); 
Button button = new System.Web.UI.WebControls.Button 
{ 
    ID = "btnSumbit", 
    Text = "TextButton", 
    UseSubmitBehavior = true 
}; 
HtmlForm form = new HtmlForm 
{ 
    ID="theForm" 
}; 
ScriptManager scriptManager = new ScriptManager 
{ 
    ID = "ajaxScriptManager" 
}; 
form.Controls.Add(scriptManager); 
form.Controls.Add(button); 
page.Controls.Add(form); 

using (StringWriter output = new StringWriter()) 
{ 
    HttpContext.Current.Server.Execute(page, output, false); 

    context.Response.ContentType = "text/plain"; 
    context.Response.Write(output.ToString()); 
} 

Cela fonctionne. La sortie est assez grande donc j'ai décidé de ne pas l'inclure dans ma réponse :)


En fait, il existe une solution de contournement. Oui, nous pouvons rendre un contrôle dans le gestionnaire.

Tout d'abord, nous avons besoin d'une page sans formulaire. Parce que sans cela, nous obtenons:

Control 'btnSumbit' de type 'bouton' doit être placé à l'intérieur d'une balise de formulaire avec runat = server.

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

Deuxièmement, personne ne peut nous empêcher de créer une instance de notre page FormlessPage. Et maintenant ajoutons un contrôle là (j'ai décidé d'ajouter un contrôle Button comme exemple, mais vous pouvez en utiliser un).

FormlessPage page = new FormlessPage(); 
Button button = new System.Web.UI.WebControls.Button 
{ 
    ID = "btnSumbit", 
    Text = "TextButton", 
    UseSubmitBehavior = true 
}; 
page.Controls.Add(button); 

Troisièmement, capturons la sortie. Pour cela, nous utilisons la méthode HttpServerUtility.Execute:

exécute le gestionnaire pour le chemin virtuel spécifié dans le contexte de la demande actuelle.A System.IO.TextWriter capture sortie à partir du gestionnaire exécuté et un paramètre booléen spécifie si les clair System.Web.HttpRequest.QueryString et System.Web.HttpRequest.Form collections.

Voici le code:

using (StringWriter output = new StringWriter()) 
{ 
    HttpContext.Current.Server.Execute(page, output, false); 

    context.Response.ContentType = "text/plain"; 
    context.Response.Write(output.ToString()); 
} 

Le résultat sera:

<input type="submit" name="btnSumbit" value="TextButton" id="btnSumbit" />

En plus je peux recommander l'article de ScottGu Tip/Trick: Cool UI Templating Technique to use with ASP.NET AJAX for non-UpdatePanel scenarios. J'espère, vous pourriez trouver beaucoup d'utile là-bas.

+0

Cela fonctionne très bien pour 90% de ce dont j'ai besoin, alors merci beaucoup pour cela. Cependant, j'ai 1 accroc gauche. Il y a des contrôles Telerik qui doivent être rendus ici. Je peux ajouter le contrôle, mais ils ont besoin d'un scriptmanager ou il explose au rendu. J'ai essayé d'en ajouter un comme un contrôle dans la page, mais ensuite il explose avec une erreur d'objet non définie sur une instance. –

1

Une autre option consiste à héberger le pipeline HTTP ASP.NET dans votre processus, rendre la page à un flux et lire le code HTML que vous devez envoyer à partir du flux HttpListenerContext.Response.OutputStream après le traitement de la page.

Cet article contient des détails: http://msdn.microsoft.com/en-us/magazine/cc163879.aspx

Questions connexes