Yeni Kayıt Eklerken Karşıya Dosya Yükleme Seçeneği Ekleme (VB)
tarafından Scott Mitchell
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 Picture
BrochurePath
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 , Description
ve BrochurePath
alanları için CategoryName
giriş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öntemInsertWithPicture
eklemeCategoriesTableAdapter
Veri Erişim Katmanı Oluşturma öğreticisinde gerisini oluşturduğunuzdaCategoriesTableAdapter
, bunu ana sorguyu temel alan , UPDATE
ve DELETE
deyimlerini otomatik olarak oluşturacak INSERT
şekilde yapılandırdık. Ayrıca, TableAdapter'a , ve yöntemlerini Insert
oluşturan DOĞRUDAN VERITABANı yaklaşımını kullanma talimatını verdikDelete
. Update
Bu yöntemler otomatik olarak oluşturulan INSERT
, UPDATE
ve 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 CategoriesTableAdapter
Picture
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ı InsertWithPicture
bu yöntem, , Description
, BrochurePath
ve sütunları için CategoryName
değ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.
Ş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, , Description
ve BrochurePath
değerlerini ekleyen CategoryName
bir 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.
Ş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.aspx
içine yapıştırın. Ayrıca, öğesinin code-behind sınıfından GenerateBrochureLink
DisplayOrDownload.aspx
yöntemine kopyalamayı UploadInDetailsView.aspx
unutmayı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.
Ş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 CategoriesBLL
bir 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.
Ş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.
Ş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 Insert
ayarlayınDefaultMode
.
Özelliği olarak ayarlandığındanFalse
, Ekleme arabiriminde InsertVisible
BoundField işlenmese de CategoryID
DetailsView'da beş BoundField CategoryID
, CategoryName
Description
, , NumberOfProducts
ve 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 NumberOfProducts
bir 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.
Ş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
, EditItemTemplate
ve InsertItemTemplate
iç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 ID
BrochureUpload
ayarlayın. Benzer şekilde, TemplateField's InsertItemTemplate
öğesine Picture
bir FileUpload denetimi ekleyin. Bu FileUpload denetimini olarak ID
PictureUpload
ayarlayın.
Ş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.aspx
aracı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 UploadWarning
ayarlayın, özelliğini temizleyinText
, özelliğini Uyarı olarak, Visible
ve EnableViewState
özelliklerini olarak False
ayarlayı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 .Brochure
sahip 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.pdf
bir 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.pdf
olarak 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
TamItemInserting
Olay İş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.aspx
Dü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.
Ş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.
Ş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.
Ş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 CategoriesBLL
InsertWithPicture
yöntemini çağıran CategoriesTableAdapter
InsertWithPicture
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 InsertParameters
de 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.