Yeni Kayıt Eklerken Karşıya Dosya Yükleme Seçeneği Ekleme (VB)

tarafından Scott Mitchell

PDF’yi İndir

Bu öğreticide, kullanıcının hem metin verileri girmesini hem de ikili dosyaları karşıya yüklemesini sağlayan bir Web arabiriminin nasıl oluşturulacağı gösterilmektedir. İkili verileri depolamak için kullanılabilen seçenekleri göstermek için, bir dosya veritabanına kaydedilirken diğeri dosya sisteminde depolanır.

Giriş

Önceki iki öğreticide, uygulamanın veri modeliyle ilişkili ikili verileri depolama tekniklerini inceledik, dosya istemciden web sunucusuna dosya göndermek için DosyaYükle denetiminin nasıl kullanılacağını inceledik ve bu ikili verilerin bir veri Web denetiminde nasıl sunıldığını gördük. Ancak karşıya yüklenen verilerin veri modeliyle nasıl ilişkilendirildiğinden henüz söz ettik.

Bu öğreticide yeni bir kategori eklemek için bir web sayfası oluşturacağız. Kategorinin adı ve açıklaması için TextBoxes'e ek olarak, bu sayfada biri yeni kategori resmi, diğeri broşür için olmak üzere iki FileUpload denetimi bulunacaktır. Karşıya yüklenen resim doğrudan yeni kaydın sütununda depolanırken, broşür yeni kayıt PictureBrochurePath sütununa kaydedilen dosyanın yolunu içeren klasöre kaydedilir~/Brochures.

Bu yeni web sayfasını oluşturmadan önce mimariyi güncelleştirmemiz gerekir. S CategoriesTableAdapter ana sorgusu sütunu almaz Picture . Sonuç olarak, otomatik oluşturulan Insert yöntem yalnızca , Descriptionve BrochurePath alanları için CategoryNamegirişlere sahiptir. Bu nedenle, TableAdapter'da dört Categories alanın tümünü isteyen ek bir yöntem oluşturmamız gerekir. CategoriesBLL İş Mantığı Katmanı'ndaki sınıfın da güncelleştirilmiş olması gerekir.

1. Adım: yöntemine yöntemInsertWithPictureeklemeCategoriesTableAdapter

Veri Erişim Katmanı Oluşturma öğreticisinde gerisini oluşturduğunuzdaCategoriesTableAdapter, bunu ana sorguyu temel alan , UPDATEve DELETE deyimlerini otomatik olarak oluşturacak INSERTşekilde yapılandırdık. Ayrıca, TableAdapter'a , ve yöntemlerini Insertoluşturan DOĞRUDAN VERITABANı yaklaşımını kullanma talimatını verdikDelete. Update Bu yöntemler otomatik olarak oluşturulan INSERT, UPDATEve DELETE deyimlerini yürütür ve sonuç olarak ana sorgu tarafından döndürülen sütunlara göre giriş parametrelerini kabul eder. Dosyaları Karşıya Yükleme öğreticisinde s ana sorgusunu CategoriesTableAdapter sütunu kullanacak BrochurePath şekilde genişlettik.

Ana sorgu sütuna CategoriesTableAdapterPicture başvurmadığından ne yeni kayıt ekleyebilir ne de mevcut bir kaydı sütun için Picture bir değerle güncelleştirebiliriz. Bu bilgileri yakalamak için TableAdapter'da özel olarak ikili veri içeren bir kayıt eklemek için kullanılan yeni bir yöntem oluşturabilir veya otomatik olarak oluşturulan INSERT deyimi özelleştirebiliriz. Otomatik oluşturulan INSERT deyimi özelleştirmeyle ilgili sorun, özelleştirmelerimizin sihirbaz tarafından üzerine yazılmasını riske atmış olmamızdır. Örneğin, deyimini sütunun INSERT kullanımını içerecek şekilde özelleştirdiğimizi Picture düşünün. Bu, TableAdapter s yöntemini kategori resminin Insert ikili verileri için ek bir giriş parametresi içerecek şekilde güncelleştirir. Daha sonra bu DAL yöntemini kullanmak ve bu BLL yöntemini Sunu Katmanı aracılığıyla çağırmak için İş Mantığı Katmanı'nda bir yöntem oluşturabiliriz ve her şey harika çalışır. Yani, TableAdapter Yapılandırma sihirbazı aracılığıyla TableAdapter'ı bir sonraki yapılandırışımıza kadar. Sihirbaz tamamlanır tamamlanmaz deyimdeki INSERT özelleştirmelerimizin üzerine yazılır, Insert yöntem eski biçimine döner ve kodumuz artık derlenmez!

Not

Geçici SQL deyimleri yerine saklı yordamlar kullanılırken bu sorun değildir. Gelecekteki bir öğreticide, Veri Erişim Katmanı'ndaki geçici SQL deyimleri yerine saklı yordamları kullanmayı keşfedeceğiz.

Bu olası baş ağrısından kaçınmak için, otomatik olarak oluşturulan SQL deyimlerini özelleştirmek yerine TableAdapter için yeni bir yöntem oluşturalım. adlı InsertWithPicturebu yöntem, , Description, BrochurePathve sütunları için CategoryNamedeğerleri kabul eder ve Picture dört değerin tümünü yeni bir kayıtta depolayan bir deyimi yürütürINSERT.

Yazılan Veri Kümesi'ni açın ve Tasarım Aracı s üst bilgisine CategoriesTableAdapter sağ tıklayın ve bağlam menüsünden Sorgu Ekle'yi seçin. Bu, TableAdapter sorgusunun veritabanına nasıl erişmesi gerektiğini sorarak başlayan TableAdapter Sorgu Yapılandırma Sihirbazı'nı başlatır. SQL deyimlerini kullan'ı seçin ve İleri'ye tıklayın. Sonraki adım, oluşturulacak sorgu türünü ister. Tabloya yeni kayıt eklemek için sorgu oluşturduğumuz için Categories EKLE'yi seçin ve İleri'ye tıklayın.

EKLE Seçeneğini Belirleyin

Şekil 1: EKLE Seçeneğini belirtin (tam boyutlu görüntüyü görüntülemek için tıklayın)

Şimdi SQL deyimini INSERT belirtmemiz gerekiyor. Sihirbaz otomatik olarak TableAdapter ana sorgusuna karşılık gelen bir INSERT deyim önerir. Bu durumda, , Descriptionve BrochurePath değerlerini ekleyen CategoryNamebir INSERT deyimdir. deyimini, sütunun Picture bir @Picture parametreyle birlikte eklenmesi için güncelleştirin, örneğin:

INSERT INTO [Categories] 
    ([CategoryName], [Description], [BrochurePath], [Picture]) 
VALUES 
    (@CategoryName, @Description, @BrochurePath, @Picture)

Sihirbazın son ekranı yeni TableAdapter yöntemini adlandırmamızı ister. Girin InsertWithPicture ve Son'a tıklayın.

Yeni TableAdapter Yöntemini InsertWithPicture Olarak Adlandırın

Şekil 2: Yeni TableAdapter Yöntemini Adlandırın InsertWithPicture (Tam boyutlu görüntüyü görüntülemek için tıklayın)

2. Adım: İş Mantığı Katmanını Güncelleştirme

Sunu Katmanı doğrudan Veri Erişim Katmanı'na gitmek için atlamak yerine yalnızca İş Mantığı Katmanı ile arabirim oluşturması gerektiğinden, az önce oluşturduğumuz DAL yöntemini çağıran bir BLL yöntemi oluşturmamız gerekir (InsertWithPicture). Bu öğretici için CategoriesBLL sınıfında, giriş üç String s ve bir dizi olarak kabul eden adlı InsertWithPicture bir Byte yöntem oluşturun. Giriş String parametreleri kategorinin adı, açıklaması ve broşür dosya yolu için, dizi ise Byte kategori resminin ikili içeriğine yöneliktir. Aşağıdaki kodda gösterildiği gibi, bu BLL yöntemi ilgili DAL yöntemini çağırır:

<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Insert, False)> _
Public Sub InsertWithPicture(categoryName As String, description As String, _
    brochurePath As String, picture() As Byte)
    
    Adapter.InsertWithPicture(categoryName, description, brochurePath, picture)
End Sub

Not

Yöntemini BLL'ye eklemeden önce Typed DataSet'i InsertWithPicture kaydettiğinizden emin olun. CategoriesTableAdapter Sınıf kodu Typed DataSet'e dayalı olarak otomatik olarak oluşturulduğundan, değişikliklerinizi önce Türlenmiş Veri Kümesi'ne Adapter kaydetmezseniz özelliği yöntem hakkında InsertWithPicture bilgi sahibi olmaz.

3. Adım: Mevcut Kategorileri ve bunların İkili Verilerini Listeleme

Bu öğreticide, son kullanıcının sisteme yeni bir kategori eklemesine olanak tanıyan ve yeni kategori için bir resim ve broşür sağlayan bir sayfa oluşturacağız. Önceki öğreticide, her kategorinin adını, açıklamasını, resmini ve broşürünü indirme bağlantısını görüntülemek için TemplateField ve ImageField içeren bir GridView kullandık. Şimdi bu öğreticinin işlevselliğini çoğaltalım ve hem mevcut kategorileri listeleyen hem de yeni kategorilerin oluşturulmasına izin veren bir sayfa oluşturalım.

İlk olarak klasörden DisplayOrDownload.aspx sayfayı BinaryData açın. Kaynak görünümüne gidin ve GridView ve ObjectDataSource bildirim temelli söz dizimini kopyalayıp içindeki öğesinin <asp:Content>UploadInDetailsView.aspxiçine yapıştırın. Ayrıca, öğesinin code-behind sınıfından GenerateBrochureLinkDisplayOrDownload.aspx yöntemine kopyalamayı UploadInDetailsView.aspxunutmayın.

Bildirim Temelli Söz Dizimini DisplayOrDownload.aspx UploadInDetailsView.aspx Kopyalayıp Yapıştırın

Şekil 3: Bildirim Temelli Söz Dizimini 'den DisplayOrDownload.aspx kopyalayıp yapıştırın UploadInDetailsView.aspx (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Bildirim temelli söz dizimini ve GenerateBrochureLink yöntemi sayfaya UploadInDetailsView.aspx kopyaladıktan sonra, her şeyin doğru şekilde kopyalanmasını sağlamak için sayfayı bir tarayıcı üzerinden görüntüleyin. Broşürü ve kategori resmini indirme bağlantısını içeren sekiz kategoriyi listeleyen bir GridView görmeniz gerekir.

Şimdi her kategoriyi ikili verileriyle birlikte görmeniz gerekir

Şekil 4: Artık Her Kategoriyi İkili Verileriyle Birlikte Görmeniz Gerekir (Tam boyutlu görüntüyü görüntülemek için tıklayın)

4. Adım: Ekleme DesteğiCategoriesDataSourceİçin Yapılandırma

CategoriesDataSource GridView tarafından Categories kullanılan ObjectDataSource şu anda veri ekleme olanağı sağlamaz. Bu veri kaynağı denetimi aracılığıyla eklemeyi desteklemek için yöntemini temel alınan nesnesindeki CategoriesBLLbir yöntemle eşlememiz Insert gerekir. Özellikle, 2InsertWithPicture. Adımda geri eklediğimiz yöntemle eşlemek CategoriesBLL istiyoruz.

ObjectDataSource'un akıllı etiketinden Veri Kaynağını Yapılandır bağlantısına tıklayarak başlayın. İlk ekranda, veri kaynağının çalışmak CategoriesBLLüzere yapılandırıldığı nesne gösterilir. Bu ayarı olduğu gibi bırakın ve İleri'ye tıklayarak Veri Yöntemlerini Tanımla ekranına ilerleyin. INSERT sekmesine gidin ve açılan listeden yöntemini seçin InsertWithPicture . Sihirbazı tamamlamak için Son’a tıklayın.

ObjectDataSource'ı InsertWithPicture Yöntemini kullanacak şekilde yapılandırma

Şekil 5: ObjectDataSource'un Yöntemini kullanacak şekilde yapılandırılması InsertWithPicture (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Not

Sihirbazı tamamladıktan sonra Visual Studio, Veri Web denetimleri alanlarını yeniden oluşturacak Olan Alanları ve Anahtarları Yenilemek isteyip istemediğinizi sorabilir. Evet'i seçtiğinizde yapmış olabileceğiniz alan özelleştirmelerinin üzerine yazılacağından Hayır'ı seçin.

Sihirbazı tamamladıktan sonra, ObjectDataSource şimdi özelliği InsertParameters için InsertMethod ve aşağıdaki bildirim temelli işaretlemede gösterildiği gibi dört kategori sütunu için bir değer içerecektir:

<asp:ObjectDataSource ID="CategoriesDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}" SelectMethod="GetCategories" 
    TypeName="CategoriesBLL" InsertMethod="InsertWithPicture">
    <InsertParameters>
        <asp:Parameter Name="categoryName" Type="String" />
        <asp:Parameter Name="description" Type="String" />
        <asp:Parameter Name="brochurePath" Type="String" />
        <asp:Parameter Name="picture" Type="Object" />
    </InsertParameters>
</asp:ObjectDataSource>

5. Adım: Ekleme Arabirimi Oluşturma

İlk olarak Veri Ekleme, Güncelleştirme ve Silmeye Genel Bakış bölümünde ele alınan DetailsView denetimi, eklemeyi destekleyen bir veri kaynağı denetimiyle çalışırken kullanılabilecek yerleşik bir ekleme arabirimi sağlar. Kullanıcının hızla yeni bir kategori eklemesine olanak tanıyarak ekleme arabirimini kalıcı olarak işleyecek olan GridView'un üzerine bu sayfaya bir DetailsView denetimi ekleyelim. DetailsView'a yeni bir kategori eklendikten sonra, altındaki GridView otomatik olarak yenilenir ve yeni kategoriyi görüntüler.

Bir DetailsView'ı Araç Kutusu'ndan GridView'ın üzerindeki Tasarım Aracı sürükleyerek başlayın, özelliğini olarak ayarlayın ID ve ve Width özellik değerlerini temizleyinHeight.NewCategory DetailsView akıllı etiketinden var olan CategoriesDataSource etikete bağlayın ve Eklemeyi Etkinleştir onay kutusunu işaretleyin.

CategoryID özelliğinin NewCategory olarak ayarlandığı, Height ve Width özellik değerlerinin boş olduğu ve Eklemeyi Etkinleştir onay kutusunun seçili olduğu DetailsView'ın ekran görüntüsü.

Şekil 6: DetailsView'ı ve Eklemeyi Etkinleştir'e CategoriesDataSource bağlama (Tam boyutlu görüntüyü görüntülemek için tıklayın)

DetailsView'ı ekleme arabiriminde kalıcı olarak işlemek için özelliğini olarak InsertayarlayınDefaultMode.

Özelliği olarak ayarlandığındanFalse, Ekleme arabiriminde InsertVisible BoundField işlenmese de CategoryID DetailsView'da beş BoundField CategoryID, CategoryNameDescription, , NumberOfProductsve BrochurePath olduğunu unutmayın. Bu BoundField'ler, ObjectDataSource'un verilerini almak için çağırdığı yöntem tarafından GetCategories() döndürülen sütunlar olduğundan var olur. Ancak ekleme için kullanıcının için NumberOfProductsbir değer belirtmesine izin vermek istemiyoruz. Ayrıca, yeni kategori için resim yüklemelerine ve broşür için PDF yüklemelerine izin vermemiz gerekir.

NumberOfProducts DetailsView'dan BoundField öğesini tamamen kaldırın ve ardından ve BrochurePath BoundFields özelliklerini CategoryName sırasıyla Category ve Broşür olarak güncelleştirinHeaderText. Ardından, BoundField'i BrochurePath TemplateField'e dönüştürün ve resim için yeni bir TemplateField ekleyin ve bu yeni TemplateField'e HeaderText Resim değeri sağlayın. TemplateField'i Picture TemplateField ile CommandField arasında BrochurePath olacak şekilde taşıyın.

TemplateField, Picture ve HeaderText seçeneklerinin vurgulandığı alanlar penceresini gösteren ekran görüntüsü.

Şekil 7: DetailsView'ı ve Eklemeyi Etkinleştir'e CategoriesDataSource bağlama

Alanları Düzenle iletişim kutusu aracılığıyla BoundField'i TemplateField'e dönüştürdüyseniz BrochurePath , TemplateField bir ItemTemplate, EditItemTemplateve InsertItemTemplateiçerir. Ancak yalnızca gerekli InsertItemTemplate olduğu için diğer iki şablonu kaldırmaktan çekinmeyin. Bu noktada DetailsView'unuzun bildirim temelli söz dizimi aşağıdaki gibi görünmelidir:

<asp:DetailsView ID="NewCategory" runat="server" AutoGenerateRows="False" 
    DataKeyNames="CategoryID" DataSourceID="CategoriesDataSource" 
    DefaultMode="Insert">
    <Fields>
        <asp:BoundField DataField="CategoryID" HeaderText="CategoryID" 
            InsertVisible="False" ReadOnly="True" 
            SortExpression="CategoryID" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category" 
            SortExpression="CategoryName" />
        <asp:BoundField DataField="Description" HeaderText="Description" 
            SortExpression="Description" />
        <asp:TemplateField HeaderText="Brochure" SortExpression="BrochurePath">
            <InsertItemTemplate>
                <asp:TextBox ID="TextBox1" runat="server"
                    Text='<%# Bind("BrochurePath") %>'></asp:TextBox>
            </InsertItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Picture"></asp:TemplateField>
        <asp:CommandField ShowInsertButton="True" />
    </Fields>
</asp:DetailsView>

Broşür ve Resim Alanları için DosyaYükleme Denetimleri Ekleme

Şu anda BrochurePath TemplateField'ler InsertItemTemplate bir TextBox içerirken Picture TemplateField herhangi bir şablon içermez. FileUpload denetimlerini kullanmak için bu iki TemplateField InsertItemTemplate öğesini güncelleştirmemiz gerekiyor.

DetailsView akıllı etiketinden Şablonları Düzenle seçeneğini belirleyin ve ardından açılan listeden TemplateField'leri InsertItemTemplate seçinBrochurePath. TextBox'ı kaldırın ve araç kutusundan fileupload denetimini şablona sürükleyin. FileUpload denetimini olarak IDBrochureUploadayarlayın. Benzer şekilde, TemplateField's InsertItemTemplateöğesine Picture bir FileUpload denetimi ekleyin. Bu FileUpload denetimini olarak IDPictureUploadayarlayın.

InsertItemTemplate'a FileUpload Denetimi Ekleme

Şekil 8: Dosyasına FileUpload Denetimi InsertItemTemplate Ekleme (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Bu eklemeleri yaptıktan sonra, iki TemplateField bildirim temelli söz dizimi olacaktır:

<asp:TemplateField HeaderText="Brochure" SortExpression="BrochurePath">
    <InsertItemTemplate>
        <asp:FileUpload ID="BrochureUpload" runat="server" />
    </InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Picture">
    <InsertItemTemplate>
        <asp:FileUpload ID="PictureUpload" runat="server" />
    </InsertItemTemplate>
</asp:TemplateField>

Kullanıcı yeni bir kategori eklediğinde, broşür ve resmin doğru dosya türünde olduğundan emin olmak istiyoruz. Broşür için kullanıcının bir PDF sağlaması gerekir. Resim için kullanıcının bir görüntü dosyasını karşıya yüklemesine ihtiyacımız var, ancak herhangi bir görüntü dosyasına mı yoksa yalnızca GIF veya JPG gibi belirli bir türdeki görüntü dosyalarına mı izin veririz? Farklı dosya türlerine izin vermek için, şemayı Categories dosya türünü yakalayan bir sütun içerecek şekilde genişletmemiz gerekir; böylece bu tür istemciye içinde DisplayCategoryPicture.aspxaracılığıyla Response.ContentType gönderilebilir. Böyle bir sütuna sahip olmadığımıza göre, kullanıcıların yalnızca belirli bir görüntü dosyası türünü sağlamasını kısıtlamak akıllıca olacaktır. Tablonun Categories mevcut görüntüleri bit eşlemlerdir, ancak JPG'ler web üzerinden sunulan görüntüler için daha uygun bir dosya biçimidir.

Bir kullanıcı yanlış bir dosya türünü karşıya yüklerse, ekleme işlemini iptal edip sorunu belirten bir ileti görüntülememiz gerekir. DetailsView altına bir Label Web denetimi ekleyin. ID özelliğini olarak UploadWarningayarlayın, özelliğini temizleyinText, özelliğini Uyarı olarak, Visible ve EnableViewState özelliklerini olarak FalseayarlayınCssClass. Warning CSS sınıfı içinde Styles.css tanımlanır ve metni büyük, kırmızı, italik, kalın yazı tipinde işler.

Not

İdeal olarak, CategoryName ve Description BoundField'ler TemplateFields'e dönüştürülür ve arabirimleri özelleştirilir. Description Örneğin ekleme arabirimi, çok satırlı bir metin kutusu aracılığıyla daha uygun olabilir. CategoryName Sütun değerleri kabul NULL etmediğinden, kullanıcının yeni kategori adı için bir değer sağladığından emin olmak için bir RequiredFieldValidator eklenmelidir. Bu adımlar okuyucuya alıştırma olarak bırakılır. Veri değişikliği arabirimlerini artırmaya ayrıntılı bir bakış için Veri Değiştirme Arabirimini Özelleştirme bölümüne geri dönün.

6. Adım: Karşıya Yüklenen Broşürü Web Sunucusu Dosya Sistemine Kaydetme

Kullanıcı yeni bir kategorinin değerlerini girip Ekle düğmesine tıkladığında bir geri gönderme gerçekleşir ve ekleme iş akışı açılır. İlk olarak DetailsView olayıItemInserting tetikler. Ardından ObjectDataSource Insert() yöntemi çağrılır ve bu da tabloya yeni bir kayıt eklenmesine Categories neden olur. Bundan sonra DetailsView olayıItemInserted tetikler.

ObjectDataSource Insert() yöntemi çağrılmadan önce kullanıcı tarafından uygun dosya türlerinin yüklendiğinden emin olmalı ve sonra broşür PDF dosyasını web sunucusunun dosya sistemine kaydetmeliyiz. DetailsView ItemInserting olayı için bir olay işleyicisi oluşturun ve aşağıdaki kodu ekleyin:

' Reference the FileUpload controls
Dim BrochureUpload As FileUpload = _
    CType(NewCategory.FindControl("BrochureUpload"), FileUpload)
If BrochureUpload.HasFile Then
    ' Make sure that a PDF has been uploaded
    If String.Compare(System.IO.Path.GetExtension _
        (BrochureUpload.FileName), ".pdf", True) <> 0 Then
        UploadWarning.Text = _
            "Only PDF documents may be used for a category's brochure."
        UploadWarning.Visible = True
        e.Cancel = True
        Exit Sub
    End If
End If

Olay işleyicisi, DetailsView şablonlarından BrochureUpload FileUpload denetimine başvurarak başlar. Ardından, bir broşür karşıya yüklendiyse, karşıya yüklenen dosyanın uzantısı incelenmiştir. Uzantı .PDF değilse bir uyarı görüntülenir, ekleme iptal edilir ve olay işleyicisinin yürütülmesi sona erer.

Not

Karşıya yüklenen dosyanın uzantısına güvenmek, karşıya yüklenen dosyanın bir PDF belgesi olduğundan emin olmak için kesin bir yöntem değildir. Kullanıcının uzantısına .Brochuresahip geçerli bir PDF belgesi olabilir veya PDF olmayan bir belge alıp uzantı vermiş .pdf olabilir. Dosya türünü daha kesin bir şekilde doğrulamak için dosyanın ikili içeriğinin program aracılığıyla incelenmesi gerekir. Ancak bu tür kapsamlı yaklaşımlar genellikle aşırıya kaçmaktadır; uzantıyı denetlemek çoğu senaryo için yeterlidir.

Dosyaları Karşıya Yükleme öğreticisinde açıklandığı gibi, bir kullanıcının karşıya yüklemesinin başka bir kullanıcının üzerine yazmaması için dosyaları dosya sistemine kaydederken dikkatli olunması gerekir. Bu öğretici için karşıya yüklenen dosyayla aynı adı kullanmayı deneyeceğiz. Ancak dizinde ~/Brochures aynı dosya adına sahip bir dosya zaten varsa, benzersiz bir ad bulunana kadar sonuna bir sayı ekleriz. Örneğin, kullanıcı adlı Meats.pdfbir broşür dosyasını karşıya yüklerse ancak klasörde adlı Meats.pdf~/Brochures bir dosya zaten varsa, kaydedilen dosya adını Meats-1.pdfolarak değiştiririz. Bu varsa, benzersiz bir dosya adı bulunana kadar , vb. deneyeceğiz Meats-2.pdf.

Aşağıdaki kod, File.Exists(path) belirtilen dosya adına sahip bir dosyanın zaten mevcut olup olmadığını belirlemek için yöntemini kullanır. Bu durumda, çakışma bulunıncaya kadar broşür için yeni dosya adlarını denemeye devam eder.

Const BrochureDirectory As String = "~/Brochures/"
Dim brochurePath As String = BrochureDirectory & BrochureUpload.FileName
Dim fileNameWithoutExtension As String = _
    System.IO.Path.GetFileNameWithoutExtension(BrochureUpload.FileName)
Dim iteration As Integer = 1
While System.IO.File.Exists(Server.MapPath(brochurePath))
    brochurePath = String.Concat(BrochureDirectory, _
        fileNameWithoutExtension, "-", iteration, ".pdf")
    iteration += 1
End While

Geçerli bir dosya adı bulunduktan sonra dosyanın dosya sistemine kaydedilmesi ve ObjectDataSource brochurePath``InsertParameter değerinin bu dosya adının veritabanına yazılması için güncelleştirilmesi gerekir. Dosyaları Karşıya Yükleme öğreticisinde gördüğümüz gibi, dosya FileUpload denetimi s SaveAs(path) yöntemi kullanılarak kaydedilebilir. ObjectDataSource brochurePath parametresini güncelleştirmek için koleksiyonunu kullanın e.Values .

' Save the file to disk and set the value of the brochurePath parameter
BrochureUpload.SaveAs(Server.MapPath(brochurePath))
e.Values("brochurePath") = brochurePath

7. Adım: Karşıya Yüklenen Resmi Veritabanına Kaydetme

Karşıya yüklenen resmi yeni Categories kayıtta depolamak için, karşıya yüklenen ikili içeriği DetailsView s ItemInserting olayında ObjectDataSource picture parametresine atamamız gerekir. Ancak bu ödevi yapmadan önce karşıya yüklenen resmin başka bir görüntü türü değil JPG olduğundan emin olmamız gerekir. 6. Adım'da olduğu gibi, türünü belirlemek için karşıya yüklenen resmin dosya uzantısını kullanalım.

Categories Tablo sütun için değerlere Picture izin verirkenNULL, tüm kategorilerde şu anda bir resim vardır. Bu sayfa aracılığıyla yeni bir kategori eklerken kullanıcıyı resim sağlamaya zorlayalım. Aşağıdaki kod, bir resmin karşıya yüklendiğinden ve uygun bir uzantıya sahip olduğundan emin olmak için denetler.

' Reference the FileUpload controls
Dim PictureUpload As FileUpload = _
    CType(NewCategory.FindControl("PictureUpload"), FileUpload)
If PictureUpload.HasFile Then
    ' Make sure that a JPG has been uploaded
    If  String.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), _
            ".jpg", True) <> 0 AndAlso _
        String.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), _
            ".jpeg", True) <> 0 Then
        
        UploadWarning.Text = _
            "Only JPG documents may be used for a category's picture."
        UploadWarning.Visible = True
        e.Cancel = True
        Exit Sub
    End If
Else
    ' No picture uploaded!
    UploadWarning.Text = _
        "You must provide a picture for the new category."
    UploadWarning.Visible = True
    e.Cancel = True
    Exit Sub
End If

Bu kod, 6. Adımdaki koddan önce yerleştirilmelidir, böylece resim karşıya yüklemeyle ilgili bir sorun varsa, broşür dosyası dosya sistemine kaydedilmeden önce olay işleyicisi sonlandırılır.

Uygun bir dosyanın karşıya yüklendiğini varsayarsak, karşıya yüklenen ikili içeriği aşağıdaki kod satırıyla picture parametresinin değerine atayın:

' Set the value of the picture parameter
e.Values("picture") = PictureUpload.FileBytes

TamItemInsertingOlay İşleyicisi

Tamlık için olay işleyicisi tam olarak aşağıdadır ItemInserting :

Protected Sub NewCategory_ItemInserting _
    (sender As Object, e As DetailsViewInsertEventArgs) _
    Handles NewCategory.ItemInserting
    
    ' Reference the FileUpload controls
    Dim PictureUpload As FileUpload = _
        CType(NewCategory.FindControl("PictureUpload"), FileUpload)
    If PictureUpload.HasFile Then
        ' Make sure that a JPG has been uploaded
        If  String.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), _
                ".jpg", True) <> 0 AndAlso _
            String.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), _
                ".jpeg", True) <> 0 Then
            
            UploadWarning.Text = _
                "Only JPG documents may be used for a category's picture."
            UploadWarning.Visible = True
            e.Cancel = True
            Exit Sub
        End If
    Else
        ' No picture uploaded!
        UploadWarning.Text = _
            "You must provide a picture for the new category."
        UploadWarning.Visible = True
        e.Cancel = True
        Exit Sub
    End If
    ' Set the value of the picture parameter
    e.Values("picture") = PictureUpload.FileBytes
    ' Reference the FileUpload controls
    Dim BrochureUpload As FileUpload = _
        CType(NewCategory.FindControl("BrochureUpload"), FileUpload)
    If BrochureUpload.HasFile Then
        ' Make sure that a PDF has been uploaded
        If String.Compare(System.IO.Path.GetExtension(BrochureUpload.FileName), _
            ".pdf", True) <> 0 Then
            
            UploadWarning.Text = _
                "Only PDF documents may be used for a category's brochure."
            UploadWarning.Visible = True
            e.Cancel = True
            Exit Sub
        End If
        Const BrochureDirectory As String = "~/Brochures/"
        Dim brochurePath As String = BrochureDirectory & BrochureUpload.FileName
        Dim fileNameWithoutExtension As String = _
            System.IO.Path.GetFileNameWithoutExtension(BrochureUpload.FileName)
        Dim iteration As Integer = 1
        While System.IO.File.Exists(Server.MapPath(brochurePath))
            brochurePath = String.Concat(BrochureDirectory, _
                fileNameWithoutExtension, "-", iteration, ".pdf")
            iteration += 1
        End While
        ' Save the file to disk and set the value of the brochurePath parameter
        BrochureUpload.SaveAs(Server.MapPath(brochurePath))
        e.Values("brochurePath") = brochurePath
    End If
End Sub

8. Adım: SayfayıDisplayCategoryPicture.aspxDüzeltme

Son birkaç adımda oluşturulan ekleme arabirimini ve ItemInserting olay işleyicisini test etmek için biraz zaman ayıralım. Tarayıcı üzerinden sayfayı UploadInDetailsView.aspx ziyaret edin ve kategori eklemeyi deneyip resmi atlayarak JPG olmayan bir resim veya PDF olmayan bir broşür belirtin. Bu durumlarda bir hata iletisi görüntülenir ve ekleme iş akışı iptal edilir.

Geçersiz Bir Dosya Türü Karşıya Yüklenirse Bir Uyarı İletisi Görüntülenir

Şekil 9: Geçersiz Bir Dosya Türü Karşıya Yüklendiyse Bir Uyarı İletisi Görüntüleniyor (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Sayfanın karşıya bir resim yüklenmesi gerektiğini ve PDF olmayan veya JPG olmayan dosyaları kabul etmeyeceğini doğruladıktan sonra geçerli bir JPG resmi içeren yeni bir kategori ekleyin ve Broşür alanını boş bırakın. Ekle düğmesine tıkladıktan sonra sayfa geri yüklenir ve karşıya yüklenen görüntünün ikili içeriği doğrudan veritabanında depolanmış şekilde tabloya yeni bir kayıt eklenir Categories . GridView güncelleştirilir ve yeni eklenen kategori için bir satır gösterir, ancak Şekil 10'da gösterildiği gibi yeni kategori resmi doğru işlenmez.

Yeni Kategori resmi görüntülenmiyor

Şekil 10: Yeni Kategori resmi görüntülenmiyor (tam boyutlu resmi görüntülemek için tıklayın)

Yeni resmin görüntülenmeme nedeni, belirtilen kategorinin DisplayCategoryPicture.aspx resmini döndüren sayfanın OLE üst bilgisine sahip bit eşlemleri işleyecek şekilde yapılandırılmasıdır. Bu 78 baytlık üst bilgi, istemciye geri gönderilmeden önce sütunun Picture ikili içeriğinden çıkarılır. Ancak yeni kategori için karşıya yüklediğimiz JPG dosyasında bu OLE üst bilgisi yok; bu nedenle, görüntünün ikili verilerinden geçerli, gerekli baytlar kaldırılıyor.

Artık tabloda HEM OLE üst bilgileri hem de JPG'ler Categories içeren bit eşlemler bulunduğundan, özgün sekiz kategori için OLE üst bilgisinin çıkarılıp yeni kategori kayıtları için bu striptiz işlemini atlayacak şekilde güncelleştirmemiz DisplayCategoryPicture.aspx gerekir. Sonraki öğreticimizde mevcut bir kaydın görüntüsünün nasıl güncelleştirildiğini inceleyecek ve tüm eski kategori resimlerini JPG olacak şekilde güncelleştireceğiz. Şimdilik, ole üst bilgilerini yalnızca özgün sekiz kategori için şerit için aşağıdaki kodu DisplayCategoryPicture.aspx kullanın:

Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    Dim categoryID As Integer = Convert.ToInt32(Request.QueryString("CategoryID"))
    ' Get information about the specified category
    Dim categoryAPI As New CategoriesBLL()
    Dim categories As Northwind.CategoriesDataTable = _
        categoryAPI.GetCategoryWithBinaryDataByCategoryID(categoryID)
    Dim category As Northwind.CategoriesRow = categories(0)
    If categoryID <= 8 Then
        ' Output HTTP headers providing information about the binary data
        Response.ContentType = "image/bmp"
        ' Output the binary data
        ' But first we need to strip out the OLE header
        Const OleHeaderLength As Integer = 78
        Dim strippedImageLength As Integer = _
            category.Picture.Length - OleHeaderLength
        Dim strippedImageData(strippedImageLength) As Byte
        Array.Copy(category.Picture, OleHeaderLength, _
            strippedImageData, 0, strippedImageLength)
        Response.BinaryWrite(strippedImageData)
    Else
        ' For new categories, images are JPGs...
        ' Output HTTP headers providing information about the binary data
        Response.ContentType = "image/jpeg"
        ' Output the binary data
        Response.BinaryWrite(category.Picture)
    End If
End Sub

Bu değişiklikle JPG görüntüsü artık GridView'da doğru şekilde işlenir.

Yeni Kategoriler için JPG Görüntüleri Doğru İşleniyor

Şekil 11: Yeni Kategoriler için JPG Görüntüleri Doğru İşleniyor (Tam boyutlu görüntüyü görüntülemek için tıklayın)

9. Adım: Özel Durumun Karşısında Broşürü Silme

İkili verileri web sunucusunun dosya sisteminde depolamanın zorluklarından biri, veri modeliyle ikili verileri arasında bir bağlantı kesilmesine neden olmasıdır. Bu nedenle, bir kayıt her silindiğinde, dosya sistemindeki ilgili ikili verilerin de kaldırılması gerekir. Bu, ekleme sırasında da devreye girer. Aşağıdaki senaryoyu göz önünde bulundurun: Kullanıcı, geçerli bir resim ve broşür belirterek yeni bir kategori ekler. Ekle düğmesine tıkladıktan sonra bir geri gönderme gerçekleşir ve DetailsView ItemInserting olayı tetiklenip broşürü web sunucusunun dosya sistemine kaydeder. Daha sonra, s yöntemini çağıran sınıfın CategoriesBLLInsertWithPicture yöntemini çağıran CategoriesTableAdapterInsertWithPicture ObjectDataSource Insert() yöntemi çağrılır.

Şimdi veritabanı çevrimdışıysa veya SQL deyiminde INSERT bir hata varsa ne olur? INSERT başarısız olacağı açıktır, bu nedenle veritabanına yeni kategori satırı eklenmez. Ancak web sunucusunun dosya sisteminde yüklü broşür dosyası hala var! Ekleme iş akışı sırasında bir özel durum karşısında bu dosyanın silinmesi gerekir.

Daha önce bir ASP.NET Sayfasında BLL- ve DAL-Level Özel Durumlarını İşleme öğreticisinde açıklandığı gibi, mimarinin derinliklerinden bir özel durum oluştuğunda çeşitli katmanlarda kabarır. Sunu Katmanı'nda DetailsView ItemInserted olayından bir özel durum olup olmadığını belirleyebiliriz. Bu olay işleyicisi, ObjectDataSource değerlerini InsertParametersde sağlar. Bu nedenle, bir özel durum olup olmadığını denetleen ve varsa ObjectDataSource brochurePath parametresi tarafından belirtilen dosyayı silecek olay için ItemInserted bir olay işleyicisi oluşturabiliriz:

Protected Sub NewCategory_ItemInserted _
    (sender As Object, e As DetailsViewInsertedEventArgs) _
    Handles NewCategory.ItemInserted
    
    If e.Exception IsNot Nothing Then
        ' Need to delete brochure file, if it exists
        If e.Values("brochurePath") IsNot Nothing Then
            System.IO.File.Delete(Server.MapPath _
                (e.Values("brochurePath").ToString()))
        End If
    End If
End Sub

Özet

İkili veri içeren kayıtlar eklemek için web tabanlı bir arabirim sağlamak için gerçekleştirilmesi gereken birkaç adım vardır. İkili veriler doğrudan veritabanına depolanıyorsa, ikili verilerin eklendiği durumu işlemek için belirli yöntemler ekleyerek mimariyi güncelleştirmeniz gerekebilir. Mimari güncelleştirildikten sonra, sonraki adım ekleme arabirimini oluşturmaktır. Bu arabirim, her ikili veri alanı için FileUpload denetimi içerecek şekilde özelleştirilmiş bir DetailsView kullanılarak gerçekleştirilebilir. Karşıya yüklenen veriler daha sonra web sunucusunun dosya sistemine kaydedilebilir veya DetailsView ItemInserting olay işleyicisindeki bir veri kaynağı parametresine atanabilir.

İkili verileri dosya sistemine kaydetmek, verileri doğrudan veritabanına kaydetmekten daha fazla planlama gerektirir. Bir kullanıcının karşıya yükleme işleminin başka bir kullanıcının üzerine yazmasını önlemek için bir adlandırma düzeni seçilmelidir. Ayrıca, veritabanı ekleme işlemi başarısız olursa karşıya yüklenen dosyayı silmek için ek adımlar atılmalıdır.

Artık sisteme broşür ve resimle yeni kategoriler ekleme özelliğine sahibiz, ancak var olan bir kategorinin ikili verilerinin nasıl güncelleştirildiğini veya silinen bir kategori için ikili verilerin doğru şekilde nasıl kaldırılacağını henüz incelemedik. Sonraki öğreticide bu iki konuyu inceleyeceğiz.

Mutlu Programlama!

Yazar hakkında

Yedi ASP/ASP.NET kitabının yazarı ve 4GuysFromRolla.com kurucusu Scott Mitchell, 1998'den beri Microsoft Web teknolojileriyle çalışmaktadır. Scott bağımsız bir danışman, eğitmen ve yazar olarak çalışmaktadır. Son kitabı Sams Teach Yourself ASP.NET 24 Hours 2.0'dır. Adresine adresinden veya adresinden ulaşabileceğiniz http://ScottOnWriting.NETblogu aracılığıyla ulaşabilirsinizmitchell@4GuysFromRolla.com.

Özel Teşekkürler

Bu öğretici serisi birçok yararlı gözden geçiren tarafından gözden geçirildi. Bu öğreticinin baş gözden geçirenleri Dave Gardner, Teresa Murphy ve Bernadette Leigh oldu. Yaklaşan MSDN makalelerimi gözden geçirmek istiyor musunuz? Öyleyse, bana adresinden bir satır mitchell@4GuysFromRolla.combırakın.