Esclusivamente riferito a questo scenario:
- WebApllication ASP.NET Ajax dentro un frame o iframe.
- Il frame si trova in un dominio differente rispetto la finestra top-level.
Se si cerca di accedere alla Web-Aplication, tramite Internet Explorer (IE), viene sollevato l'errore lato client "access denied" ogni volta che un evento DOM viene sollevato.
Prima di proseguire due parole sullo scenario, anche se a prima vista potrebbe sembrare strano che si possa verificare, provate ad immaginare una situazione del genere: WebpartPage su Moss che ospita la vostra Web-Application.
In sostanza e per essere più chiari, quello che si verifica è l'impossibilità di utilizzare qualsiasi controllo Ajax inserito nella Web-Application.
Per poter permettere il corretto funzionamento di Ajax anche in uno scenario del genere esiste un work around di Bertrand Le Roy, che spiega dettagliatamente le cause, la risoluzione e alcune considerazioni e update, di conseguenza se volete andare a fondo vi consiglio di dare una letta al suo post, altrimenti eccovi la soluzione che io ho adottato, prendendo sempre spunto dal suo post.
Il concetto che sta alla base del work-around è la localizzazione degli script che compongono la Microsoft Ajax Library di solito per chi ha installato Ajax questi si trovano nella directory di installazione di quest'ultimo es: "C:\[PathToAjaxFolder]\ASP.NET 2.0 AJAX Extensions\v1.0.61025\MicrosoftAjaxLibrary\" (PathToAjaxFolder è il path alla tua directory di installazione) all'interno della directory System.Web.Extension.
Bene, trovata System.Web.Extension l'ho copiata ed inserita all'interno della directory che contiene il file soluzione di VS2005 della mia Web-Application, notate che il "dove" copiare la directory dipende sopratutrto da come sono stati concettualmente suddivisi i vari file e directory che compongono la vostra soluzione. Fatto questo da Visual Studio ho reso visibile la directory all'interno della soluzione (ora è visibile dal Solution Explorer di Visual Studio).
Altra considerazione se avete certezza che la vostra aplicazione faccia comunque uso di una sola lingua ad esempio italiano potete eliminare tutti i file che si trovano all'interno della directory "System.Web.Extensions\1.0.61025.0\Globalization" escluso il file "it-IT.js", questo vi permette di mantenere il supporto alla globalizzazione per la lingua Italiana in Ajax, e di risparmiare spazio su disco.
Ancora non ci siamo, ci sono altri step che dobbiamo fare:
1) Modifica dei file "*.aspx" che contengono lo Script Manager. Certo lo script manager deve essere modificato e nel particolare si deve aggiungere questa referenza in questo modo:
<asp:ScriptManager ID="MyScriptManager" runat="server" EnableScriptGlobalization="true" EnablePageMethods="true" >
<Scripts>
<asp:ScriptReference Name="MicrosoftAjax.js" ScriptMode="Auto" Path="System.Web.Extensions/1.0.61025.0/MicrosoftAjax.js"/>
</Scripts>
</asp:ScriptManager>
Due considerazioni sull'attributo Path del tag asp:ScriptReference, questo si riferisce propio al path della directory Suystem.Web.Extension rispetto alla path del file .aspx alla quale lo script manager, che stiamo modificando, appartiene. Nello specifico l'esempio mostra lo ScirptManager del file Default.aspx (vedi immagine). Se il file .aspx si trovasse di un livello inferiore rispetto alla gerarchia delle directory allora l'attributo path deve essere modificato come segue:
Path="~/System.Web.Extensions/1.0.61025.0/MicrosoftAjax.js"
2) Patchare i file MicrosoftAjax.debug.js e MicrosoftAjax.js, ok non vi dico dove trovate questi file se avete seguito con interesse lo sapete, per cui apriamo il file MicrosoftAjax.debug.js cerchiamo questo testo all'interno del file:
switch(Sys.Browser.agent) {
case Sys.Browser.InternetExplorer:
Ora rimpiazziamo qualsiasi cosa si trova tra il codice sopra e questo codice:
case Sys.Browser.Safari:
Con questo codice (NB: le righe di codice sopra non devono essere rimpiazzate deve essere rimpiazzato solo il codice che si trova tra le due righe sopra):
Sys.UI.DomElement.getLocation = function(element) {
if (element.self || element.nodeType === 9) return new Sys.UI.Point(0,0);
var clientRect = element.getBoundingClientRect();
if (!clientRect) {
return new Sys.UI.Point(0,0);
}
var ownerDocument = element.document.documentElement;
var offsetX = clientRect.left - 2 + ownerDocument.scrollLeft,
offsetY = clientRect.top - 2 + ownerDocument.scrollTop;
try {
var f = element.ownerDocument.parentWindow.frameElement || null;
if (f) {
var offset = 2 - (f.frameBorder || 1) * 2;
offsetX += offset;
offsetY += offset;
}
}
catch(ex) {
}
return new Sys.UI.Point(offsetX, offsetY);
}
break;
Bene un consiglio invece di rimpiazzare brutalmente al vecchio codice dategli una commentata. Ora dobbiamo modificare il file MicrosoftAjax.js attenzione non dovete modificare la formattazzione del testo, ma semplicemnte rimpiazzare il codice, vi dico questo perche questo file non è formattato allo stesso modo di quello precedente. Per cui aprite il file MicrosoftAjax.js trovate il codice:
switch(Sys.Browser.agent){case Sys.Browser.InternetExplorer:
rimpiazzate tutto quello che si trova tra la riga sopra e questa riga:
case Sys.Browser.Safari:
con questo codice (NB: Ancora una volta assicuratevi che il codice sotto non contenga interruzioni di linea prima di effettuare la sostituzione, copiatelo in notepad eliminate le interruzioni di linea sostituitelo):
Sys.UI.DomElement.getLocation=function(a){if(a.self||a.nodeType===9)return new Sys.UI.Point(0,0);
var b=a.getBoundingClientRect();if(!b)return new Sys.UI.Point(0,0);
var c=a.document.documentElement,d=b.left-2+c.scrollLeft,e=b.top-2+c.scrollTop;
try{var g=a.ownerDocument.parentWindow.frameElement||null;
if(g){var f=2-(g.frameBorder||1)*2;d+=f;e+=f}}catch(h){}return new Sys.UI.Point(d,e)};break;
Fine ora la Web-Application non deve più mostrare gli errori.