Como Fazer Callbacks Do Lado Do Servidor
Os Callbacks foram introduzidos no ASP.NET 2.0 e são um mecanismo simples de chamar funcionalidade de uma page ou controlo se ter de gerar a página e sem que o utilizador se aperceba.
Para que uma página possa receber callbacks, tudo o que é necessário é implementar a interface ICallbackEventHandler.
Quando o cliente chama funcionalidade de uma página ou controlo no servidor, o estado inicial dos controlos é enviado para o servidor junto com o controlo cuja funcionalidade está a ser chamada no campo __CALLBACKID e o parâmetro da chamada no campo __CALLBACKPARAM.
É um procedimento bastante simples.
Mas, e se for necessário fazer a mesma chamada do lado do servidor?
Para que um pedido seja identificado como um callback (IsCallback), o pedido tem de ser um postback (IsPostback) e os campos acima mencionados têm de fazer parte dos dados do pedido (post data). Por outro lado, para que um pedido seja considerado um postback, o nível de chamadas do lado do servidor (Transfer ou Execute) tem de ser 0 (o que quer dizer que não foi feita nenhuma chamada a Transfer ou Execute) ou o tipo da página é o mesmo do Handler do pedido corrente e o método HTTP é POST.
Modificar o método HTTP (tnato quanto sei) é impossível. Portanto, se o pedido não for já um POST, não há qualquer forma de efectuar um callback.
Inicializar os dados do pedido é mais fácil. É apenas necessário reimplementar o método DeterminePostBackMode da página (ou de um page adapter) e retornar os dados previamente guardados no contexto. Algo assim:
protected override NameValueCollection DeterminePostBackMode()
{
NameValueCollection postBackMode = Context.Items["callbackPostData"] as NameValueCollection;
return (postBackMode != null) ? postBackMode : base.DeterminePostBackMode();
}
E fazer uma chamada será algo assim:
IHttpHandler handler = this.Context.Handler;
try
{
NameValueCollection postData = new NameValueCollection();
postData.Add("__CALLBACKID", sender);
postData.Add("__CALLBACKPARAM", this.argument.Text);
Context.Items["callbackPostData"] = postData;
Page calledPage = (Page)PageParser.GetCompiledPageInstance("~/Callback1.aspx", this.Server.MapPath("~/Callback1.aspx"), this.Context);
this.Context.Handler = calledPage;
StringWriter writer = new StringWriter();
Server.Execute(calledPage, writer, false);
this.response.Text = writer.ToString();
}
finally
{
this.Context.Handler = handler;
}
Aqui está uma implementação deste conceito.