protected void Application_Start(object sender, EventArgs e)
{
AuthorizeRequest += Application_AutorizeRequest;
}
protected void Application_AutorizeRequest(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
if(...) // user hasn`t rights to use current page
{
Response.Redirect("AccessDenied.aspx");
}
}
else // must log in
{
Response.Redirect("Login.aspx");
}
}
Компілимо код, запускаємо, пробуємо і... Ніфіга не працює! Мало того, після наших редіректів аплікація взагалі вмирає - браузер приречено повідомляє про те, що не може отримати сторінку від сервера. Оживає все тільки по F5.
В чому ж проблема?
По перше, давайте зрозуміємо, що робить Response.Redirect. Він записує кудись адресу, куди треба перенаправити браузер, після чого викидає System.Threading.ThreadAbortException, який перериває виконання поточного потоку. Біда в тому, що на етапі, коли обробляються події в Global.asax ще не існує механізму, який перенаправить браузер за адресою, яку залишив Response.Redirect. Власне тому виклик цього методу просто і тупо завершує роботу аплікації.
ОК. А що ж робити? А все просто.
/*
Тут маленький відступ: хорошим тоном в ASP.Net є наслідування всіх стандартних контролів своїми, в які в будь-який момент можна дописати все, що завгодно. Так нехай всі наші сторінки наслідують не стандартний System.Web.UI.Page, а свій public class MyPage : System.Web.UI.Page.
*/
Отже, допишемо в Global.asax метод, який запише в кеші адресу сторінки, куди треба редіректитися і заюзаємо його в обробнику Application_AutorizeRequest:
protected void Application_Start(object sender, EventArgs e)
{
AuthorizeRequest += Application_AutorizeRequest;
}
protected void Application_AutorizeRequest(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
if(...) // user hasn`t rights to use current page
{
Redirect("AccessDenied.aspx");
}
}
else
{
Redirect("Login.aspx");
}
}
protected void Redirect(string url)
{
HttpContext.Current.Cache["RedirectUrl"] = url;
}
А тепер треба сказати сторінці, що треба редіректитися, якщо в кеші є ця адреса:
public abstract class MyPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(HttpContext.Current.Cache["RedirectUrl"] != null)
{
string url = (string) HttpContext.Current.Cache["RedirectUrl"];
HttpContext.Current.Cache.Remove("RedirectUrl");
Response.Redirect(url);
}
// ...
}
// ...
}
Завдяки тому, що ми унаслідували свій клас для сторінки, не потрібно писати одне й те ж для кожної сторінки - тепер все прекрасно працює.
Отака повчальна історія.
P.S. Нарешті знайшов нормальний syntax highlighter для блогспота. Чим і хвалюся =)
Немає коментарів:
Дописати коментар