04. Przykłady zastosowania popularnych kontrolek - część II
Autor:
Piotr Gaszewski
Opublikowano:
23 grudnia 2005
Odsłon:
70 306
W rozdziale tym postaram się zaprezentować działanie
kolejnych kilku popularnych kontrolek, które będziemy mogli wykorzystywać w
swoich projektach.
Często spotykana jest sytuacja, w której użytkownik musi
zapisać jakiś plik na serwerze za pośrednictwem formularza. Przykładowo może być
to zdjęcie, dołączone do swoich danych lub też awatar na forum internetowym. W
ASP.NET funkcjonalność tą łatwo możemy zrealizować używając do tego kontrolki
FileUpload.
Pierwszym krokiem, który musimy uczynić jest dodanie nowej
formatki, lub utworzenie nowego projektu w Visual Studio. Następnie musimy
wybrać lokalizację, w której będzie zapisywany plik na serwerze. Proponuje
utworzyć nowy katalog w ramach naszego projektu. W tym celu w oknie Solution
Explorera klikamy prawym przyciskiem myszy na ścieżkę dostępu do naszego
projektu i wybieramy opcje: Add Folder -> Regular Folder. Utworzony folder
nazwijmy „UploadedFiles" (lub inaczej, wedle własnego uznania, będziemy musieli
wówczas jednak zmienić ścieżkę dostępu w kodzie strony, odpowiedzialnym za
zapisywanie plików na serwerze). Następnie na otwartą formatkę przeciągnijmy
elementy typu: FileUpload, Button oraz Label. Po zmianie właściwości Text
przycisku oraz pola Label moja formatka wygląda następująco:

Kliknijmy teraz dwukrotnie na zamieszczonym na formatce
przycisku, co spowoduje dodanie funkcji wywoływanej w momencie jego naciśnięcia.
Zmodyfikujmy ją w następujący sposób:
protected
void Button1_Click(object
sender, EventArgs e)
{
HttpPostedFile file1 =
this.FileUpload1.PostedFile;
if ((file1 !=
null)
&& (file1.ContentLength > 0))
{
fileName =
System.IO.Path.GetFileName(file1.FileName);
string saveLocation =
Server.MapPath("UploadedFiles\\" + fileName);
try
{
file1.SaveAs(saveLocation);
this.Label1.Text
= "Plik został zapisany na serwerze";
}
catch(Exception ex)
{
this.Label1.Text
= "Wystąpił błąd: " +ex.Message;
}
}
else
{
this.Label1.Text = "Nie podałeś lokalizacji
pliku na dysku, lub plik ten jest nieprawidłowy";
}
}
Na początku następuje utworzenie obiektu, typu
HttpPostedFile (nasza formatka FileUpload, nosi w tym przypadku domyślną nazwę
FileUpload1). Następnie sprawdzamy, czy zadany plik istnieje, w przeciwnym
wypadku użytkownik otrzyma na stronie stosowną informację. W przypadku
poprawnego pliku, kolejnym krokiem jest pobranie jego nazwy oraz utworzenie
łańcucha znakowego, zawierającego przyszłą lokalizację pliku na serwerze (uwaga
– katalog „UploadedFiles" musi istnieć w systemie przed pierwszym uruchomieniem
aplikacji, w przeciwnym razie w momencie próby zapisania pliku otrzymamy
komunikat o błędzie). Następnie plik jest zapisywany na w odpowiednim miejscu na
serwerze, za pomocą metody „SaveAs" obiektu typu HttpPostedFile. Użytkownik
zobaczy również w oknie przeglądarki tekst, informujący o poprawnym przebiegu
operacji.
Wyobraźmy sobie teraz sytuację, w której chcemy wyświetlić
na stronie wszystkie obrazy, zawarte w naszym katalogu (oczywiście na serwerze
możemy umieszczać nie tylko pliki zawierające obrazy, na potrzeby tego artykułu
przyjąłem jednak uproszczenie, że tylko takie obiekty będą się w nim znajdować).
Wykorzystamy do tego kontrolkę „Image". Tym razem, nie będziemy jednak
umieszczać jej na stronie, przeciągając kontrolkę na naszą formatkę z pasku
narzędzi. Ponieważ nie wiemy ile obrazów znajdować się będzie we wskazanym przez
nas katalogu, kolejne obiekty klasy Image będą dodawane na stronę w sposób
dynamiczny, tzn. za pomocą kodu w języku C#. Dodajmy nową formatkę do naszego
projektu, a następnie zmodyfikujmy jej kod w następujący sposób:
protected
void Page_Load(object
sender, EventArgs e)
{
string
dir = @"C:\Documents and Settings\Gash\Moje dokumenty\Visual Studio
2005\WebSites\WebSite1\UploadedFiles";
string[]
files = System.IO.Directory.GetFiles(dir);
for(int
i =0; i < files.Length; i++)
{
Image im =
new Image();
im.ImageUrl =
@"UploadedFiles\" + GetFileName(files[i]);
im.Height =
200;
im.Width = 300;
Label lbl =
new Label();
lbl.Text =
GetFileName(" " + files[i]) +
"<br>";
this.form1.Controls.Add(im);
this.form1.Controls.Add(lbl);
}
}
private
string GetFileName(string
filePath)
{
string[]
temp = filePath.Split(System.Char.Parse(@"\"));
return
temp[temp.Length - 1];
}
Pierwszą czynnością, którą musimy wykonać, jest dodanie
nowej metody, o nazwie GetFileName, do pliku zawierający kod źródłowy formatki.
Metoda ta, pobierać będzie napis, zawierający pełną ścieżkę źródłową,
określającą położenie pliku na serwerze, natomiast zwracać będzie wyodrębnioną z
tej ścieżki nazwę pliku. W metodzie Page_Load na początku podajemy ścieżkę do
katalogu, w którym znajdować się mają pliki graficzne. Następnie, za pomocą
metody GetFiles, klasy Directory, tworzymy tablicę zawierającą ścieżki dostępu
do poszczególnych plików, zawartych z katalogu. Następnie tworzymy obiekt klasy
Image i ustawiamy jego właściwości (kolejno: względną ścieżkę do pliku, który ma
być wyświetlany na stronie, wysokość oraz szerokość prezentowanego obrazu).
Tworzymy również obiekt klasy Label, wyświetlający nazwę pliku na stronie.
Następnie, za pomocą metody Add, dodajemy stworzone obiekty do formatki. Podane
czynność wykonujemy w pętli, dla wszystkich plików zawartych w katalogu. Efekt
działania powyższego kodu przedstawiać się może następująco:

Niektórzy z Was, zastanawiają się pewnie, co oznacza symbol
„@", umieszczany przed zawartymi w kodzie napisami. Otóż, umożliwia on
traktowanie znaków specjalnych (w naszym przypadku będzie to „\"), jak zwykłych
symboli. Wiecie zapewnie, że ciągi typu: „\n" lub „\t" nie są wyświetlane
„dosłownie", reprezentują natomiast odpowiednio: sybol nowego wiersza oraz
tabulatora. Jeżeli chcemy, aby nasz napis zawierał symbol „\" musimy zastosować
jedną z następujących konstrukcji:
string napis =
"\\";
string napis = @"\";
Ostatnią kontrolką, którą chciałbym umówić z tym rozdziale,
jest obiekt, reprezentujący kalendarz. Wyobraźmy sobie sytuację, w której
użytkownik musi podać w formularzu datę swojego urodzenia. Do tej czynności
wystarczy zwykła formatka TextBox – w tym przypadku skazani jesteśmy jednak na
żmudne sprawdzanie poprawności danych, wprowadzonych przez użytkownika. Osoba,
wypełniająca formularz, może popełnić wiele błędów, na przykład podać datę w
rodzaju: „2005-13-30", czy też: „32-00-2003". Dzięki zastosowaniu kontrolki Calendar, możemy łatwo uniknąć tego typu błędów. Do naszego projektu w Visual
Studio dodajmy nową formatkę, następnie z pasku narzędzi przeciągnijmy na nią
obiekty: ToolBox oraz Calendar. Na początku ustawmy właściwość kontroli
textBox1: ReadOnly = True. Uniemożliwimy w ten sposób użytkownikowi aplikacji
własnoręczną edycję wspomnianego pola. Następnie kliknijmy dwukrotnie lewym
przyciskiem myszy na znajdującej się na edytowanej stronie kontrolce Calendar1.
Spowoduje to wygenerowanie metody: Calendar_Selection_Changed, obsługującej
zdarzenie zmiany daty kalendarza. Uzupełnijmy kod tej metody z następujący
sposób:
protected
void Calendar1_SelectionChanged(object
sender, EventArgs e)
{
this.TextBox1.Text
= this.Calendar1.SelectedDate.ToShortDateString();
}
Po uruchomieniu projektu, edytowana przez nas strona,
wyglądać będzie następująco:

Wybierając datę w wyświetlonym kalendarzu (za pomocą lewego
przycisku myszy) uzyskamy następujący efekt:

Platforma .NET udostępnia dziesiątki innych gotowych do
użycia kontrolek. Część z nich zostanie omówiona w kolejnych rozdziałach kursu.
Ponadto wiele rozmaitych obiektów tego typu, często o bardzo rozbudowanej
funkcjonalności, możemy znaleźć w Internecie. Udostępniane są one przez swoich
twórców za darmo, bądź po wniesieniu odpowiedniej opłaty.
Komentarze
I wszystko jasne !!!
gregorito33,
29 maja 2006, 18:11
w 7 linijce należy dodać "string" przed "filename" - inaczej nie ruszy :)
Lukas,
29 czerwca 2006, 19:22
dokładnie
MałyfromSłupca,
17 lipca 2006, 14:46
imho "UploadedFiles/", a nie "UploadedFiles\" ;)
riju,
18 lipca 2006, 23:10
mam problem... czy do drugiej formatki trzeba utworzyc drugi plik zrodlowy c#? w jaki sposób to zrobic?
szymon ,
24 lipca 2006, 15:22
gdy robie upload pliku 5MB strona sie wysypuje..
daniel,
4 września 2006, 14:48
Zrobilem 2 zadanie i wyswietlamy mi sie tylko nazwy plikow, skopiowalem z www (bo sam mialem inne nazwy) i nadal to samo ale po uwzglednieniu uwagi od riju juz wszystko dziala.
Co do 3 zadania (kalendarz) to tutaj jest blad w tekscie: "przeciągnijmy na nią obiekty: ToolBox oraz Calenda" bo chyba calego ToolBoxa nie da sie przeciagnac na formatke ;)
Adam,
12 września 2006, 20:03
fajny kurs:)
kasia,
4 czerwca 2007, 16:09
adam, zamiast "przeciągnijmy na nią obiekty: ToolBox.." winno byc TextBox, i tyle.
f,
17 czerwca 2007, 16:24
ja mam problem , bo jak daje Image img=new Image();
to potem nie widzi wlasnosci img.ImageUrl,,, czy ktos moze mi pomoc? dzieki
mati,
18 czerwca 2007, 02:57
Poradził sobie ktoś z zapisywaniem plików większych niż 5 MB? Ja próbowałem zapisać plik 4.4MB i też mi się wysypywało...
iceman1982,
17 września 2007, 17:10
@riju, adam
z "UploadedFiles\" też zadziała ale chyba tylko pod IE.
Qba,
17 listopada 2007, 01:38
no nie wiem ale nie działa mi wyswietlanie zawartości jpegów ....
UploadedFiles / albo \ i nic nie zmienia :/
Rafał,
2 grudnia 2007, 17:03
Jeżeli chodzi o "wysypywanie" się plików pow. 4MB:
"The maximum size allowed for a request, which includes uploaded files, is 4 MB, by default. Maximum request size can be specified in the Machine.config or Web.config file in the maxRequestLength attribute of the httpRuntime Element (ASP.NET Settings Schema) element. The maximum request size for a specific page can be specified using the location Element (ASP.NET Settings Schema) element in a Web.config file."
Yaro,
25 stycznia 2008, 15:43
Kurs tylko przegladam narazie ale wydaje mi sie ze jest blad w lini
if ((file1 != null) && (file1.ContentLength > 0))
Za jednym razem jest tu sprawdzenie czy file1 nie jest pusta referencja i odwolanie do jego pola co w przypadku gdy file1 rzeczywiscie jest null powinno wykoleic skrypt.
krzysiek,
27 stycznia 2008, 23:56
zapis: if ((file1 != null) && (file1.ContentLength > 0))
jest równoznaczny z zapisem:
if (file1 != null) {
if (file1.ContentLength > 0) {
.............
.............
}
}
Yaro,
28 stycznia 2008, 16:47
krzysiek nie wywali skryptu ponieważ jeśli file1 == null to warunek drugi już nie jest sprawdzany
juchusek,
1 lutego 2008, 17:59
ja zmienilem 3 linijke na
string dir = Server.MapPath("UploadedFiles\\");
oraz "UploadedFiles\" na "UploadedFiles/" i mi dziala :D
turbo,
4 marca 2008, 17:33
To jest trochę zmodyfikowany kod, ale przynajmniej działa.
protected void Page_Load(object sender, EventArgs e)
{
string katalog = Server.MapPath("Uploaded Files");
string["> pliki = System.IO.Directory.GetFiles(katalog);
for (int i = 0; i < pliki.Length; i++)
{
Image im = new Image();
im.ImageUrl = "~/Uploaded Files/" + GetFileName(pliki);
im.Height = 200;
im.Width = 300;
this.form1.Controls.Add(im);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
HttpPostedFile plik = this.FileUpload1.PostedFile;
string nazwa_pliku, sciezka_zapisu;
if (plik.ContentLength >0)
{
nazwa_pliku = plik.FileName;
sciezka_zapisu = Server.MapPath("Uploaded Files//" + nazwa_pliku);
plik.SaveAs(sciezka_zapisu);
Label1.Text = "Zapisano plik";
}
else
{
Label1.Text = "Nie wybrano pliku";
}
}
private string GetFileName(string filePath)
{
string["> temp = filePath.Split(System.Char.Parse(@"\"));
return temp[temp.Length - 1">;
}
rychu_elektryk,
9 marca 2008, 16:10
czy komus pojawia sie błąd : The name "GetFileName" does not exist in the current context?? skad on sie wział? ma ktos jakis pomysl?
gj,
10 marca 2008, 21:46
co tak naprawde znaczy "dodac nową formatkę"" prosze o odp:)
abc,
10 marca 2008, 22:14
riju ma racje w ponizszej linijce zamiast "UploadedFiles\" POWINNO BYC "UploadedFiles/" <==== WAZNE bez tego nie wyswietla sie obrazki
im.ImageUrl = @"UploadedFiles/" + GetFileName(files); POPRAWNY
s0d,
22 marca 2008, 18:37
Aby dodać nową formatkę należy w okienku Solution Explorer klinąć prawym na drugi na liscie plik i pojawi sie lista z któej wybieramy "Add new Item"-->Web Form. I mamy dodatkowa forme w projekcie ;)
s0d,
22 marca 2008, 18:53
ToolBox oraz Calendar. Mialo byc TextBox zamiast ToolBox ;">
s0d,
22 marca 2008, 18:56
Ok, działa, tylko u mnie po załadowaniu zdjęcia, gdy strona się przeładuje, to tego zdjęcia nie widać, dopiero po załadowaniu następnego widać poprzednie, ale znow obecnego nie ma. Jak zrobić, zeby w momencie zapisania zdjecia, na przeladowanej stronie ono juz bylo widoczne?
xnimac,
10 kwietnia 2008, 00:56
Hej,troję laickie pytanie,ale cóż począć dopiero się uczę :) Co zrobić żeby z pierwszej formy, po naciśnięciu " jakiegoś" buttona pojawiła nam się ta 2-ga forma?
madzia,
14 maja 2008, 08:36
Przepraszam, toż to w następnej części jest napisane ;P
madzia,
15 maja 2008, 09:02
A w jaki sposób odnosić się do ścieżki względnej, autor podał pełną ścieżkę do katalogu z obrazkami. Gdy zamiast tej ścieżki podam samo "upload" dostaje błąd: "Could not find a part of the path "C:\WINDOWS\system32\upload". "
Duch,
18 maja 2008, 18:27
To było w przypadku umieszczenia do katalogu IIS przy uruchomieniu ctrl+F5 dostaję "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\upload"
Duch,
18 maja 2008, 18:29
Zastanawiam sie dlaczego Autor nie poprawia bledow zgloszonych przez czytelnikow kursu... :/
Beens,
25 lipca 2008, 12:47
bo nie ma czasu?
odpowiednik,
19 września 2008, 22:28
Witam, mam takie pytanie, dlaczego w FireFoxie i w Operze nie wyświetląją się obrazki, tylko nazwy plików?
Bartek,
3 października 2008, 16:46
Bartek odpowiedz na twoje pytanie pojawiła się wyżej w komentarzach i to nie jeden raz
adakkj,
6 października 2008, 00:47
Bez sensu nic nie działa
Do dupy z takim kodem
sa,
3 czerwca 2009, 20:51
czy zamiast
this.TextBox1.Text = this.Calendar1.SelectedDate.ToShortDateString();
nie powinno być
this.TextBox1.Text = Calendar1.SelectedDate.ToShortDateString();
?? mi tylko ta druga opcja działa.
magda,
2 września 2009, 15:59
Ja jakiś głupi jestem albo po prostu już za późno się zrobiło. Nikt moim zdaniem nie odpowiedział na pytanie "gj" - co z tajemniczym GetFileName? Ani to metoda, ani obiekt... czy to jest jakieś this, a może coś jeszcze innego? Byłoby super, gdyby ktoś odpowiedział, bo nie mogę dalej się ruszyć. I tak, poprawiłem ukośnik przy UploadedFiles.
wypisany,
5 września 2009, 01:40
Ok, było za późno i nie zauważyłem definicji metody. Już nie zawracam głowy.
wypisany,
5 września 2009, 10:24
Magdo oby dwie opcje MUSZĄ działać! Jeżeli ty nie napiszesz this to kompilator to za Ciebie zrobi... this jest pointerem pokazującym na obiekty wewnątrz klasy.
sid,
17 maja 2010, 20:58
Jeżeli ktoś potrzebuje pomocy w sprawie niewrzucających się plików powyżej 4 MB, proszę pisać na gg: 2013818
Chicken,
16 czerwca 2010, 14:30
nie laduje *.bmp o wiekszej rozdzielczosci
whiskas,
15 października 2010, 13:25
Proszę o dokładne podawanie w której linii kodu występuje błąd. Nr linii podawany jest przy kodzie źródłowym i nie potrzeba robić wyliczanek.
I tak co się tyczy błędu "filename" to jest to linia nr 45 i rzeczywiście trzeba doipisać "string" ale też, przynajmniej u mnie trzeba zmienić "fileName" na "FileName".
Kolejna sprawa to katalog "UploadedFiles". W linii 18 należy sprawdzić czy ścieżka do katalogu jest prawidłowa, w przeciwnym wypadku należy podać prawidłową ścieżkę.
Myślę, że wspólnymi siłami damy radę z tym kursem.
Darek,
25 października 2011, 13:12
A orientuje się ktoś jak to może wyglądać dodawanie na serwer bądź co najlepsze do utworzonej bazy danych pliku mp3 ?? A później np. pobranie takiego pliku ??
bartos,
31 stycznia 2012, 19:23
Ten kalendarz to bardzo toporna sprawa, w sensie działania. Za każdym razem, gdy wybiera się datę przeładowuję się strona. Bardziej, sensownie działało by to w w JS.
Emi,
5 kwietnia 2012, 15:04