Piotr Szczepanik – programowanie (.Net, C#, SQL), administracja, IT

blog IT: programowanie, administracja
Pomimo tego, iż Response.Redirect oraz Server.Transfer są dosyć często używanymi metodami przez programistów ASP.Net, często zdarza się, że tak naprawdę nie wiemy co się dzieje wskutek ich użycia.

Response.Redirect

Metoda ta nakazuje klientowi (przeglądarce internetowej) odwiedzenie danej lokalizacji URL. W praktyce po stronie użytkownika skutek jest taki sam jak byśmy wpisali nowy adres do paska adresu.

Jak właściwie to się odbywa? W momencie użycia Response.Redirect przeglądarka otrzymuje od serwera nagłówek HTTP podobny do poniższego (w nagłówku znajdują się również dodatkowe informacje, które w tym miejscu, akurat są bez znaczenia dla wytłumaczenia tematu):

HTTP/1.1 302 Object moved
Server: Microsoft-IIS/5.0
Location: new-url/new-page.aspx


Ten nagłówek informuje przeglądarkę, iż żądana strona znajduje się pod nową lokalizacją. Po tej informacji przeglądarka wykonuje kolejne żądanie (Request), tym razem pod lokalizację przekazaną w nagłówku.

Dzięki temu mechanizmowi możemy przekierowywać klienta zarówno na strony znajdujące się na naszym serwerze jak i na pełne adresy URL (np. http://www.photoartis.pl). Nowy URL może zawierać również tzw. QueryString, m.in. dzięki czemu możemy uzyskać przekazywanie informacji między stronami.

Należy pamiętać, że w momencie zastosowania Response.Redirect wszelkie pola z POST’a zostają utracone (jest to logiczne wskutek opisanych powyżej działań, ale warto o tym przypomnieć).

Server.Transfer

Ta metoda odbywa się całkowicie po stronie serwera. Np. przeglądarka wykonuje żądanie o stronę A.aspx. Aplikacja wywołuje metodę Server.Transfer(„B.aspx”). W rezultacie serwer zwraca do klienta zawartość strony B.aspx. W tym przypadku przeglądarka nadal myśli, że znajduje się na stronie A.aspx. Wskutek powyższego mechanizmu w pasku adresu przeglądarki będzie widniał URL do strony A.aspx.

Dzięki temu mechanizmowi otrzymujemy m.in. fakt, iż nie jest wykonywane kolejne żądanie HTTP po stronie klienta. Również zachowywane są wszystkie pola z POST’a.
Należy jednak pamiętać, że jeżeli strona wywołująca „Transfer” przed ta operacją zapisze coś do Response buffer to w rezultacie otrzymamy wynik z danymi zapisanymi do bufora oraz zawartością strony, na którą wykonaliśmy metodę Transfer. W takich przypadkach możemy po prostu przed wywołaniem metody przeprowadzić czyszczenie buforu Response.

Pamiętajmy również, że Server.Transfer nie umożliwia przekierowania na strony poza nasz serwer.
Często zdarza się, iż wrzucamy na naszą WebForm kontrolkę TextBox, a zaraz obok niej przycisk, który wywołuje jakąś akcję związaną z treścią wpisaną do kontrolki, np. pole wyszukiwania.

Co zrobić, żeby użytkownik zamiast klikania w przycisk wcisnął Enter po wpisaniu treści do pola TextBox ?

Poniżej przedstawię dwa sposoby:

Sposób 1 – kontrolka Panel

Umieszczamy obydwie kontrolki wewnątrz asp:Panel, której atrybut defaultButton ustawiamy na nasz przycisk.

 ASP |  kopiuj kod |? 
1
<asp:panel defaultbutton="btnSearch runat=">
2
    <asp:textbox id="textbox1" runat="server">
3
    <asp:button id="btnSearch" runat="server" text="Szukaj">
4
</asp:button></asp:textbox></asp:panel>

Sposób 2 - JavaScript

Na kontrolce TextBox dodajemy obsługę zdarzenia OnClick (np. w zdarzeniu PageLoad).
 Javascript |  kopiuj kod |? 
01
textbox1.Attributes.Add("onkeydown", 
02
            @"if(event.which || event.keyCode){
03
                  if ((event.which == 13) || (event.keyCode == 13)) {
04
                      document.getElementById('" + btnSearch.UniqueID.Replace('$', '_') + 
05
                      "').click();
06
                      return false;
07
                      }
08
                } else {
09
                    return true
10
                }; ");
Kontrolka ASP:Menu dziwnie się zachowuje / renderuje w przypadku wielopoziomowego menu w przeglądarkach Chrome i Menu. Jest kilka rozwiązań tego problemu. Poniżej jeden z nich, prawdopodobnie najszybszy.

W kodzie danej Page / MasterPage / bądź klasy nadrzędnej nad naszymi „Page” dodajemy:

 C# |  kopiuj kod |? 
01
protected override void OnInit(EventArgs e)
02
{
03
    base.OnInit(e);
04
 
05
    if (!string.IsNullOrEmpty(Request.UserAgent) &&
06
        (Request.UserAgent.IndexOf("AppleWebKit") > 0))
07
    {
08
        Request.Browser.Adapters.Clear();
09
    }
10
} 

Co może być przyczyną jeżeli podczas próby użycia ASP.Net Charting Control pojawia nam się HttpException: Błąd podczas wykonywania żądania podrzędnego dla ChartImg.axd ?

1. Brak odpowiedniego wpisu w web.config w sekcji HttpHandlers.
Wpis w pliku konfiguracyjnym naszej Web’owej aplikacji po poprawnej instalacji kontrolki powinien wyglądać tak:
 XML |  kopiuj kod |? 
1
<add path="ChartImg.axd" verb="GET,HEAD" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
2
    validate="false" ></add>

2. Jeżeli HttpException występuje tylko tuż po wywołaniu POST, wtedy nasz wpis w web.config powinien wyglądać następująco:
 XML |  kopiuj kod |? 
1
<add path="ChartImg.axd" verb="GET,HEAD,POST" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
2
    validate="false" ></add>

Dodatkowe problemu mogą się pojawić przy wyświetlaniu wykresu jeżeli w sekcji <handlers> nie mamy następującego wpisu:
 XML |  kopiuj kod |? 
1
<remove name="ChartImageHandler" />
2
<add name="ChartImageHandler" preCondition="integratedMode" verb="GET,HEAD"
3
    path="ChartImg.axd" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
Przy zastosowaniu kontrolki ASP:Menu w Internet Explorer 8 zamiast elementów menu pojawia się pusty „placek” ?

Nie wgłębiając się w szczegóły przyczyn spróbujmy nadać wartość CSS z-index, np.

 CSS |  kopiuj kod |? 
1
.menu-class
2
{
3
   z-index: 666;
4
}

Działa ?