Udostępnij za pośrednictwem


Przekazywanie plików (C#)

Autor: Scott Mitchell

Pobierz plik PDF

Dowiedz się, jak umożliwić użytkownikom przekazywanie plików binarnych (takich jak dokumenty programu Word lub PDF) do witryny sieci Web, w której mogą być przechowywane w systemie plików serwera lub bazie danych.

Wprowadzenie

Wszystkie samouczki, które zbadano do tej pory, działały wyłącznie z danymi tekstowymi. Jednak wiele aplikacji ma modele danych, które przechwytują zarówno dane tekstowe, jak i binarne. Witryna randkowa online może umożliwić użytkownikom przekazywanie zdjęcia do skojarzenia z ich profilem. Witryna internetowa rekrutująca może pozwolić użytkownikom przekazać swoje życiorysy jako dokument programu Microsoft Word lub PDF.

Praca z danymi binarnymi dodaje nowy zestaw wyzwań. Musimy zdecydować, w jaki sposób dane binarne są przechowywane w aplikacji. Interfejs używany do wstawiania nowych rekordów musi zostać zaktualizowany, aby umożliwić użytkownikowi przekazanie pliku z komputera i należy wykonać dodatkowe czynności w celu wyświetlenia lub udostępnienia środków do pobrania skojarzonych z rekordami danych binarnych. W tym samouczku i kolejnych trzech omówimy, jak utrudnić te wyzwania. Na końcu tych samouczków utworzymy w pełni funkcjonalną aplikację, która kojarzy obraz i broszurę PDF z każdą kategorią. W tym konkretnym samouczku przyjrzymy się różnym technikom przechowywania danych binarnych i dowiesz się, jak umożliwić użytkownikom przekazywanie pliku z komputera i zapisanie go w systemie plików serwera internetowego.

Uwaga

Dane binarne, które są częścią modelu danych aplikacji, są czasami nazywane obiektem BLOB, akronimem binary large OBject. W tych samouczkach zdecydowałem się używać danych binarnych terminologii, chociaż termin BLOB jest synonimem.

Krok 1. Tworzenie stron sieci Web danych binarnych

Zanim zaczniemy eksplorować wyzwania związane z dodawaniem obsługi danych binarnych, najpierw pośmińmy chwilę, aby utworzyć strony ASP.NET w naszym projekcie witryny internetowej, które będą potrzebne w tym samouczku i w kolejnych trzech. Zacznij od dodania nowego folderu o nazwie BinaryData. Następnie dodaj następujące strony ASP.NET do tego folderu, aby skojarzyć każdą stronę ze stroną wzorcową Site.master :

  • Default.aspx
  • FileUpload.aspx
  • DisplayOrDownloadData.aspx
  • UploadInDetailsView.aspx
  • UpdatingAndDeleting.aspx

Dodawanie stron ASP.NET dla samouczków dotyczących danych binarnych

Rysunek 1. Dodawanie stron ASP.NET dla samouczków dotyczących danych binarnych

Podobnie jak w innych folderach, Default.aspx w BinaryData folderze zostanie wyświetlona lista samouczków w jego sekcji. Pamiętaj, że kontrolka SectionLevelTutorialListing.ascx użytkownika udostępnia tę funkcję. W związku z tym dodaj tę kontrolkę Default.aspx użytkownika, przeciągając ją z Eksplorator rozwiązań na stronę Widok projektu.

Dodaj kontrolkę Użytkownika SectionLevelTutorialListing.ascx, aby Default.aspx

Rysunek 2. Dodawanie kontrolki SectionLevelTutorialListing.ascx użytkownika do Default.aspx (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Na koniec dodaj te strony jako wpisy do Web.sitemap pliku. W szczególności dodaj następujący znacznik po zwiększeniu kontrolki GridView <siteMapNode>:

<siteMapNode 
    title="Working with Binary Data" 
    url="~/BinaryData/Default.aspx" 
    description="Extend the data model to include collecting binary data.">
    
    <siteMapNode 
        title="Uploading Files" 
        url="~/BinaryData/FileUpload.aspx" 
        description="Examine the different ways to store binary data on the 
                     web server and see how to accept uploaded files from users 
                     with the FileUpload control." />
    <siteMapNode 
        title="Display or Download Binary Data" 
        url="~/BinaryData/DisplayOrDownloadData.aspx" 
        description="Let users view or download the captured binary data." />
    <siteMapNode 
        title="Adding New Binary Data" 
        url="~/BinaryData/UploadInDetailsView.aspx" 
        description="Learn how to augment the inserting interface to 
                     include a FileUpload control." />
    <siteMapNode 
        title="Updating and Deleting Existing Binary Data" 
        url="~/BinaryData/UpdatingAndDeleting.aspx" 
        description="Learn how to update and delete existing binary data." />
</siteMapNode>

Po zaktualizowaniu Web.sitemapprogramu pośmiń chwilę, aby wyświetlić witrynę internetową samouczków za pośrednictwem przeglądarki. Menu po lewej stronie zawiera teraz elementy samouczków Praca z danymi binarnymi.

Mapa witryny zawiera teraz wpisy dotyczące pracy z danymi binarnymi — samouczki

Rysunek 3. Mapa witryny zawiera teraz wpisy dotyczące pracy z danymi binarnymi — samouczki

Krok 2. Wybieranie miejsca przechowywania danych binarnych

Dane binarne skojarzone z modelem danych aplikacji mogą być przechowywane w jednym z dwóch miejsc: w systemie plików serwera internetowego z odwołaniem do pliku przechowywanego w bazie danych; lub bezpośrednio w samej bazie danych (zobacz Rysunek 4). Każde podejście ma własny zestaw zalet i wad i zalet bardziej szczegółowej dyskusji.

Dane binarne mogą być przechowywane w systemie plików lub bezpośrednio w bazie danych

Rysunek 4. Dane binarne mogą być przechowywane w systemie plików lub bezpośrednio w bazie danych (kliknij, aby wyświetlić obraz pełnowymiarowy)

Załóżmy, że chcemy rozszerzyć bazę danych Northwind, aby skojarzyć obraz z każdym produktem. Jedną z opcji jest przechowywanie tych plików obrazów w systemie plików serwera internetowego i rejestrowanie ścieżki Products w tabeli. W przypadku tego podejścia dodaliśmy kolumnę ImagePath do Products tabeli typu varchar(200), być może. Gdy użytkownik przekaże obraz dla usługi Chai, ten obraz może być przechowywany w systemie plików serwera internetowego w ~/Images/Tea.jpglokalizacji , gdzie ~ reprezentuje ścieżkę fizyczną aplikacji. Oznacza to, że jeśli witryna sieci Web jest zakorzeniona w ścieżce C:\Websites\Northwind\fizycznej , ~/Images/Tea.jpg byłaby równoważna C:\Websites\Northwind\Images\Tea.jpg. Po przekazaniu pliku obrazu zaktualizujemy rekord Chai w Products tabeli, tak aby jego ImagePath kolumna odwołyła się do ścieżki nowego obrazu. Możemy użyć ~/Images/Tea.jpg polecenia lub tylko Tea.jpg wtedy, gdy zdecydujemy, że wszystkie obrazy produktów zostaną umieszczone w folderze aplikacji Images .

Główne zalety przechowywania danych binarnych w systemie plików to:

  • Łatwość implementacji , ponieważ wkrótce zobaczymy przechowywanie i pobieranie danych binarnych przechowywanych bezpośrednio w bazie danych obejmuje nieco więcej kodu niż podczas pracy z danymi za pośrednictwem systemu plików. Ponadto aby użytkownik mógł wyświetlać lub pobierać dane binarne, musi zostać wyświetlony adres URL dla tych danych. Jeśli dane znajdują się w systemie plików serwera internetowego, adres URL jest prosty. Jeśli jednak dane są przechowywane w bazie danych, należy utworzyć stronę internetową, która pobierze i zwróci dane z bazy danych.
  • Szerszy dostęp do danych binarnych, które mogą być dostępne dla innych usług lub aplikacji, które nie mogą ściągać danych z bazy danych. Na przykład obrazy skojarzone z każdym produktem mogą być również dostępne dla użytkowników za pośrednictwem protokołu FTP, w tym przypadku chcemy przechowywać dane binarne w systemie plików.
  • Wydajność , jeśli dane binarne są przechowywane w systemie plików, zapotrzebowanie i przeciążenie sieci między serwerem bazy danych a serwerem internetowym będzie mniejsze niż wtedy, gdy dane binarne są przechowywane bezpośrednio w bazie danych.

Główną wadą przechowywania danych binarnych w systemie plików jest oddzielenie danych z bazy danych. Jeśli rekord zostanie usunięty z Products tabeli, skojarzony plik w systemie plików serwera internetowego nie zostanie automatycznie usunięty. Musimy napisać dodatkowy kod, aby usunąć plik lub system plików stanie się zaśmiecony nieużywanymi, oddzielonymi plikami. Ponadto podczas tworzenia kopii zapasowej bazy danych musimy również utworzyć kopie zapasowe skojarzonych danych binarnych w systemie plików. Przeniesienie bazy danych do innej lokacji lub serwera wiąże się z podobnymi wyzwaniami.

Alternatywnie dane binarne mogą być przechowywane bezpośrednio w bazie danych programu Microsoft SQL Server 2005, tworząc kolumnę typu varbinary. Podobnie jak w przypadku innych typów danych o zmiennej długości, można określić maksymalną długość danych binarnych, które mogą być przechowywane w tej kolumnie. Na przykład aby zarezerwować maksymalnie 5000 bajtów, varbinary(5000)użyj polecenia ; varbinary(MAX) pozwala na maksymalny rozmiar magazynu, około 2 GB.

Główną zaletą przechowywania danych binarnych bezpośrednio w bazie danych jest ścisłe sprzężenie między danymi binarnymi a rekordem bazy danych. Znacznie upraszcza to zadania administracyjne bazy danych, takie jak kopie zapasowe lub przenoszenie bazy danych do innej lokacji lub serwera. Ponadto usunięcie rekordu powoduje automatyczne usunięcie odpowiednich danych binarnych. Istnieją również bardziej subtelne korzyści wynikające z przechowywania danych binarnych w bazie danych. Aby uzyskać bardziej szczegółowe omówienie, zobacz Przechowywanie plików binarnych bezpośrednio w bazie danych przy użyciu ASP.NET 2.0 .

Uwaga

W programie Microsoft SQL Server 2000 i starszych wersjach varbinary typ danych miał maksymalny limit 8000 bajtów. Aby przechowywać do 2 GB danych binarnych, image należy zamiast tego użyć typu danych. Po dodaniu w MAX programie SQL Server 2005 typ danych został jednak image przestarzały. Nadal jest obsługiwana w przypadku zgodności z poprzednimi wersjami, ale firma Microsoft ogłosiła, że image typ danych zostanie usunięty w przyszłej wersji programu SQL Server.

Jeśli pracujesz ze starszym modelem danych, możesz zobaczyć image typ danych. Tabela bazy danych Categories Northwind zawiera kolumnę Picture , która może służyć do przechowywania danych binarnych pliku obrazu dla kategorii. Ponieważ baza danych Northwind ma swoje korzenie w programie Microsoft Access i wcześniejszych wersjach programu SQL Server, ta kolumna jest typu image.

W tym samouczku i w następnych trzech przypadkach użyjemy obu metod. Tabela Categories zawiera już kolumnę Picture do przechowywania zawartości binarnej obrazu dla kategorii. Dodamy dodatkową kolumnę , BrochurePathw celu przechowywania ścieżki do pliku PDF w systemie plików serwera internetowego, który może służyć do zapewnienia jakości wydruku, dopracowanego przeglądu kategorii.

Krok 3. DodawanieBrochurePathkolumny doCategoriestabeli

Obecnie tabela Categories ma tylko cztery kolumny: CategoryID, , DescriptionCategoryNamei Picture. Oprócz tych pól musimy dodać nową, która będzie wskazywać broszurę kategorii (jeśli istnieje). Aby dodać tę kolumnę, przejdź do Eksploratora serwera, przejdź do szczegółów tabel, kliknij prawym przyciskiem myszy Categories tabelę i wybierz polecenie Otwórz definicję tabeli (zobacz Rysunek 5). Jeśli eksplorator serwera nie jest widoczny, wyświetl go, wybierając opcję Eksplorator serwera z menu Widok lub naciśnij Ctrl+Alt+S.

Dodaj nową varchar(200) kolumnę do Categories tabeli o nazwie BrochurePath i zezwala na NULL s i kliknij ikonę Zapisz (lub naciśnij Ctrl+S).

Dodawanie kolumny BroszuraPath do tabeli Categories

Rysunek 5. Dodawanie BrochurePath kolumny do Categories tabeli (kliknij, aby wyświetlić obraz pełnowymiarowy)

Krok 4. Aktualizowanie architektury w celu używaniaPicturekolumn iBrochurePath

Element CategoriesDataTable w warstwie dostępu do danych (DAL) ma obecnie zdefiniowane cztery DataColumn elementy: CategoryID, , CategoryNameDescriptioni NumberOfProducts. Pierwotnie zaprojektowano tę tabelę DataTable w samouczku Tworzenie warstwy dostępu do danych, CategoriesDataTable tylko trzy pierwsze kolumny. Kolumna NumberOfProducts została dodana w samouczku Master/Detail Using a Bulleted List of Master Records with a Details DataList (Lista punktowana rekordów głównych z samouczkiem Details DataList ).

Zgodnie z opisem w temacie Tworzenie warstwy dostępu do danych tabele DataTable w typowych zestawach danych tworzą obiekty biznesowe. Elementy TableAdapters są odpowiedzialne za komunikację z bazą danych i wypełnianie obiektów biznesowych wynikami zapytania. Element CategoriesDataTable jest wypełniany przez metodę CategoriesTableAdapter, która zawiera trzy metody pobierania danych:

  • GetCategories() Wykonuje główne zapytanie TableAdapter i zwraca CategoryIDpola , CategoryNamei Description wszystkich rekordów w Categories tabeli. Głównym zapytaniem jest to, co jest używane przez generowane Insert automatycznie metody i Update .
  • GetCategoryByCategoryID(categoryID)CategoryIDZwraca pola , CategoryNamei Description kategorii, których CategoryID jest równe categoryID.
  • GetCategoriesAndNumberOfProducts() — zwraca CategoryIDpola , CategoryNamei Description dla wszystkich rekordów w Categories tabeli. Używa również podzapytania, aby zwrócić liczbę produktów skojarzonych z każdą kategorią.

Zwróć uwagę, że żadne z tych zapytań nie zwraca Categories tabel ani BrochurePath Picture kolumn, ani nie CategoriesDataTable zawiera DataColumn parametrów dla tych pól. Aby pracować z obrazem i BrochurePath właściwościami, musimy najpierw dodać je do CategoriesDataTable klasy , a następnie zaktualizować klasę CategoriesTableAdapter , aby zwrócić te kolumny.

Dodawanie parametrówPictureiBrochurePath``DataColumn

Zacznij od dodania tych dwóch kolumn do elementu CategoriesDataTable. Kliknij prawym przyciskiem myszy CategoriesDataTable nagłówek s, wybierz pozycję Dodaj z menu kontekstowego, a następnie wybierz opcję Kolumna. Spowoduje to utworzenie nowego DataColumn elementu w tabeli DataTable o nazwie Column1. Zmień nazwę tej kolumny na Picture. W okno Właściwości ustaw DataColumn właściwość s DataType na System.Byte[] (nie jest to opcja na liście rozwijanej; musisz wpisać ją).

Utwórz obraz o nazwie DataColumn, którego typ danych to System.Byte[]

Rysunek 6. Tworzenie nazwanego DataColumn elementu o System.Byte[] DataType nazwie Picture (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Dodaj kolejny DataColumn element do tabeli DataTable, nazewnictwa go BrochurePath przy użyciu wartości domyślnej DataType (System.String).

ZwracaniePicturewartości iBrochurePathz tabeli TableAdapter

Po dodaniu tych dwóch DataColumn plików do CategoriesDataTableelementu możemy ponownie zaktualizować element CategoriesTableAdapter. Oba te wartości kolumn mogą być zwracane w głównym zapytaniu TableAdapter, ale spowoduje to przywrócenie danych binarnych za każdym razem, gdy GetCategories() metoda została wywołana. Zamiast tego zaktualizujmy główne zapytanie TableAdapter, aby przywrócić BrochurePath i utworzyć dodatkową metodę pobierania Picture danych zwracającą określoną kolumnę kategorii.

Aby zaktualizować główne zapytanie TableAdapter, kliknij prawym przyciskiem myszy CategoriesTableAdapter nagłówek s i wybierz opcję Konfiguruj z menu kontekstowego. Spowoduje to wyświetlenie Kreatora konfiguracji adaptera tabel, który widzieliśmy w wielu poprzednich samouczkach. Zaktualizuj zapytanie, aby przywrócić BrochurePath element i kliknij przycisk Zakończ.

Zaktualizuj listę kolumn w instrukcji SELECT, aby również zwrócić broszuręPath

Rysunek 7. Aktualizowanie listy kolumn w instrukcji SELECT również w celu zwrócenia BrochurePath (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

W przypadku używania instrukcji SQL ad hoc dla tabeli TableAdapter aktualizowanie listy kolumn w zapytaniu głównym aktualizuje listę kolumn dla wszystkich SELECT metod zapytań w tabeli TableAdapter. Oznacza to, że GetCategoryByCategoryID(categoryID) metoda została zaktualizowana w celu zwrócenia BrochurePath kolumny, co może być zamierzone. Jednak zaktualizowała ona również listę kolumn w metodzie GetCategoriesAndNumberOfProducts() , usuwając podzapytywanie zwracające liczbę produktów dla każdej kategorii! W związku z tym musimy zaktualizować to zapytanie metody SELECT . Kliknij prawym przyciskiem myszy metodę GetCategoriesAndNumberOfProducts() , wybierz pozycję Konfiguruj i przywróć kwerendę SELECT z powrotem do oryginalnej wartości:

SELECT CategoryID, CategoryName, Description, 
       (SELECT COUNT(*) 
            FROM Products p 
            WHERE p.CategoryID = c.CategoryID) 
       as NumberOfProducts
FROM Categories c

Następnie utwórz nową metodę TableAdapter, która zwraca wartość kolumny Picture określonej kategorii. Kliknij prawym przyciskiem myszy CategoriesTableAdapter nagłówek s i wybierz opcję Dodaj zapytanie, aby uruchomić Kreatora konfiguracji zapytań TableAdapter. Pierwszy krok tego kreatora nas, czy chcemy wykonywać zapytania o dane przy użyciu instrukcji AD-hoc SQL, nowej procedury składowanej lub istniejącej. Wybierz pozycję Użyj instrukcji SQL i kliknij przycisk Dalej. Ponieważ zwracamy wiersz, wybierz opcję SELECT, która zwraca wiersze z drugiego kroku.

Wybierz opcję Użyj instrukcji SQL

Rysunek 8. Wybierz opcję Użyj instrukcji SQL (kliknij, aby wyświetlić obraz pełnowymiarowy)

Ponieważ zapytanie zwróci rekord z tabeli Categories, wybierz pozycję SELECT, która zwraca wiersze

Rysunek 9. Ponieważ zapytanie zwróci rekord z tabeli Kategorii, wybierz pozycję SELECT, która zwraca wiersze (kliknij, aby wyświetlić obraz pełnowymiarowy)

W trzecim kroku wprowadź następujące zapytanie SQL i kliknij przycisk Dalej:

SELECT     CategoryID, CategoryName, Description, BrochurePath, Picture
FROM       Categories
WHERE      CategoryID = @CategoryID

Ostatnim krokiem jest wybranie nazwy nowej metody. Użyj FillCategoryWithBinaryDataByCategoryID odpowiednio metod i GetCategoryWithBinaryDataByCategoryID w polach Fill a DataTable (Wypełnianie tabeli DataTable) i Return a DataTable patterns (Zwracanie wzorców DataTable). Kliknij przycisk Zakończ, aby zakończyć kreatora.

Wybieranie nazw metod TableAdapter s

Rysunek 10. Wybierz nazwy metod TableAdapter (Kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Po zakończeniu pracy Kreatora konfiguracji kwerendy adaptera tabel może zostać wyświetlone okno dialogowe z informacją, że nowy tekst polecenia zwraca dane ze schematem innym niż schemat zapytania głównego. Krótko mówiąc, kreator zauważa, że główne zapytanie GetCategories() tableAdapter zwraca inny schemat niż właśnie utworzony. Ale to jest to, czego chcemy, więc możesz zignorować tę wiadomość.

Należy również pamiętać, że jeśli używasz instrukcji ad hoc SQL i użyjesz kreatora, aby zmienić główne zapytanie TableAdapter w pewnym późniejszym momencie, zmodyfikuje GetCategoryWithBinaryDataByCategoryID listę kolumn instrukcji metody SELECT , aby uwzględnić tylko te kolumny z zapytania głównego (czyli spowoduje to usunięcie Picture kolumny z zapytania). Musisz ręcznie zaktualizować listę kolumn, aby zwrócić kolumnę Picture , podobnie jak GetCategoriesAndNumberOfProducts() w przypadku metody wcześniej w tym kroku.

Po dodaniu dwóch DataColumn s do CategoriesDataTable metody i GetCategoryWithBinaryDataByCategoryID do CategoriesTableAdapterklasy w projektancie Typed DataSet powinny wyglądać jak zrzut ekranu na rysunku 11.

Projektant zestawu danych zawiera nowe kolumny i metodę

Rysunek 11. Projektant zestawu danych zawiera nowe kolumny i metodę

Aktualizowanie warstwy logiki biznesowej (BLL)

Po zaktualizowaniu dal wystarczy rozszerzyć warstwę logiki biznesowej (BLL), aby uwzględnić metodę dla nowej CategoriesTableAdapter metody. Dodaj następującą metodę do klasy CategoriesBLL:

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Select, false)] 
public Northwind.CategoriesDataTable 
    GetCategoryWithBinaryDataByCategoryID(int categoryID)
{
    return Adapter.GetCategoryWithBinaryDataByCategoryID(categoryID);
}

Krok 5. Przekazywanie pliku z klienta do serwera sieci Web

Podczas zbierania danych binarnych często te dane są dostarczane przez użytkownika końcowego. Aby przechwycić te informacje, użytkownik musi mieć możliwość przekazania pliku z komputera do serwera internetowego. Przekazane dane należy następnie zintegrować z modelem danych, co może oznaczać zapisanie pliku w systemie plików serwera internetowego i dodanie ścieżki do pliku w bazie danych lub zapisanie zawartości binarnej bezpośrednio w bazie danych. W tym kroku przyjrzymy się, jak umożliwić użytkownikowi przekazywanie plików z komputera na serwer. W następnym samouczku zwrócimy uwagę na integrację przekazanego pliku z modelem danych.

ASP.NET 2.0 nowej kontrolki sieci Web FileUpload udostępnia mechanizm wysyłania pliku z komputera do serwera internetowego. Kontrolka FileUpload renderuje się jako <input> element, którego type atrybut jest ustawiony na plik, który przeglądarki są wyświetlane jako pole tekstowe z przyciskiem Przeglądaj. Kliknięcie przycisku Przeglądaj powoduje wyświetlenie okna dialogowego, z którego użytkownik może wybrać plik. Po wysłaniu formularza z powrotem wybrana zawartość pliku jest wysyłana wraz ze postbackiem. Po stronie serwera informacje o przekazanym pliku są dostępne za pośrednictwem właściwości kontrolki FileUpload.

Aby zademonstrować przekazywanie plików, otwórz FileUpload.aspx stronę w BinaryData folderze, przeciągnij kontrolkę FileUpload z przybornika do Projektanta i ustaw właściwość kontrolki ID na UploadTest. Następnie dodaj kontrolkę Przycisk Sieci Web, ustawiając jej ID właściwości i Text odpowiednio na UploadButton i Przekaż wybrany plik. Na koniec umieść kontrolkę Etykieta w sieci Web pod przyciskiem, wyczyść jej Text właściwość i ustaw jej ID właściwość na UploadDetailswartość .

Dodawanie kontrolki FileUpload do strony ASP.NET

Rysunek 12. Dodawanie kontrolki FileUpload do strony ASP.NET (kliknij, aby wyświetlić obraz pełnowymiarowy)

Rysunek 13 przedstawia tę stronę po wyświetleniu za pośrednictwem przeglądarki. Należy pamiętać, że kliknięcie przycisku Przeglądaj powoduje wyświetlenie okna dialogowego wyboru pliku, co umożliwia użytkownikowi wybranie pliku z komputera. Po wybraniu pliku kliknięcie przycisku Przekaż wybrany plik powoduje powrót, który wysyła wybraną zawartość binarną pliku do serwera internetowego.

Użytkownik może wybrać plik do przekazania z komputera na serwer

Rysunek 13. Użytkownik może wybrać plik do przekazania z komputera na serwer (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Po przesłaniu zwrotnym przekazany plik można zapisać w systemie plików lub z danymi binarnymi można pracować bezpośrednio za pośrednictwem usługi Stream. W tym przykładzie utwórzmy ~/Brochures folder i zapiszmy tam przekazany plik. Zacznij od dodania Brochures folderu do witryny jako podfolderu katalogu głównego. Następnie utwórz procedurę obsługi zdarzeń dla UploadButton zdarzenia s Click i dodaj następujący kod:

protected void UploadButton_Click(object sender, EventArgs e)
{
    if (UploadTest.HasFile == false)
    {
        // No file uploaded!
        UploadDetails.Text = "Please first select a file to upload...";            
    }
    else
    {
        // Display the uploaded file's details
        UploadDetails.Text = string.Format(
                @"Uploaded file: {0}<br />
                  File size (in bytes): {1:N0}<br />
                  Content-type: {2}", 
                  UploadTest.FileName, 
                  UploadTest.FileBytes.Length,
                  UploadTest.PostedFile.ContentType);
        // Save the file
        string filePath = 
            Server.MapPath("~/Brochures/" + UploadTest.FileName);
        UploadTest.SaveAs(filePath);
    }
}

Kontrolka FileUpload udostępnia różne właściwości do pracy z przekazanymi danymi. Na przykład właściwość wskazuje,HasFile czy plik został przekazany przez użytkownika, podczas gdy FileBytes właściwość zapewnia dostęp do przekazanych danych binarnych jako tablicy bajtów. Procedura Click obsługi zdarzeń rozpoczyna się od upewnienia się, że plik został przekazany. Jeśli plik został przekazany, etykieta zawiera nazwę przekazanego pliku, jego rozmiar w bajtach i jego typ zawartości.

Uwaga

Aby upewnić się, że użytkownik przekaże plik, możesz sprawdzić HasFile właściwość i wyświetlić ostrzeżenie, jeśli jest to false, lub zamiast tego możesz użyć kontrolki RequiredFieldValidator.

PlikUpload zapisuje SaveAs(filePath) przekazany plik do określonej ścieżki plików. filePath musi być ścieżką fizyczną (C:\Websites\Brochures\SomeFile.pdf), a nie ścieżką wirtualną ()./Brochures/SomeFile.pdf Metoda Server.MapPath(virtPath) przyjmuje ścieżkę wirtualną i zwraca odpowiadającą jej ścieżkę fizyczną. W tym miejscu ścieżka wirtualna to ~/Brochures/fileName, gdzie fileName jest nazwą przekazanego pliku. Aby uzyskać więcej informacji na temat ścieżek wirtualnych i fizycznych, zobacz Server.MapPath Method (Metoda Server.MapPath), aby uzyskać więcej informacji na temat ścieżek wirtualnych i fizycznych oraz używania metody Server.MapPath.

Po zakończeniu obsługi zdarzeń Click pośmiń chwilę na przetestowanie strony w przeglądarce. Kliknij przycisk Przeglądaj i wybierz plik z dysku twardego, a następnie kliknij przycisk Przekaż wybrany plik. Postback wyśle zawartość wybranego pliku na serwer internetowy, który następnie wyświetli informacje o pliku przed zapisaniem go w folderze ~/Brochures . Po przekazaniu pliku wróć do programu Visual Studio i kliknij przycisk Odśwież w Eksplorator rozwiązań. Powinien zostać wyświetlony właśnie przekazany plik w folderze ~/Broszury!

Plik EvolutionValley.jpg został przekazany do serwera sieci Web

Rysunek 14. Plik EvolutionValley.jpg został przekazany do serwera sieci Web (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

EvolutionValley.jpg został zapisany w folderze ~/Broszury

Rysunek 15. EvolutionValley.jpg Zapisano w folderze ~/Brochures

Subtelności z zapisywaniem przekazanych plików do systemu plików

Istnieje kilka subtelności, które należy rozwiązać podczas zapisywania plików przekazywanych do systemu plików serwera internetowego. Po pierwsze, istnieje problem z zabezpieczeniami. Aby zapisać plik w systemie plików, kontekst zabezpieczeń, w którym jest uruchamiana strona ASP.NET, musi mieć uprawnienia do zapisu. Serwer internetowy ASP.NET development działa w kontekście bieżącego konta użytkownika. Jeśli używasz usług Internet Information Services (IIS) firmy Microsoft jako serwera internetowego, kontekst zabezpieczeń zależy od wersji usług IIS i jej konfiguracji.

Innym wyzwaniem zapisania plików w systemie plików jest nazewnictwo plików. Obecnie nasza strona zapisuje wszystkie przekazane pliki do ~/Brochures katalogu przy użyciu tej samej nazwy co plik na komputerze klienckim. Jeśli użytkownik A przekaże broszurę o nazwie Brochure.pdf, plik zostanie zapisany jako ~/Brochure/Brochure.pdf. Ale co zrobić, jeśli jakiś czas później użytkownik B przekaże inny plik broszury, który ma taką samą nazwę pliku (Brochure.pdf)? Po kodzie, który mamy teraz, plik User A zostanie zastąpiony przekazywaniem użytkownika B.

Istnieje wiele technik rozwiązywania konfliktów nazw plików. Jedną z opcji jest zakaz przekazywania pliku, jeśli istnieje już jeden o tej samej nazwie. W przypadku tej metody, gdy użytkownik B próbuje przekazać plik o nazwie Brochure.pdf, system nie zapisze pliku, a zamiast tego wyświetli komunikat informujący użytkownika B o zmianie nazwy pliku i spróbuj ponownie. Innym podejściem jest zapisanie pliku przy użyciu unikatowej nazwy pliku, która może być globalnie unikatowym identyfikatorem (GUID) lub wartością z odpowiednich kolumn klucza podstawowego rekordu bazy danych (przy założeniu, że przekazywanie jest skojarzone z określonym wierszem w modelu danych). W następnym samouczku bardziej szczegółowo zapoznamy się z tymi opcjami.

Wyzwania związane z bardzo dużymi ilościami danych binarnych

W tych samouczkach założono, że przechwycone dane binarne są niewielkie. Praca z bardzo dużymi ilościami plików danych binarnych, które są kilkoma megabajtami lub większymi, wprowadza nowe wyzwania wykraczające poza zakres tych samouczków. Na przykład domyślnie ASP.NET odrzuca przekazywanie więcej niż 4 MB, chociaż można to skonfigurować za pomocą elementu w Web.configprogramie <httpRuntime> . Usługi IIS nakładają również ograniczenia rozmiaru przekazywania plików. Ponadto czas potrzebny na przekazanie dużych plików może przekroczyć domyślne 110 sekund, ASP.NET będzie czekać na żądanie. Występują również problemy z pamięcią i wydajnością występujące podczas pracy z dużymi plikami.

Kontrolka FileUpload jest niepraktyczna w przypadku przekazywania dużych plików. Ponieważ zawartość pliku jest publikowana na serwerze, użytkownik końcowy musi cierpliwie czekać bez potwierdzenia, że ich przekazywanie trwa. Nie jest to tak duży problem podczas pracy z mniejszymi plikami, które można przekazać w ciągu kilku sekund, ale może to być problem podczas pracy z większymi plikami, które mogą potrwać kilka minut. Istnieje wiele kontrolek przekazywania plików innych firm, które lepiej nadają się do obsługi dużych operacji przekazywania, a wielu z tych dostawców zapewnia wskaźniki postępu i menedżerów przekazywania ActiveX, które przedstawiają znacznie bardziej dopracowane środowisko użytkownika.

Jeśli aplikacja musi obsługiwać duże pliki, należy dokładnie zbadać wyzwania i znaleźć odpowiednie rozwiązania dla konkretnych potrzeb.

Podsumowanie

Tworzenie aplikacji, która musi przechwytywać dane binarne, stanowi szereg wyzwań. W tym samouczku zapoznaliśmy się z dwoma pierwszymi: podejmowanie decyzji o tym, gdzie mają być przechowywane dane binarne i umożliwiają użytkownikowi przekazywanie zawartości binarnej za pośrednictwem strony internetowej. W kolejnych trzech samouczkach zobaczymy, jak skojarzyć przekazane dane z rekordem w bazie danych, a także jak wyświetlić dane binarne wraz z polami danych tekstowych.

Szczęśliwe programowanie!

Dalsze informacje

Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:

Informacje o autorze

Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w 24 godzinach. Można go uzyskać pod adresem mitchell@4GuysFromRolla.com. lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.

Specjalne podziękowania

Ta seria samouczków została omówiona przez wielu przydatnych recenzentów. Recenzenci w tym samouczku to Teresa Murphy i Bernadette Leigh. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.