Utilizando Server.Transfer e ASP.NET AJAX 1.0

Salve desenvolvedores,

depois de incluirmos o ASP.NET AJAX 1.0 no projeto, verificamos um sério problema com o Server.Transfer(novamente). Transferindo dados da Pagina1.aspx que está no diretório /Pasta1/, utilizando Server.Transfer para a Pagina2.aspx que está no diretório /Pasta2/. Ao executarmos uma ação na Pagina2 utilizando o UpdatePanel, após o primeiro post assíncrono, recebiamos o seguinte erro:

Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the request on the server. The status code returned from the server was: 404

Erro 404? Página não encontrada? oras… como o primeiro post funciona e o restante não? Procurei, procurei, procurei e nada. Algumas pessoas com o mesmo erro, desde o Beta 2 e nada.

Então, debugando o Javascript (viva o IE6 hehe), consegui achar o problema.

Quando entramos na Pagina2.aspx pelo Server.Transfer, o action do formulário está correto, nesse caso: “../Pasta2/Pagina2.aspx”, pois o Server.Transfer não muda a URL e ainda estamos rodando no Contexto da Pagina1 (/Pasta1/), então temos que voltar uma pasta, entrar na pasta correta e chamar o arquivo correto.

Adicionando um evento no EndRequest (Sys.WebForms.PageRequestManager.getInstance().add_endRequest…), após o primeiro post, o action do formulário era apenas “Pagina2.aspx”, e nesse caso, como o contexto está ainda na Pasta1, vem a excessão 404.

Isso ocorre, porque dentro do ASP.NET AJAX, arquivo Resource (que é gerado dinamicamente pelo ScriptManager), é chamado o método Sys.Net.WebRequest._resolveUrl:

Sys.Net.WebRequest._resolveUrl = function Sys$Net$WebRequest$_resolveUrl(url, baseUrl) {
if (url && url.indexOf(‘://’) !== -1) {
return url;
}

if (!baseUrl || baseUrl.length === 0) {
var baseElement = document.getElementsByTagName(‘base’)[0];
if (baseElement && baseElement.href && baseElement.href.length > 0) {
baseUrl = baseElement.href;
}
else {
baseUrl = document.URL;
}
}

var qsStart = baseUrl.indexOf(‘?’);
if (qsStart !== -1) {
baseUrl = baseUrl.substr(0, qsStart);
}
baseUrl = baseUrl.substr(0, baseUrl.lastIndexOf(‘/’) + 1);

if (!url || url.length === 0) {
return baseUrl;
}

if (url.charAt(0) === ‘/’) {
var slashslash = baseUrl.indexOf(‘://’);
if (slashslash === -1) {
throw Error.argument(“baseUrl”, Sys.Res.badBaseUrl1);
}

var nextSlash = baseUrl.indexOf(‘/’, slashslash + 3);
if (nextSlash === -1) {
throw Error.argument(“baseUrl”, Sys.Res.badBaseUrl2);
}

return baseUrl.substr(0, nextSlash) + url;
}
else {
var lastSlash = baseUrl.lastIndexOf(‘/’);
if (lastSlash === -1) {
throw Error.argument(“baseUrl”, Sys.Res.badBaseUrl3);
}

return baseUrl.substr(0, lastSlash+1) + url;
}
}

e nesse caso, ele recupera a URL, “baseUrl = document.URL;”, que ainda está na Pasta1, chamando o action atual, “Pagina2.aspx”, e gerando a excessão pra frente.

Mesmo mudando o action na mão, no evento BeginRequest (Sys.WebForms.PageRequestManager.getInstance().add_beginRequest), não funciona como o esperado.

Para resolver esse problema, basta adicionarmos o seguinte script no codebehind. Nesse caso, eu sei exatamente a estrutura das duas páginas, e passei o parametro na mão. Se alguém quiser, pode fazer essa comparação de diretórios utilizando AppRelativeVirtualPath e Context.Request.FilePath, seria bem-vindo o código.

// Adiciona JS para correção do AJAX
StringBuilder sbJS = new StringBuilder();
string actionUrl = string.Format(“‘{0}’”, “../Pasta2/Pagina2.aspx”);
sbJS.Append(“Sys.Application.add_load(function(){“);
sbJS.Append(” var form = Sys.WebForms.PageRequestManager.getInstance()._form;”);
sbJS.Append(” form._initialAction = ” + actionUrl + “;”);
sbJS.Append(” form.action = ” + actionUrl + “;”);
sbJS.Append(“});”);
ClientScript.RegisterStartupScript(this.GetType(), “CorrecaoAjax”, sbJS.ToString(), true);

Esse foi o único modo que consegui resolver esse outro problema com Server.Transer. Lembrando que eu sei exatamente a estrutura de pastas e sei para onde ele tinha que postar corretamente. E também, porque de uma página para outra, são pastas (estruturas) diferentes.

abraços,

Leave a Reply