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

Scott Mitchell tarafından

Örnek uygulamayı indirin veya PDF 'yi indirin

Bu öğreticide, kullanıcının metin verileri girmesine ve ikili dosyaları yüklemesine izin veren bir Web arabirimi oluşturma işleminin nasıl yapılacağı gösterilmektedir. İkili verileri depolamak için kullanılabilen seçenekleri göstermek için, diğeri dosya sisteminde depolanırken bir dosya veritabanına kaydedilir.

Giriş

Önceki iki öğreticide, uygulama veri modeliyle ilişkili ikili verileri depolama tekniklerini araştırırken, dosyaları istemciden Web sunucusuna göndermek için dosya yükleme denetiminin nasıl kullanılacağı ve bu ikili verilerin bir veri W 'da nasıl görüntüleneceği gördünüz. EB denetimi. Yine de karşıya yüklenen verileri veri modeliyle ilişkilendirme hakkında konuşuyoruz, ancak.

Bu öğreticide, yeni bir kategori eklemek için bir Web sayfası oluşturacağız. Kategori adı ve açıklaması için metin kutularına ek olarak, bu sayfanın yeni kategori s resmi ve bir broşür için bir tane olmak üzere iki dosya yükleme denetimini içermesi gerekir. Karşıya yüklenen resim, yeni kayıt s Picture sütununda doğrudan depolanacak, ancak broşür yeni kayıt s BrochurePath sütununda kaydedilen dosyanın yoluyla ~/Brochures klasöre kaydedilir.

Bu yeni Web sayfasını oluşturmadan önce mimariyi güncelleştirmeniz gerekir. CategoriesTableAdapter s ana sorgusu Picture sütununu almaz. Sonuç olarak, otomatik olarak oluşturulan Insert yönteminin yalnızca CategoryName, Descriptionve BrochurePath alanları için girişleri vardır. Bu nedenle, TableAdapter 'ta dört Categories alanı için istemde bulunan ek bir yöntem oluşturuyoruz. Iş mantığı katmanındaki CategoriesBLL sınıfının de güncellenmesi gerekir.

1. Adım:CategoriesTableAdapter``InsertWithPictureyöntemi ekleme

Veri erişim katmanı oluşturma öğreticisinde geri CategoriesTableAdapter oluşturduğumuz, bunu ana sorguya göre otomatik olarak INSERT, UPDATEve DELETE deyimlerini oluşturacak şekilde yapılandırdık. Üstelik, TableAdapter 'ın Insert, Updateve Delete' i oluşturan VERITABANı doğrudan yaklaşımını benimseme konusunda talimat verdik. 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, BrochurePath sütununu kullanmak için CategoriesTableAdapter s ana sorgusunu genişlettik.

CategoriesTableAdapter s ana sorgusu Picture sütununa başvurmadığından, yeni bir kayıt eklememiz veya mevcut bir kaydı Picture sütunu için bir değer ile güncelleştirebiliriz. Bu bilgileri yakalamak için, TableAdapter 'ta ikili verilerle bir kayıt eklemek için kullanılan yeni bir yöntem oluşturabilir ya da otomatik olarak oluşturulan INSERT ifadesini özelleştirebiliriz. Otomatik olarak oluşturulan INSERT deyimin özelleştirilmesi sorunu, özelleştirmelerimizin üzerine, sihirbaz tarafından geçersiz kılınmasından risklidir. Örneğin, Picture sütununun kullanımını dahil etmek için INSERT ifadesini özelleştirdiğinizi düşünün. Bu, TableAdapter s Insert yöntemini, kategori s Picture s ikili verileri için ek bir giriş parametresi içerecek şekilde güncelleştirir. Daha sonra bu DAL yöntemini kullanmak için Iş mantığı katmanında bir yöntem oluşturabilir ve bu BLL metodunu sunum katmanı üzerinden çağırabilirsiniz ve her şey wonderfully çalışacaktır. Diğer bir deyişle, TableAdapter Yapılandırma Sihirbazı aracılığıyla TableAdapter 'ı yapılandırdığımızda. Sihirbaz tamamlandıktan hemen sonra, INSERT deyimindeki özelleştirmelerimiz üzerine yazılır, Insert yöntemi eski biçimine döndürülür ve kodumuz artık derlenmeyebilir!

Note

Bu annoyance, ad-hoc SQL deyimleri yerine saklı yordamlar kullanılırken bir sorun değildir. Gelecekteki bir öğreticide, veri erişim katmanında geçici SQL deyimleri yerine saklı yordamlar kullanılarak araştırılacak.

Bunun yerine, otomatik olarak oluşturulan SQL deyimlerini özelleştirmek yerine, bu olası headache 'i önlemek için TableAdapter için yeni bir yöntem oluşturun. InsertWithPictureadlı bu yöntem, CategoryName, Description, BrochurePathve Picture sütunlarının değerlerini kabul eder ve tüm dört değeri yeni bir kayıtta depolayan bir INSERT ifadesini yürütür.

Türü belirtilmiş veri kümesini açın ve tasarımcıdan CategoriesTableAdapter s başlığına sağ tıklayıp bağlam menüsünden sorgu Ekle ' yi seçin. Bu, TableAdapter sorgusunun veritabanına nasıl erişmesi gerektiğini bize sorarak başlayan TableAdapter sorgu Yapılandırma Sihirbazı 'nı başlatır. SQL deyimlerini kullan ' ı seçin ve Ileri ' ye tıklayın. Sonraki adım, oluşturulacak sorgu türünü sorar. Categories tabloya yeni bir kayıt eklemek için bir sorgu oluşturduğumuz için, Ekle ' yi seçin ve Ileri ' ye tıklayın.

Ekle seçeneğini belirleyin

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

Artık INSERT SQL ifadesini belirtmemiz gerekir. Sihirbaz, TableAdapter s ana sorgusuna karşılık gelen bir INSERT ifadesini otomatik olarak önerir. Bu durumda, CategoryName, Descriptionve BrochurePath değerlerini ekleyen bir INSERT deyimidir. Picture sütunun bir @Picture parametresiyle birlikte dahil edilmesini sağlamak için ifadeyi güncelleştirin, örneğin:

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

Sihirbazın son ekranında yeni TableAdapter metodunu adlandırma bize sorulur. InsertWithPicture girin ve son ' a tıklayın.

yeni TableAdapter metodunu ınsertwithpicture olarak adlandırın

Şekil 2: yeni TableAdapter metodunu adlandırma InsertWithPicture (tam boyutlu görüntüyü görüntülemek için tıklayın)

2. Adım: Iş mantığı katmanını güncelleştirme

Sunum katmanı yalnızca veri erişim katmanına doğrudan gitmek yerine yalnızca Iş mantığı katmanıyla arabirim gerektirdiğinden, yeni oluşturduğumuz DAL yöntemini (InsertWithPicture) çağıran bir BLL yöntemi oluşturuyoruz. Bu öğreticide, giriş üç string ve bir byte dizisi olarak kabul eden InsertWithPicture adlı CategoriesBLL sınıfında bir yöntem oluşturun. string giriş parametreleri, kategori s adı, açıklaması ve broşür dosya yolu için, byte dizisi ise kategori s resminin ikili içeriğine yöneliktir. Aşağıdaki kodda gösterildiği gibi, bu BLL yöntemi karşılık gelen DAL yöntemini çağırır:

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Insert, false)] 
public void InsertWithPicture(string categoryName, string description, 
    string brochurePath, byte[] picture)
{
    Adapter.InsertWithPicture(categoryName, description, brochurePath, picture);
}

Note

InsertWithPicture metodunu BLL 'e eklemeden önce, yazılan veri kümesini kaydettiğinizden emin olun. CategoriesTableAdapter sınıfı kodu, türü belirtilmiş veri kümesine göre otomatik olarak oluşturulduğundan, yaptığınız değişiklikleri ilk olarak yazılan veri kümesine kaydedemezsiniz Adapter özelliği InsertWithPicture yöntemi hakkında bilgi vermez.

3. Adım: mevcut kategorileri ve bunların Ikili verilerini listeleme

Bu öğreticide, son kullanıcının sisteme yeni bir kategori eklemesine izin veren bir sayfa oluşturacak ve yeni kategori için bir resim ve broşür sağlamamız gerekir. Önceki öğreticide , her bir kategorinin adını, açıklamasını, resmini ve bir bağlantıyı, onun broşürini indirmek için bir bağlantı görüntüleyecek bir TemplateField ve ImageField Içeren bir GridView kullandık. Bu öğreticide, her iki mevcut kategoriyi listeleyen ve yenilerini oluşturulmasına izin veren bir sayfa oluşturmak için bu işlevselliği çoğaltmasına izin verin.

BinaryData klasöründen DisplayOrDownload.aspx sayfasını açarak başlayın. Kaynak görünümüne gidin ve GridView ve ObjectDataSource öğelerinin bildirime dayalı sözdizimini kopyalayın ve UploadInDetailsView.aspx``<asp:Content> öğesi içinde yapıştırın. Ayrıca, DisplayOrDownload.aspx arka plan kod sınıfından UploadInDetailsView.aspx``GenerateBrochureLink yöntemi kopyalamayı unutmayın.

DisplayOrDownload. aspx konumundan Uploadındetailsview. aspx ' e bildirim temelli sözdizimini kopyalayıp yapıştırın

Şekil 3: DisplayOrDownload.aspx bildirime dayalı sözdizimini kopyalayıp UploadInDetailsView.aspx yapıştırın (tam boyutlu görüntüyü görüntülemek için tıklayın)

Bildirim temelli sözdizimini ve GenerateBrochureLink yöntemini UploadInDetailsView.aspx sayfasına kopyaladıktan sonra, her şeyin doğru şekilde kopyalandığından emin olmak için sayfayı bir tarayıcı üzerinden görüntüleyin. Broşür ve kategori s resmini indirmek için bir bağlantı içeren sekiz kategorinin listelendiği bir GridView görmeniz gerekir.

her kategoriyi Ikili verilerle birlikte görmeniz gerekir

Şekil 4: artık her kategoriyi Ikili verilerle birlikte görmeniz gerekir (tam boyutlu görüntüyü görüntülemek için tıklayın)

4. Adım: eklemeyi desteklemek içinCategoriesDataSourceyapılandırma

Categories GridView tarafından kullanılan CategoriesDataSource ObjectDataSource Şu anda veri ekleme özelliği sağlamıyor. Bu veri kaynağı denetimini eklemeyi desteklemek için, Insert yöntemini temel alınan nesnesindeki bir yönteme eşliyoruz gerekir, CategoriesBLL. Özellikle, bu dosyayı adım 2 ' de geri eklediğimiz CategoriesBLL yöntemiyle eşlemek istiyoruz InsertWithPicture.

Başlat ' ın akıllı etiketinden veri kaynağını Yapılandır bağlantısına tıklayarak başlayın. İlk ekranda, veri kaynağının ile birlikte çalışmak üzere yapılandırıldığı nesne gösterilir CategoriesBLL. Bu ayarı olduğu gibi bırakın ve veri yöntemlerini tanımla ekranına ilerlemek için Ileri ' ye tıklayın. Ekle sekmesine gidin ve açılan listeden InsertWithPicture yöntemini seçin. Sihirbazı tamamladığınızda son ' a tıklayın.

ınsertwithpicture metodunu kullanmak için ObjectDataSource 'ı yapılandırma

Şekil 5: InsertWithPicture yöntemini kullanmak için ObjectDataSource 'ı yapılandırın (tam boyutlu görüntüyü görüntülemek için tıklayın)

Note

Sihirbaz tamamlandıktan sonra Visual Studio, veri Web denetimleri alanlarını yeniden oluşturacak alanları ve anahtarları yenilemek isteyip istemediğinizi sorabilir. Evet ' i seçmek, yapmış olduğunuz tüm alan özelleştirmelerinin üzerine yazacak şekilde Hayır ' ı seçin.

Sihirbazı tamamladıktan sonra, ObjectDataSource artık InsertMethod özelliği için bir değer ve dört Kategori sütunu için InsertParameters ve aşağıdaki bildirime dayalı biçimlendirme gösterilmektedir:

<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

Veri ekleme, güncelleştirme ve silme konusunda genel bakışkapsamında, DetailsView denetimi, eklemeyi destekleyen bir veri kaynağı denetimiyle çalışırken kullanılabilecek bir yerleşik ekleme arabirimi sağlar. Ekleme arabirimini kalıcı olarak işleyecek GridView 'un bu sayfaya bir DetailsView denetimi ekleyelim, böylece bir kullanıcının kolayca yeni bir kategori eklemesine izin verilir. DetailsView 'a yeni bir kategori eklendiğinde, bunun altındaki GridView otomatik olarak yenilenir ve yeni kategoriyi görüntüler.

Araç kutusundan GridView 'un üzerindeki tasarımcı üzerine bir DetailsView sürükleyip ID özelliğini NewCategory ve Height ve Width özellik değerlerini temizleyerek başlatın. DetailsView 'un akıllı etiketinde, mevcut CategoriesDataSource bağlayın ve sonra eklemeyi etkinleştir onay kutusunu işaretleyin.

DetailsView öğesini Kategorilerverikaynağına bağlamak ve ekleme özelliğini etkinleştirmek

Şekil 6: DetailsView 'ı CategoriesDataSource bağlayın ve eklemeyi etkinleştirin (tam boyutlu görüntüyü görüntülemek için tıklayın)

DetailsView 'u ekleme arabiriminde kalıcı olarak işlemek için DefaultMode özelliğini Insertolarak ayarlayın.

DetailsView 'un BrochurePath özelliği CategoryID olarak ayarlandığı için, InsertVisible BoundField CategoryID, CategoryName, Description, NumberOfProductsve falsebeş BoundFields olduğunu unutmayın. Bu BoundFields, ObjectDataSource 'un verileri almak için çağırdığı GetCategories() yöntemi tarafından döndürülen sütunlar olduklarından oluşur. Bununla birlikte, ekleme için kullanıcının NumberOfProductsbir değer belirtmesini istiyorum. Üstelik, bu kullanıcıların yeni kategori için bir resim yüklemesine ve broşür için bir PDF 'YI karşıya yüklemesine izin vermemiz gerekir.

DetailsView NumberOfProducts BoundField öğesini tamamen kaldırın ve ardından CategoryName ve BrochurePath BoundFields HeaderText özelliklerini sırasıyla kategori ve broşür olarak güncelleştirin. Sonra, BrochurePath BoundField öğesini TemplateField öğesine dönüştürün ve resme yeni bir TemplateField ekleyin, bu yeni TemplateField değerini bir resim HeaderText olarak verir. Picture TemplateField alanını BrochurePath TemplateField ve CommandField arasında olacak şekilde taşıyın.

DetailsView 'u Kategorilerverikaynağına bağlayın ve eklemeyi etkinleştirin

Şekil 7: DetailsView 'ı CategoriesDataSource bağlayın ve eklemeyi etkinleştirin

Alanları Düzenle iletişim kutusu aracılığıyla BrochurePath BoundField öğesini bir TemplateField 'a dönüştürdüyseniz, TemplateField bir ItemTemplate, EditItemTemplateve InsertItemTemplateiçerir. Ancak yalnızca InsertItemTemplate gereklidir, bu nedenle diğer iki şablonu kaldırmayı ücretsiz olarak hissetmekten çekinmeyin. Bu noktada, DetailsView 'un bildirime dayalı sözdizimi 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 dosya yükleme denetimleri ekleme

Şu anda BrochurePath TemplateField InsertItemTemplate bir TextBox içerir, ancak Picture TemplateField herhangi bir şablon içermez. Bu iki TemplateField s InsertItemTemplate, dosya yükleme denetimlerini kullanacak şekilde güncelleştirmemiz gerekiyor.

DetailsView 'un akıllı etiketinde Şablonları Düzenle seçeneğini belirleyin ve ardından açılan listeden BrochurePath TemplateField InsertItemTemplate ' ı seçin. TextBox ' ı kaldırın ve ardından araç kutusundan bir dosya yükleme denetimini şablona sürükleyin. Dosya karşıya yükleme denetim s ID BrochureUploadolarak ayarlayın. Benzer şekilde, Picture TemplateField s InsertItemTemplatebir dosya karşıya yükleme denetimi ekleyin. Bu dosya yükleme denetim s ID PictureUploadolarak ayarlayın.

InsertItemTemplate 'e dosya yükleme denetimi ekleme

Şekil 8: InsertItemTemplate bir dosya yükleme denetimi ekleme (tam boyutlu görüntüyü görüntülemek için tıklayın)

Bu eklemeleri yaptıktan sonra, iki TemplateField bildirim sözdizimi şu şekilde olur:

<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>

Bir 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. Resimde, kullanıcının bir resim dosyasını karşıya yüklemesi gerekir, ancak herhangi bir görüntü dosyası ya da yalnızca belirli bir türdeki (örneğin, GIF 'Ler veya jpgs) görüntü dosyaları izin veririz. Farklı dosya türlerine izin vermek için, Categories şemayı, bu türün DisplayCategoryPicture.aspxiçindeki Response.ContentType aracılığıyla istemciye gönderilebilmesi için dosya türünü yakalayan bir sütun içerecek şekilde genişletmemiz gerekir. Böyle bir sütun olmadığı için, kullanıcıların yalnızca belirli bir görüntü dosyası türü sağlaması için akıllıca olur. Categories tablo var olan görüntüler bit eşlemlerdir, ancak JPGs 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üklediğinde, eklemeyi iptal etmemiz ve sorunu belirten bir ileti görüntülemesi gerekir. DetailsView 'un altına bir etiket Web denetimi ekleyin. ID özelliğini UploadWarningolarak ayarlayın, Text özelliğini temizleyin, CssClass özelliğini uyarı olarak ayarlayın ve Visible ve EnableViewState özelliklerini false. Warning CSS sınıfı Styles.css tanımlanır ve metni büyük, kırmızı, italik, kalın yazı tipiyle işler.

Note

İdeal olarak, CategoryName ve Description BoundFields alanları TemplateFields 'e, eklenen arabirimleri de özelleştirilmiş olarak dönüştürülür. Örneğin, Description ekleme arabirimi, büyük olasılıkla çok satırlı bir metin kutusuyla daha uygun olabilir. CategoryName sütunu NULL değerlerini kabul etmediğinden, kullanıcının yeni kategori s adı için bir değer sağladığından emin olmak için bir RequiredFieldValidator eklenmelidir. Bu adımlar, okuyucuya bir alıştırma olarak kalır. Veri değiştirme arabirimlerini genişletmekten derinlemesine bir bakış için veri değiştirme arabirimini özelleştirmek üzere geri bakın.

6. Adım: karşıya yüklenen broşürü Web sunucusu s dosya sistemine kaydetme

Kullanıcı yeni bir kategorinin değerlerini girdiğinde ve Ekle düğmesine tıkladığında, bir geri gönderme gerçekleşir ve iş akışı kaldırılıyor. İlk olarak, DetailsView ItemInserting olayı ateşlenir. Ardından, ObjectDataSource s Insert() yöntemi çağrılır ve bu, Categories tablosuna yeni bir kaydın eklenmesine neden olur. Bundan sonra, DetailsView ItemInserted olayı ateşlenir.

ObjectDataSource Insert() yöntemi çağrılmadan önce, önce uygun dosya türlerinin Kullanıcı tarafından karşıya yüklendiğinden emin olunması ve sonra Broşür PDF 'YI Web sunucusu s dosya sistemine kaydetmeniz gerekir. DetailsView ItemInserting olayı için bir olay işleyicisi oluşturun ve aşağıdaki kodu ekleyin:

// Reference the FileUpload control
FileUpload BrochureUpload = 
    (FileUpload)NewCategory.FindControl("BrochureUpload");
if (BrochureUpload.HasFile)
{
    // Make sure that a PDF has been uploaded
    if (string.Compare(System.IO.Path.GetExtension
        (BrochureUpload.FileName), ".pdf", true) != 0)
    {
        UploadWarning.Text = 
            "Only PDF documents may be used for a category's brochure.";
        UploadWarning.Visible = true;
        e.Cancel = true;
        return;
    }
}

Olay işleyicisi, DetailsView 'un şablonlarından BrochureUpload FileUpload denetimine başvurulduğunda başlar. Daha sonra, bir broşür karşıya yüklenmişse karşıya yüklenen dosya uzantıları incelenir. Uzantı yoksa. PDF, sonra bir uyarı görüntülenir, ekleme iptal edilir ve olay işleyicisinin yürütülmesi sona erer.

Note

Karşıya yüklenen dosya uzantısına bağlı olarak, karşıya yüklenen dosyanın bir PDF belgesi olduğundan emin olmak için bir,-Fire yöntemi değildir. Kullanıcının uzantısı .Brochuregeçerli bir PDF belgesi olabilir ya da PDF olmayan bir belge alınmış ve bir .pdf uzantısı vermiş olabilir. Dosya türünü daha yaratacağı doğrulamak için dosyanın ikili içeriğinin programlı bir şekilde incelenmesi gerekir. Ancak, bu tür kapsamlı yaklaşımlar genellikle fazla sonlandırılmalıdır; uzantının çoğu senaryo için yeterli olup olmadığı denetleniyor.

Dosyaları karşıya yükleme öğreticisinde açıklandığı gibi, bir kullanıcının karşıya yüklenmesi başka bir veritabanının üzerine yazılmaması için dosyaları dosya sistemine kaydederken dikkatli olunmalıdır. Bu öğretici için karşıya yüklenen dosyayla aynı adı kullanmayı deneyeceğiz. ~/Brochures dizininde aynı dosya adıyla bir dosya zaten varsa, benzersiz bir ad bulunana kadar sonuna bir sayı eklenir. Örneğin, Kullanıcı Meats.pdfadlı bir broşür dosyasını karşıya yüklediğinde, ancak ~/Brochures klasöründe Meats.pdf adında bir dosya zaten varsa, kaydedilen dosya adını Meats-1.pdfolarak değiştireceksiniz. Bu varsa, benzersiz bir dosya adı bulunana kadar Meats-2.pdf, vb. deneyeceğiz.

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

const string BrochureDirectory = "~/Brochures/";
string brochurePath = BrochureDirectory + BrochureUpload.FileName;
string fileNameWithoutExtension = 
    System.IO.Path.GetFileNameWithoutExtension(BrochureUpload.FileName);
int iteration = 1;
while (System.IO.File.Exists(Server.MapPath(brochurePath)))
{
    brochurePath = string.Concat(BrochureDirectory, 
        fileNameWithoutExtension, "-", iteration, ".pdf");
    iteration++;
}

Geçerli bir dosya adı bulunduğunda, dosyanın dosya sistemine kaydedilmesi gerekir ve bu dosya adının veritabanına yazılması için ObjectDataSource s brochurePath``InsertParameter değerinin güncelleştirilmesi gerekir. Karşıya yükleme dosyaları öğreticisinde geri döndüğünüzde dosya, FileUpload denetim s SaveAs(path) yöntemi kullanılarak kaydedilebilir. ObjectDataSource s brochurePath parametresini güncelleştirmek için e.Values koleksiyonunu kullanın.

// 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 kaydına depolamak için, karşıya yüklenen ikili içeriği, DetailsView s ItemInserting olayında ObjectDataSource s picture parametresine atamamız gerekir. Ancak, bu atamayı yapmadan önce karşıya yüklenen resmin başka bir görüntü türü değil, bir JPG olduğundan emin olmanız gerekir. Adım 6 ' da olduğu gibi, ' ın türünü belirlemek için karşıya yüklenen resim dosyası uzantısını kullanmasına izin verin.

Categories tablosu Picture sütunu için NULL değerlere izin verdiğinden, tüm kategorilerin Şu anda bir resmi vardır. Bu sayfa aracılığıyla yeni bir kategori eklerken kullanıcıya bir resim sağlamaya izin verin. Aşağıdaki kod, bir resmin karşıya yüklenmiş ve uygun bir uzantıya sahip olduğundan emin olmak için kontrol eder.

// Reference the FileUpload controls
FileUpload PictureUpload = (FileUpload)NewCategory.FindControl("PictureUpload");
if (PictureUpload.HasFile)
{
    // Make sure that a JPG has been uploaded
    if (string.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), 
            ".jpg", true) != 0 &&
        string.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), 
            ".jpeg", true) != 0)
    {
        UploadWarning.Text = 
            "Only JPG documents may be used for a category's picture.";
        UploadWarning.Visible = true;
        e.Cancel = true;
        return;
    }
}
else
{
    // No picture uploaded!
    UploadWarning.Text = 
        "You must provide a picture for the new category.";
    UploadWarning.Visible = true;
    e.Cancel = true;
    return;
}

Bu kod 6. adımdaki koddan önce yerleştirilmelidir, böylece resim karşıya yükleme ile 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 varsayarak, karşıya yüklenen ikili içeriği resim parametresi s değerine aşağıdaki kod satırıyla atayın:

// Set the value of the picture parameter
e.Values["picture"] = PictureUpload.FileBytes;

TümItemInsertingolay Işleyicisi

Tamamlanma için, ItemInserting olay işleyicisi tamamen aşağıda verilmiştir:

protected void NewCategory_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
    // Reference the FileUpload controls
    FileUpload PictureUpload = (FileUpload)NewCategory.FindControl("PictureUpload");
    if (PictureUpload.HasFile)
    {
        // Make sure that a JPG has been uploaded
        if (string.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), 
                ".jpg", true) != 0 &&
            string.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), 
                ".jpeg", true) != 0)
        {
            UploadWarning.Text = 
                "Only JPG documents may be used for a category's picture.";
            UploadWarning.Visible = true;
            e.Cancel = true;
            return;
        }
    }
    else
    {
        // No picture uploaded!
        UploadWarning.Text = 
            "You must provide a picture for the new category.";
        UploadWarning.Visible = true;
        e.Cancel = true;
        return;
    }
    // Set the value of the picture parameter
    e.Values["picture"] = PictureUpload.FileBytes;
    
    
    // Reference the FileUpload controls
    FileUpload BrochureUpload = 
        (FileUpload)NewCategory.FindControl("BrochureUpload");
    if (BrochureUpload.HasFile)
    {
        // Make sure that a PDF has been uploaded
        if (string.Compare(System.IO.Path.GetExtension(BrochureUpload.FileName), 
            ".pdf", true) != 0)
        {
            UploadWarning.Text = 
                "Only PDF documents may be used for a category's brochure.";
            UploadWarning.Visible = true;
            e.Cancel = true;
            return;
        }
        const string BrochureDirectory = "~/Brochures/";
        string brochurePath = BrochureDirectory + BrochureUpload.FileName;
        string fileNameWithoutExtension = 
            System.IO.Path.GetFileNameWithoutExtension(BrochureUpload.FileName);
        int iteration = 1;
        while (System.IO.File.Exists(Server.MapPath(brochurePath)))
        {
            brochurePath = string.Concat(BrochureDirectory, fileNameWithoutExtension, 
                "-", iteration, ".pdf");
            iteration++;
        }
        // Save the file to disk and set the value of the brochurePath parameter
        BrochureUpload.SaveAs(Server.MapPath(brochurePath));
        e.Values["brochurePath"] = brochurePath;
    }
}

8. Adım:DisplayCategoryPicture.aspxsayfasını Düzeltme

Son birkaç adımda oluşturulan ekleme arabirimini ve ItemInserting olay işleyicisini test etmek için bir süre bekleyin. UploadInDetailsView.aspx sayfasını bir tarayıcıda ziyaret edin ve bir kategori eklemeyi deneyin, ancak resmi atlayın veya JPG olmayan bir resim ya da PDF olmayan bir broşür belirtin. Bu durumların hiçbirinde, 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ı Iletisi görüntülenir

Şekil 9: geçersiz bir dosya türü karşıya yüklenirse bir uyarı iletisi görüntülenir (tam boyutlu görüntüyü görüntülemek için tıklayın)

Sayfanın karşıya yükleneceğini ve PDF olmayan ya da JPG olmayan dosyaları kabul etmeyeceği doğrulandıktan sonra, geçerli bir JPG resmine sahip yeni bir kategori ekleyerek, broşür alanını boş bırakın. Ekle düğmesine tıkladıktan sonra, sayfa geri gönderilir ve yeni bir kayıt, Categories tablosuna doğrudan veritabanında depolanan karşıya yüklenen resim ikili içeriğiyle birlikte eklenir. GridView güncellenir ve yeni eklenen kategori için bir satır gösterir, ancak Şekil 10 ' un gösterdiği gibi, yeni kategorinin resmi doğru işlenmez.

Yeni kategorinin resim görüntülenmiyor

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

Yeni resmin görüntülenmediği nedeni, belirtilen bir kategori resmini döndüren DisplayCategoryPicture.aspx sayfasının, OLE üst bilgisi olan bit eşlemleri işleyecek şekilde yapılandırılmasının nedeni. Bu 78 bayt üst bilgisi, istemciye geri gönderilmeden önce Picture sütundan ikili içeriklerden çıkarılır. Ancak yeni kategoride karşıya yüklediğiniz JPG dosyası bu OLE başlığına sahip değil; Bu nedenle, geçerli ve gerekli baytlar Image s binary verilerinden kaldırılıyor.

Categories tablosunda hem OLE üst bilgileri hem de JPGs olan bit eşlemler olduğundan, OLE üst bilgisinin orijinal sekiz kategoriye göre olması ve daha yeni kategori kayıtları için bu kadar bu kadar bu kadar bu kadar bu kadar bu kadar bu kadar bu kadar bu kadar bu kadar devam edebilmesi için DisplayCategoryPicture.aspx güncelleştirme Sonraki öğreticimizde, var olan bir kayıt görüntüsünü güncelleştirmeyi inceleyeceğiz ve tüm eski kategori resimlerini JPGs olacak şekilde güncelleştireceğiz. Şimdilik, yalnızca özgün sekiz kategori için OLE üstbilgilerini eklemek üzere DisplayCategoryPicture.aspx ' de aşağıdaki kodu kullanın:

protected void Page_Load(object sender, EventArgs e)
{
    int categoryID = Convert.ToInt32(Request.QueryString["CategoryID"]);
    // Get information about the specified category
    CategoriesBLL categoryAPI = new CategoriesBLL();
    Northwind.CategoriesDataTable categories = 
        categoryAPI.GetCategoryWithBinaryDataByCategoryID(categoryID);
    Northwind.CategoriesRow category = categories[0];
    if (categoryID <= 8)
    {
        // For older categories, we must strip the OLE header... images are bitmaps
        // 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 int OleHeaderLength = 78;
        int strippedImageLength = category.Picture.Length - OleHeaderLength;
        byte[] strippedImageData = new byte[strippedImageLength];
        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);
    }
}

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

Yeni kategoriler için JPG görüntülerinin doğru şekilde Işlendiğine

Şekil 11: yeni KATEGORILER Için jpg resimleri doğru işlenir (tam boyutlu görüntüyü görüntülemek için tıklayın)

9. Adım: bir özel durum durumunda broşürü silme

Web sunucusu s dosya sisteminde ikili verileri depolamanın güçlüklerinden biri, veri modeli ve onun ikili verileri arasında bir bağlantı kesmeyi sunmakta. Bu nedenle, bir kayıt silindiğinde dosya sistemindeki karşılık gelen ikili verilerin de kaldırılması gerekir. Bu, ekleme sırasında da oynatılmasına gelebilir. Aşağıdaki senaryoyu göz önünde bulundurun: bir Kullanıcı, geçerli bir resim ve broşür belirten yeni bir kategori ekler. Ekle düğmesine tıklandıktan sonra, bir geri gönderme gerçekleşir ve DetailsView ItemInserting olay ateşlenir ve bu da broşür Web sunucusu s dosya sistemine kaydediliyor. Daha sonra, CategoriesTableAdapter s InsertWithPicture yöntemini çağıran CategoriesBLL sınıf s InsertWithPicture yöntemini çağıran ObjectDataSource s Insert() yöntemi çağrılır.

Şimdi, veritabanı çevrimdışıysa veya INSERT SQL deyimindeki bir hata varsa ne olur? Açıkça ekleme başarısız olur, bu nedenle veritabanına yeni bir kategori satırı eklenmez. Ancak yine de karşıya yüklenen broşür dosyası Web sunucusu s dosya sisteminde oturduk! Bu dosyanın, ekleme iş akışı sırasında bir özel durum durumunda silinmesi gerekir.

Daha önce bir ASP.NET sayfa öğreticisindeki BLL ve dal düzeyi özel durumları işleme konusunda anlatıldığı gibi, bir özel durum, mimarinin derinliğinden farklı katmanlar aracılığıyla kabarcıklanmasını. Sunum katmanında, DetailsView ItemInserted olayından bir özel durumun oluşup oluşmadığını belirleyebiliriz. Bu olay işleyicisi, InsertParametersObjectDataSource 'un değerlerini de sağlar. Bu nedenle, bir özel durum olup olmadığını denetleyen ItemInserted olayı için bir olay işleyicisi oluşturuyoruz ve bu durumda, ObjectDataSource s brochurePath parametresi tarafından belirtilen dosyayı siler:

protected void NewCategory_ItemInserted
    (object sender, DetailsViewInsertedEventArgs e)
{
    if (e.Exception != null)
    {
        // Need to delete brochure file, if it exists
        if (e.Values["brochurePath"] != null)
            System.IO.File.Delete(Server.MapPath(
                e.Values["brochurePath"].ToString()));
    }
}

Özet

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

İkili verileri dosya sistemine kaydetmek, verileri doğrudan veritabanına kaydetmeye kıyasla daha fazla planlama gerektirir. Bir Kullanıcı yüklemesinin karşıya yüklenmesini önlemek için bir adlandırma düzeni seçilmelidir. Ayrıca, veritabanı ekleme başarısız olursa karşıya yüklenen dosyayı silmek için ek adımların alınması gerekir.

Artık, bir broşür ve resimle sisteme yeni kategoriler ekleyebilme olanağı sunuyoruz, ancak mevcut bir kategorinin ikili verilerinin nasıl güncelleştireceğiz veya silinen bir kategorinin ikili verilerinin nasıl doğru şekilde kaldırılacağı hakkında daha fazla bakıyoruz. Sonraki öğreticide bu iki konuyu araştıracağız.

Programlamanın kutlu olsun!

Yazar hakkında

4GuysFromRolla.com 'in, Scott Mitchell, yedi ASP/ASP. net books ve 'in yazarı, 1998 sürümünden bu yana Microsoft Web teknolojileriyle çalışmaktadır. Scott bağımsız danışman, Trainer ve yazıcı olarak çalışıyor. En son kitabı, 24 saat içinde ASP.NET 2,0 kendi kendinize eğitimister. mitchell@4GuysFromRolla.comadresinden erişilebilir . ya da blog aracılığıyla http://ScottOnWriting.NETbulabilirsiniz.

Özel olarak teşekkürler

Bu öğretici serisi birçok yararlı gözden geçirenler tarafından incelendi. Bu öğreticide lider gözden geçirenler, Gardner, Teresa Murphy ve Bernadette Leigh. Yaklaşan MSDN makalelerimi gözden geçiriyor musunuz? Öyleyse, benimitchell@4GuysFromRolla.combir satır bırakın .