Включение параметра отправки файла при добавлении новой записи (C#)Including a File Upload Option When Adding a New Record (C#)

по Скотт Митчеллby Scott Mitchell

Скачивание примера приложения или Загрузка PDF-файлаDownload Sample App or Download PDF

В этом учебнике показано, как создать веб-интерфейс, позволяющий пользователю вводить текстовые данные и отправлять двоичные файлы.This tutorial shows how to create a Web interface that allows the user to both enter text data and upload binary files. Чтобы продемонстрировать параметры, доступные для хранения двоичных данных, один файл будет сохранен в базе данных, а другой — в файловой системе.To illustrate the options available to store binary data, one file will be saved in the database while the other is stored in the file system.

ВведениеIntroduction

В предыдущих двух учебниках мы рассматривали методы хранения двоичных данных, связанных с моделью данных приложения, рассмотрели, как использовать элемент управления FileUpload для отправки файлов с клиента на веб-сервер, и увидеть, как представлять эти двоичные данные в данных элемент управления EB.In the previous two tutorials we explored techniques for storing binary data that is associated with the application s data model, looked at how to use the FileUpload control to send files from the client to the web server, and saw how to present this binary data in a data Web control. Но мы еще не говорим о том, как связать загруженные данные с моделью данных.We ve yet to talk about how to associate uploaded data with the data model, though.

В этом учебнике будет создана веб-страница для добавления новой категории.In this tutorial we will create a web page to add a new category. Помимо текстовых полей для имени и описания категории s, на этой странице необходимо включить два элемента управления FileUpload, один для изображения новой категории и один для буклета.In addition to TextBoxes for the category s name and description, this page will need to include two FileUpload controls one for the new category s picture and one for the brochure. Отправленная картинка будет сохранена непосредственно в новой записи Picture столбец, тогда как буклет будет сохранен в папке ~/Brochures с путем к файлу, сохраненному в столбце новая запись s BrochurePath.The uploaded picture will be stored directly in the new record s Picture column, whereas the brochure will be saved to the ~/Brochures folder with the path to the file saved in the new record s BrochurePath column.

Перед созданием этой новой веб-страницы необходимо обновить архитектуру.Before creating this new web page, we'll need to update the architecture. Основной запрос CategoriesTableAdapter s не извлекает столбец Picture.The CategoriesTableAdapter s main query does not retrieve the Picture column. Следовательно, автоматически созданный метод Insert содержит только входные данные для полей CategoryName, Descriptionи BrochurePath.Consequently, the auto-generated Insert method only has inputs for the CategoryName, Description, and BrochurePath fields. Поэтому нам нужно создать дополнительный метод в TableAdapter, который запрашивает все четыре поля Categories.Therefore, we need to create an additional method in the TableAdapter that prompts for all four Categories fields. Необходимо также обновить класс CategoriesBLL на уровне бизнес-логики.The CategoriesBLL class in the Business Logic Layer will also need to be updated.

Шаг 1. Добавление методаInsertWithPictureвCategoriesTableAdapterStep 1: Adding anInsertWithPictureMethod to theCategoriesTableAdapter

Когда мы создали CategoriesTableAdapter обратно в учебнике Создание уровня доступа к данным , мы настроили автоматическое создание INSERT, UPDATEи DELETE инструкций на основе основного запроса.When we created the CategoriesTableAdapter back in the Creating a Data Access Layer tutorial, we configured it to automatically generate INSERT, UPDATE, and DELETE statements based on the main query. Более того, мы предзадали TableAdapter инструкцию использовать прямой подход к базе данных, который создал методы Insert, Updateи Delete.Moreover, we instructed the TableAdapter to employ the DB Direct approach, which created the methods Insert, Update, and Delete. Эти методы выполняют автоматически созданные инструкции INSERT, UPDATEи DELETE и, соответственно, принимают входные параметры на основе столбцов, возвращаемых основным запросом.These methods execute the auto-generated INSERT, UPDATE, and DELETE statements and, consequently, accept input parameters based on the columns returned by the main query. В руководстве по отправке файлов мы дополнены основным запросом CategoriesTableAdapter s для использования BrochurePath столбца.In the Uploading Files tutorial we augmented the CategoriesTableAdapter s main query to use the BrochurePath column.

Так как основной запрос CategoriesTableAdapter s не ссылается на столбец Picture, мы не можем добавлять новую запись и обновлять существующую запись со значением столбца Picture.Since the CategoriesTableAdapter s main query does not reference the Picture column, we can neither add a new record nor update an existing record with a value for the Picture column. Чтобы записать эти сведения, можно создать в TableAdapter новый метод, который используется специально для вставки записи с двоичными данными, или можно настроить автоматически созданную инструкцию INSERT.In order to capture this information, we can either create a new method in the TableAdapter that is used specifically to insert a record with binary data or we can customize the auto-generated INSERT statement. Проблема, связанная с настройкой автоматически созданной инструкции INSERT, заключается в том, что наши настройки перезаписываются мастером.The problem with customizing the auto-generated INSERT statement is that we risk having our customizations overwritten by the wizard. Например, предположим, что мы настроили инструкцию INSERT для включения использования столбца Picture.For example, imagine that we customized the INSERT statement to include use of the Picture column. Это приведет к обновлению метода Insert TableAdapter, чтобы включить дополнительный входной параметр для двоичных данных категории s Picture.This would update the TableAdapter s Insert method to include an additional input parameter for the category s picture s binary data. Затем можно создать метод на уровне бизнес-логики, чтобы использовать этот метод DAL и вызвать этот метод BLL через уровень представления, и все будет работать замечательно.We could then create a method in the Business Logic Layer to use this DAL method and invoke this BLL method through the Presentation Layer, and everything would work wonderfully. То есть до следующего настройки TableAdapter с помощью мастера настройки TableAdapter.That is, until the next time we configured the TableAdapter through the TableAdapter Configuration wizard. После завершения работы мастера наши настройки INSERTной инструкции будут перезаписаны, метод Insert вернется к старой форме, а наш код больше не будет компилироваться!As soon as the wizard completed, our customizations to the INSERT statement would be overwritten, the Insert method would revert to its old form, and our code would no longer compile!

Note

Это неудобством не вызывает проблем при использовании хранимых процедур вместо специальных инструкций SQL.This annoyance is a non-issue when using stored procedures instead of ad-hoc SQL statements. В следующем учебнике рассматривается использование хранимых процедур вместо специальных инструкций SQL на уровне доступа к данным.A future tutorial will explore using stored procedures in lieu of ad-hoc SQL statements in the Data Access Layer.

Чтобы избежать такой потенциальной недостаточной проблемы, вместо настройки автоматически создаваемых инструкций SQL позвольте ей создать новый метод для TableAdapter.To avoid this potential headache, rather than customizing the auto-generated SQL statements let s instead create a new method for the TableAdapter. Этот метод с именем InsertWithPictureпринимает значения для столбцов CategoryName, Description, BrochurePathи Picture и выполняет инструкцию INSERT, в которой хранятся все четыре значения в новой записи.This method, named InsertWithPicture, will accept values for the CategoryName, Description, BrochurePath, and Picture columns and execute an INSERT statement that stores all four values in a new record.

Откройте типизированный набор данных и в конструкторе щелкните правой кнопкой мыши заголовок CategoriesTableAdapter s и выберите в контекстном меню команду Добавить запрос.Open the Typed DataSet and, from the Designer, right-click on the CategoriesTableAdapter s header and choose Add Query from the context menu. Запустится мастер настройки запросов TableAdapter, который начинает с того, как запрос TableAdapter должен получить доступ к базе данных.This launches the TableAdapter Query Configuration Wizard, which begins by asking us how the TableAdapter query should access the database. Выберите использовать инструкции SQL и нажмите кнопку Далее.Choose Use SQL statements and click Next. На следующем шаге запрашивается тип создаваемого запроса.The next step prompts for the type of query to be generated. Так как мы повторно создаем запрос для добавления новой записи в Categories таблицу, выберите Вставить и нажмите кнопку Далее.Since we re creating a query to add a new record to the Categories table, choose INSERT and click Next.

выбрать параметр вставкиSelect the INSERT Option

Рисунок 1. Выбор параметра вставки (щелкните, чтобы просмотреть изображение с полным размером)Figure 1: Select the INSERT Option (Click to view full-size image)

Теперь необходимо указать инструкцию SQL INSERT.We now need to specify the INSERT SQL statement. Мастер автоматически предложит инструкцию INSERT, соответствующую основному запросу TableAdapter s.The wizard automatically suggests an INSERT statement corresponding to the TableAdapter s main query. В данном случае это инструкция INSERT, которая вставляет значения CategoryName, Descriptionи BrochurePath.In this case, it s an INSERT statement that inserts the CategoryName, Description, and BrochurePath values. Обновите инструкцию таким образом, чтобы столбец Picture был включен вместе с параметром @Picture, например следующим образом:Update the statement so that the Picture column is included along with a @Picture parameter, like so:

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

На последнем экране мастера запрашивается имя нового метода TableAdapter.The final screen of the wizard asks us to name the new TableAdapter method. Введите InsertWithPicture и нажмите кнопку Готово.Enter InsertWithPicture and click Finish.

назовите новый метод TableAdapter ИнсертвиспиктуреName the New TableAdapter Method InsertWithPicture

Рис. 2. Именование нового метода адаптера таблицы InsertWithPicture (щелкните, чтобы просмотреть изображение с полным размером)Figure 2: Name the New TableAdapter Method InsertWithPicture (Click to view full-size image)

Шаг 2. обновление уровня бизнес-логикиStep 2: Updating the Business Logic Layer

Поскольку уровень представления данных должен взаимодействовать только с уровнем бизнес-логики, а не обходить его непосредственно на уровне доступа к данным, необходимо создать метод BLL, который вызывает только что созданный метод DAL (InsertWithPicture).Since the Presentation Layer should only interface with the Business Logic Layer rather than bypassing it to go directly to the Data Access Layer, we need to create a BLL method that invokes the DAL method we just created (InsertWithPicture). В рамках этого руководства создайте метод в классе CategoriesBLL с именем InsertWithPicture, который принимает в качестве входных данных три string s и массив byte.For this tutorial, create a method in the CategoriesBLL class named InsertWithPicture that accepts as input three string s and a byte array. Входные параметры string предназначены для имени категории, описания и пути к файлу брошюры, а byte массив — для двоичного содержимого изображения категории s.The string input parameters are for the category s name, description, and brochure file path, while the byte array is for the binary contents of the category s picture. Как показано в следующем коде, этот метод BLL вызывает соответствующий метод DAL:As the following code shows, this BLL method invokes the corresponding DAL method:

[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 к BLL.Make sure that you have saved the Typed DataSet before adding the InsertWithPicture method to the BLL. Так как код класса CategoriesTableAdapter создается автоматически на основе типизированного набора данных, если не сохранить изменения в типизированном наборе DataSet, свойство Adapter не будет известно о методе InsertWithPicture.Since the CategoriesTableAdapter class code is auto-generated based on the Typed DataSet, if you don t first save your changes to the Typed DataSet the Adapter property won't know about the InsertWithPicture method.

Шаг 3. Перечисление существующих категорий и их двоичных данныхStep 3: Listing the Existing Categories and their Binary Data

В этом учебнике мы создадим страницу, которая позволяет пользователю добавить новую категорию в систему, предоставив рисунок и буклет для новой категории.In this tutorial we will create a page that allows an end user to add a new category to the system, providing a picture and brochure for the new category. В предыдущем учебном курсе мы использовали GridView с TemplateField и имажефиелд для вывода каждого названия категории, описания, изображения и ссылки для загрузки его буклета.In the preceding tutorial we used a GridView with a TemplateField and ImageField to display each category s name, description, picture, and a link to download its brochure. Давайте выполним репликацию этой функции для этого руководства, создав страницу, в которой оба списка имеют все существующие категории, и допускают создание новых.Let s replicate that functionality for this tutorial, creating a page that both lists all existing categories and allows for new ones to be created.

Для начала откройте страницу DisplayOrDownload.aspx из папки BinaryData.Start by opening the DisplayOrDownload.aspx page from the BinaryData folder. Перейдите в представление исходного кода и скопируйте декларативный синтаксис GridView и ObjectDataSource s, вставляя его в элемент <asp:Content> в UploadInDetailsView.aspx.Go to the Source view and copy the GridView and ObjectDataSource s declarative syntax, pasting it within the <asp:Content> element in UploadInDetailsView.aspx. Кроме того, не забывайте копировать метод GenerateBrochureLink из класса кода программной части DisplayOrDownload.aspx в UploadInDetailsView.aspx.Also, don t forget to copy over the GenerateBrochureLink method from the code-behind class of DisplayOrDownload.aspx to UploadInDetailsView.aspx.

скопировать и вставить декларативный синтаксис из Дисплайордовнлоад. aspx в Уплоадиндетаилсвиев. aspx.Copy and Paste the Declarative Syntax from DisplayOrDownload.aspx to UploadInDetailsView.aspx

Рис. 3. копирование и вставка декларативного синтаксиса из DisplayOrDownload.aspx в UploadInDetailsView.aspx (щелкните, чтобы просмотреть изображение с полным размером)Figure 3: Copy and Paste the Declarative Syntax from DisplayOrDownload.aspx to UploadInDetailsView.aspx (Click to view full-size image)

После копирования декларативного синтаксиса и GenerateBrochureLink метода на страницу UploadInDetailsView.aspx просмотрите страницу в браузере, чтобы убедиться, что все скопировано правильно.After copying the declarative syntax and GenerateBrochureLink method over to the UploadInDetailsView.aspx page, view the page through a browser to ensure that everything was copied over correctly. Вы должны увидеть список из восьми категорий, содержащих ссылку для скачивания буклета, а также изображение категорий.You should see a GridView listing the eight categories that includes a link to download the brochure as well as the category s picture.

должны отобразиться все категории вместе с двоичными даннымиYou Should Now See Each Category Along with Its Binary Data

Рис. 4. Теперь вы увидите каждую категорию вместе с двоичными данными (щелкните, чтобы просмотреть изображение с полным размером).Figure 4: You Should Now See Each Category Along with Its Binary Data (Click to view full-size image)

Шаг 4. НастройкаCategoriesDataSourceдля поддержки вставкиStep 4: Configuring theCategoriesDataSourceto Support Inserting

CategoriesDataSource ObjectDataSource, используемый Categories GridView, в настоящее время не предоставляет возможности вставки данных.The CategoriesDataSource ObjectDataSource used by the Categories GridView currently does not provide the ability to insert data. Для поддержки вставки через этот элемент управления источниками данных необходимо соотнести его метод Insert с методом в его базовом объекте CategoriesBLL.In order to support inserting through this data source control, we need to map its Insert method to a method in its underlying object, CategoriesBLL. В частности, мы хотим преобразовать его в метод CategoriesBLL, который мы добавили обратно на шаге 2, InsertWithPicture.In particular, we want to map it to the CategoriesBLL method we added back in Step 2, InsertWithPicture.

Для начала щелкните ссылку Настройка источника данных из смарт-тега ObjectDataSource s.Start by clicking the Configure Data Source link from the ObjectDataSource s smart tag. На первом экране показан объект, для работы с которым настроен источник данных, CategoriesBLL.The first screen shows the object the data source is configured to work with, CategoriesBLL. Оставьте этот параметр как есть и нажмите кнопку Далее, чтобы перейти к экрану определение методов обработки данных.Leave this setting as-is and click Next to advance to the Define Data Methods screen. Перейдите на вкладку Вставка и выберите метод InsertWithPicture из раскрывающегося списка.Move to the INSERT tab and pick the InsertWithPicture method from the drop-down list. Нажмите кнопку Готово, чтобы завершить работу с мастером.Click Finish to complete the wizard.

настроить ObjectDataSource для использования метода ИнсертвиспиктуреConfigure the ObjectDataSource to use the InsertWithPicture Method

Рис. 5. Настройка ObjectDataSource для использования метода InsertWithPicture (щелкните, чтобы просмотреть изображение с полным размером)Figure 5: Configure the ObjectDataSource to use the InsertWithPicture Method (Click to view full-size image)

Note

После завершения работы мастера Visual Studio может запросить обновление полей и ключей, что приведет к повторному формированию полей веб-элементов управления данными.Upon completing the wizard, Visual Studio may ask if you want to Refresh Fields and Keys, which will regenerate the data Web controls fields. Выберите Нет, так как при нажатии кнопки Да будут перезаписаны все сделанные настройки полей.Choose No, because choosing Yes will overwrite any field customizations you may have made.

После завершения работы мастера ObjectDataSource будет включать значение свойства InsertMethod, а также InsertParameters для четырех столбцов категории, как показано в следующей декларативной разметке:After completing the wizard, the ObjectDataSource will now include a value for its InsertMethod property as well as InsertParameters for the four category columns, as the following declarative markup illustrates:

<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. Создание интерфейса вставкиStep 5: Creating the Inserting Interface

Как было описано в обзоре вставки, обновления и удаления данных, элемент управления DetailsView предоставляет встроенный интерфейс вставки, который можно использовать при работе с элементом управления источниками данных, поддерживающим вставку.As first covered in the An Overview of Inserting, Updating, and Deleting Data, the DetailsView control provides a built-in inserting interface that can be utilized when working with a data source control that supports inserting. Добавим на эту страницу элемент управления DetailsView, расположенный над элементом GridView, который будет постоянно отображать свой интерфейс вставки, позволяя пользователю быстро добавить новую категорию.Let s add a DetailsView control to this page above the GridView that will permanently render its inserting interface, allowing a user to quickly add a new category. После добавления новой категории в DetailsView элемент управления GridView под ней автоматически обновит и отобразит новую категорию.Upon adding a new category in the DetailsView, the GridView beneath it will automatically refresh and display the new category.

Начните с перетаскивания элемента управления DetailsView с панели элементов в конструктор над элементом управления GridView, устанавливая для его свойства ID значение NewCategory и очищаются значения свойств Height и Width.Start by dragging a DetailsView from the Toolbox onto the Designer above the GridView, setting its ID property to NewCategory and clearing out the Height and Width property values. В смарт-теге DetailsView s привяжите его к существующему CategoriesDataSource, а затем установите флажок Enable INSERT (включить вставку).From the DetailsView s smart tag, bind it to the existing CategoriesDataSource and then check the Enable Inserting checkbox.

привязать DetailsView к CategoriesDataSource и включить вставкуBind the DetailsView to the CategoriesDataSource and Enable Inserting

Рис. 6. привязка элемента DetailsView к CategoriesDataSource и включение вставки (щелкните, чтобы просмотреть изображение с полным размером)Figure 6: Bind the DetailsView to the CategoriesDataSource and Enable Inserting (Click to view full-size image)

Чтобы окончательно отобразить DetailsView в своем интерфейсе вставки, установите для свойства DefaultMode значение Insert.To permanently render the DetailsView in its inserting interface, set its DefaultMode property to Insert.

Обратите внимание, что элемент DetailsView содержит пять BoundFields CategoryID, CategoryName, Description, NumberOfProductsи BrochurePath, хотя CategoryID BoundField не отображается в интерфейсе вставки, так как его свойство InsertVisible имеет значение false.Note that the DetailsView has five BoundFields CategoryID, CategoryName, Description, NumberOfProducts, and BrochurePath although the CategoryID BoundField is not rendered in the inserting interface because its InsertVisible property is set to false. Эти BoundFields существуют, так как они являются столбцами, возвращаемыми методом GetCategories(), который вызывается ObjectDataSource для получения своих данных.These BoundFields exists because they are the columns returned by the GetCategories() method, which is what the ObjectDataSource invokes to retrieve its data. Однако для вставки мы не хотим, чтобы пользователь указал значение для NumberOfProducts.For inserting, however, we don t want to let the user specify a value for NumberOfProducts. Кроме того, необходимо разрешить им передавать изображение для новой категории, а также отправить PDF-файл для буклета.Moreover, we need to allow them to upload a picture for the new category as well as upload a PDF for the brochure.

Удалите NumberOfProducts BoundField из DetailsView, а затем обновите свойства HeaderText CategoryName и BrochurePath BoundFields на категорию и буклет соответственно.Remove the NumberOfProducts BoundField from the DetailsView altogether and then update the HeaderText properties of the CategoryName and BrochurePath BoundFields to Category and Brochure, respectively. Затем преобразуйте BrochurePath BoundField в TemplateField и добавьте новый TemplateField для изображения, предоставляя этому новому TemplateField HeaderText значение Picture.Next, convert the BrochurePath BoundField into a TemplateField and add a new TemplateField for the picture, giving this new TemplateField a HeaderText value of Picture. Переместите Picture TemplateField, чтобы они находятся между BrochurePath TemplateField и CommandField.Move the Picture TemplateField so that it is between the BrochurePath TemplateField and CommandField.

Привязка DetailsView к CategoriesDataSource и включение вставки

Рис. 7. привязка элемента DetailsView к CategoriesDataSource и включение вставкиFigure 7: Bind the DetailsView to the CategoriesDataSource and Enable Inserting

Если вы преобразовали BrochurePath BoundField в TemplateField в диалоговом окне Изменение полей, TemplateField включает ItemTemplate, EditItemTemplateи InsertItemTemplate.If you converted the BrochurePath BoundField into a TemplateField through the Edit Fields dialog box, the TemplateField includes an ItemTemplate, EditItemTemplate, and InsertItemTemplate. Однако требуется только InsertItemTemplate, поэтому вы можете удалить два других шаблона.Only the InsertItemTemplate is needed, however, so feel free to remove the other two templates. На этом этапе декларативный синтаксис DetailsView s должен выглядеть следующим образом:At this point your DetailsView s declarative syntax should look like the following:

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

Добавление элементов управления FileUpload для буклетов и полей рисунковAdding FileUpload Controls for the Brochure and Picture Fields

В настоящее время BrochurePath TemplateField s InsertItemTemplate содержит текстовое поле, а Picture TemplateField не содержит шаблонов.Presently, the BrochurePath TemplateField s InsertItemTemplate contains a TextBox, while the Picture TemplateField does not contain any templates. Чтобы использовать элементы управления FileUpload, необходимо обновить эти две TemplateField InsertItemTemplate s.We need to update these two TemplateField s InsertItemTemplate s to use FileUpload controls.

В смарт-теге DetailsView s выберите пункт изменить шаблоны, а затем выберите BrochurePath TemplateField s InsertItemTemplate из раскрывающегося списка.From the DetailsView s smart tag, choose the Edit Templates option and then select the BrochurePath TemplateField s InsertItemTemplate from the drop-down list. Удалите текстовое поле и перетащите элемент управления FileUpload из панели элементов в шаблон.Remove the TextBox and then drag a FileUpload control from the Toolbox into the template. Задайте для элемента управления FileUpload ID BrochureUpload.Set the FileUpload control s ID to BrochureUpload. Аналогичным образом добавьте элемент управления FileUpload в Picture TemplateField s InsertItemTemplate.Similarly, add a FileUpload control to the Picture TemplateField s InsertItemTemplate. Задайте для этого элемента управления FileUpload ID PictureUpload.Set this FileUpload control s ID to PictureUpload.

добавить элемент управления FileUpload в InsertItemTemplateAdd a FileUpload Control to the InsertItemTemplate

Рис. 8. Добавление элемента управления FileUpload в InsertItemTemplate (щелкните, чтобы просмотреть изображение с полным размером)Figure 8: Add a FileUpload Control to the InsertItemTemplate (Click to view full-size image)

После внесения этих дополнений декларативный синтаксис TemplateField s будет следующим:After making these additions, the two TemplateField s declarative syntax will be:

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

Когда пользователь добавляет новую категорию, мы хотим убедиться, что буклет и рисунок имеют правильный тип файла.When a user adds a new category, we want to ensure that the brochure and picture are of the correct file type. Для буклета пользователь должен предоставить PDF-файл.For the brochure, the user must supply a PDF. Для изображения необходимо передать файл изображения, но разрешить любой файл изображения или только файлы изображений определенного типа, например GIF или жпгс?For the picture, we need the user to upload an image file, but do we allow any image file or only image files of a particular type, such as GIFs or JPGs? Чтобы разрешить различные типы файлов, нам нужно расширить схему Categories, включив в нее столбец, который захватывает тип файла, чтобы этот тип можно было отправить клиенту с помощью Response.ContentType в DisplayCategoryPicture.aspx.In order to allow for different file types, we d need to extend the Categories schema to include a column that captures the file type so that this type can be sent to the client through Response.ContentType in DisplayCategoryPicture.aspx. Так как у нас нет такого столбца, было бы разумно ограничить доступ пользователей, предоставив только конкретный тип файла изображения.Since we don t have such a column, it would be prudent to restrict users to only providing a specific image file type. Categories таблица s — это точечные рисунки, но для изображений, обслуживаемых через Интернет, Жпгс имеет более подходящий формат файлов.The Categories table s existing images are bitmaps, but JPGs are a more appropriate file format for images served over the web.

Если пользователь передает неверный тип файла, необходимо отменить вставку и отобразить сообщение, указывающее на проблему.If a user uploads an incorrect file type, we need to cancel the insert and display a message indicating the problem. Добавьте веб-элемент управления Label под элементом DetailsView.Add a Label Web control beneath the DetailsView. Присвойте свойству ID значение UploadWarning, удалите его свойство Text, задайте для свойства CssClass значение Warning, а для Visible EnableViewState и falseсвойства.Set its ID property to UploadWarning, clear out its Text property, set the CssClass property to Warning, and the Visible and EnableViewState properties to false. Класс Warning CSS определен в Styles.css и отображает текст в большом, красно-курсивном полужирном шрифте.The Warning CSS class is defined in Styles.css and renders the text in a large, red, italicized, bold font.

Note

В идеале CategoryName и Description BoundFields будут преобразованы в полей TemplateField, а их интерфейсы вставки будут настроены.Ideally, the CategoryName and Description BoundFields would be converted to TemplateFields and their inserting interfaces customized. Например, интерфейс вставки Description, скорее всего, лучше подходит для многострочного текстового поля.The Description inserting interface, for example, would likely be better suited through a multi-line textbox. А поскольку CategoryName столбец не принимает NULL значений, необходимо добавить RequiredFieldValidator, чтобы гарантировать, что пользователь предоставит значение для нового имени категории s.And since the CategoryName column does not accept NULL values, a RequiredFieldValidator should be added to ensure the user provides a value for the new category s name. Эти шаги оставлены в качестве упражнения для читателя.These steps are left as an exercise to the reader. Дополнительные сведения о дополнении интерфейсов изменения данных см. в статье о настройке интерфейса изменения данных .Refer back to Customizing the Data Modification Interface for an in-depth look at augmenting the data modification interfaces.

Шаг 6. Сохранение отправленной брошюры в файловую систему веб-сервераStep 6: Saving the Uploaded Brochure to the Web Server s File System

Когда пользователь вводит значения для новой категории и нажимает кнопку «Вставить», происходит обратная передача, а рабочий процесс вставки размещается.When the user enters the values for a new category and clicks the Insert button, a postback occurs and the inserting workflow unfolds. Во первых, срабатывает событиеItemInserting DetailsView s.First, the DetailsView s ItemInserting event fires. Затем вызывается метод ObjectDataSource Insert(), который приводит к добавлению новой записи в Categories таблицу.Next, the ObjectDataSource s Insert() method is invoked, which results in a new record being added to the Categories table. После этого срабатывает событиеItemInserted DetailsView s.After that, the DetailsView s ItemInserted event fires.

Прежде чем вызывать метод Insert() ObjectDataSource s, необходимо убедиться, что пользователь передал соответствующие типы файлов, а затем сохранить файл брошюры PDF в файловой системе веб-сервера.Before the ObjectDataSource s Insert() method is invoked, we must first ensure that the appropriate file types were uploaded by the user and then save the brochure PDF to the web server s file system. Создайте обработчик событий для события ItemInserting DetailsView s и добавьте следующий код:Create an event handler for the DetailsView s ItemInserting event and add the following code:

// 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;
    }
}

Обработчик событий начинает с ссылки на элемент управления BrochureUpload FileUpload из шаблонов DetailsView s.The event handler starts by referencing the BrochureUpload FileUpload control from the DetailsView s templates. Затем, если буклет был отправлен, проверяется расширение отправленных файлов.Then, if a brochure has been uploaded, the uploaded file s extension is examined. Если расширение не имеет значение. PDF, отображается предупреждение, вставка отменяется и выполнение обработчика событий завершается.If the extension is not .PDF, then a warning is displayed, the insert is cancelled, and the execution of the event handler ends.

Note

Использование расширения переданного файла не является самым гарантией того, что отправленный файл является документом в формате PDF.Relying on the uploaded file s extension is not a sure-fire technique for ensuring that the uploaded file is a PDF document. Пользователь может иметь допустимый PDF-документ с расширением .Brochureили мог взять документ в формате, отличном от PDF, и присвоить ему расширение .pdf.The user could have a valid PDF document with the extension .Brochure, or could have taken a non-PDF document and given it a .pdf extension. Для более окончательной проверки типа файла необходимо программно проверять двоичное содержимое файлов.The file s binary content would need to be programmatically examined in order to more conclusively verify the file type. Однако такие глубокие подходы часто являются избыточными; Проверка расширения достаточна для большинства сценариев.Such thorough approaches, though, are often overkill; checking the extension is sufficient for most scenarios.

Как обсуждалось в руководстве по отправке файлов , необходимо соблюдать осторожность при сохранении файлов в файловой системе, чтобы одна пользовательская передача не перезаписала другой.As discussed in the Uploading Files tutorial, care must be taken when saving files to the file system so that one user s upload does not overwrite another s. В этом учебнике будет предпринята попытка использовать то же имя, что и у отправленного файла.For this tutorial we will attempt to use the same name as the uploaded file. Однако если в каталоге ~/Brochures уже существует файл с таким же именем файла, мы добавим номер в конец, пока не будет найдено уникальное имя.If there already exists a file in the ~/Brochures directory with that same file name, however, we'll append a number at the end until a unique name is found. Например, если пользователь отправляет файл буклета с именем Meats.pdf, но в папке ~/Brochures уже есть файл с именем Meats.pdf, имя сохраненного файла будет изменено на Meats-1.pdf.For example, if the user uploads a brochure file named Meats.pdf, but there is already a file named Meats.pdf in the ~/Brochures folder, we'll change the saved file name to Meats-1.pdf. Если он существует, мы попытаемся Meats-2.pdfи т. д., пока не будет найдено уникальное имя файла.If that exists, we'll try Meats-2.pdf, and so on, until a unique file name is found.

В следующем коде используется методFile.Exists(path) , чтобы определить, существует ли уже файл с указанным именем.The following code uses the File.Exists(path) method to determine if a file already exists with the specified file name. В этом случае он будет пытаться использовать новые имена файлов для буклета, пока не будет найден конфликт.If so, it continues to try new file names for the brochure until no conflict is found.

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++;
}

После обнаружения допустимого имени файла файл необходимо сохранить в файловой системе, а значение ObjectDataSource brochurePath``InsertParameter необходимо обновить, чтобы оно записывалось в базу данных.Once a valid file name has been found, the file needs to be saved to the file system and the ObjectDataSource s brochurePath``InsertParameter value needs to be updated so that this file name is written to the database. Как мы видели в руководстве по отправке файлов , файл можно сохранить с помощью метода управления FileUpload SaveAs(path).As we saw back in the Uploading Files tutorial, the file can be saved using the FileUpload control s SaveAs(path) method. Чтобы обновить параметр brochurePath ObjectDataSource, используйте коллекцию e.Values.To update the ObjectDataSource s brochurePath parameter, use the e.Values collection.

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

Шаг 7. Сохранение отправленной фотографии в базу данныхStep 7: Saving the Uploaded Picture to the Database

Чтобы сохранить отправленное изображение в новой записи Categories, необходимо назначить переданное двоичное содержимое параметру ObjectDataSource s picture в событии ItemInserting DetailsView s.To store the uploaded picture in the new Categories record, we need to assign the uploaded binary content to the ObjectDataSource s picture parameter in the DetailsView s ItemInserting event. Прежде чем приступать к этому назначению, необходимо сначала убедиться, что отправленный рисунок является JPG, а не другим типом изображения.Before we make this assignment, however, we need to first make sure that the uploaded picture is a JPG and not some other image type. Как и на шаге 6, для определения его типа можно использовать расширение переданного файла Picture s.As in Step 6, let s use the uploaded picture s file extension to ascertain its type.

Хотя Categories таблица допускает NULL значений для столбца Picture, все категории в данный момент имеют рисунок.While the Categories table allows NULL values for the Picture column, all categories currently have a picture. Пусть при добавлении новой категории с помощью этой страницы пользователь должен будет указать рисунок.Let s force the user to provide a picture when adding a new category through this page. Следующий код проверяет, чтобы убедиться, что изображение Отправлено и имеет соответствующее расширение.The following code checks to ensure that a picture has been uploaded and that it has an appropriate extension.

// 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;
}

Этот код следует поместить перед кодом из шага 6, чтобы при возникновении проблемы с отправкой изображения обработчик событий завершит работу перед сохранением файла буклета в файловой системе.This code should be placed before the code from Step 6 so that if there is a problem with the picture upload, the event handler will terminate before the brochure file is saved to the file system.

При условии, что соответствующий файл был отправлен, назначьте переданное двоичное содержимое значению параметра Picture с помощью следующей строки кода:Assuming that an appropriate file has been uploaded, assign the uploaded binary content to the picture parameter s value with the following line of code:

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

Полный обработчик событийItemInsertingThe CompleteItemInsertingEvent Handler

Для полноты здесь ItemInserting обработчик событий целиком:For completeness, here is the ItemInserting event handler in its entirety:

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. исправление страницыDisplayCategoryPicture.aspxStep 8: Fixing theDisplayCategoryPicture.aspxPage

Подождите немного, чтобы протестировать интерфейс вставки и ItemInserting обработчика событий, который был создан за последние несколько шагов.Let s take a moment to test out the inserting interface and ItemInserting event handler that was created over the last few steps. Откройте страницу UploadInDetailsView.aspx в браузере и попытайтесь добавить категорию, но не пропустите рисунок или укажите изображение в формате, отличном от JPG, или буклет.Visit the UploadInDetailsView.aspx page through a browser and attempt to add a category, but omit the picture, or specify a non-JPG picture or a non-PDF brochure. В любом из этих случаев отобразится сообщение об ошибке, и рабочий процесс вставки будет отменен.In any of these cases, an error message will be displayed and the insert workflow cancelled.

отображается предупреждающее сообщение, если передан недопустимый тип файлаA Warning Message is Displayed If an Invalid File Type is Uploaded

Рис. 9. Если передан недопустимый тип файла, отображается предупреждение (щелкните, чтобы просмотреть изображение с полным размером)Figure 9: A Warning Message is Displayed If an Invalid File Type is Uploaded (Click to view full-size image)

Убедившись, что страница требует передачи изображения и не принимает файлы в формате, отличном от PDF или JPG, добавьте новую категорию с допустимым изображением JPG, оставьте поле буклета пустым.Once you have verified that the page requires a picture to be uploaded and won't accept non-PDF or non-JPG files, add a new category with a valid JPG picture, leaving the Brochure field empty. После нажатия кнопки "вставить" страница будет выполнять обратную передачу, и в таблицу Categories будет добавлена новая запись с сохраненным двоичным содержимым Image s, хранящимся непосредственно в базе данных.After clicking the Insert button, the page will postback and a new record will be added to the Categories table with the uploaded image s binary contents stored directly in the database. Элемент управления GridView обновляется и отображает строку только что добавленной категории, но, как показано на рис. 10, новая картинка категории не отображается правильно.The GridView is updated and shows a row for the newly added category, but, as Figure 10 shows, the new category s picture is not rendered correctly.

изображение новой категории не отображаетсяThe New Category s Picture is not Displayed

Рис. 10. изображение новой категории не отображается (щелкните, чтобы просмотреть изображение с полным размером)Figure 10: The New Category s Picture is not Displayed (Click to view full-size image)

Причина, по которой новое изображение не отображается, заключается в том, что страница DisplayCategoryPicture.aspx, которая возвращает определенную картинку категорий, настроена для обработки точечных рисунков, имеющих заголовок OLE.The reason the new picture is not displayed is because the DisplayCategoryPicture.aspx page that returns a specified category s picture is configured to process bitmaps that have an OLE header. Этот заголовок 78 байта удаляется из двоичного содержимого столбца Picture, прежде чем они будут отправлены обратно клиенту.This 78 byte header is stripped from the Picture column s binary contents before they are sent back to the client. Но файл JPG, который был только что отправлен для новой категории, не имеет этого заголовка OLE. Таким образом, допустимые байты удаляются из двоичных данных образа.But the JPG file we just uploaded for the new category does not have this OLE header; therefore, valid, necessary bytes are being removed from the image s binary data.

Так как в таблице Categories есть оба точечных рисунка с заголовками OLE и Жпгс, необходимо обновить DisplayCategoryPicture.aspx таким образом, чтобы она выпускала заголовок OLE для исходных восьми категорий и обойти эту проблему для новых записей категорий.Since there are now both bitmaps with OLE headers and JPGs in the Categories table, we need to update DisplayCategoryPicture.aspx so that it does the OLE header stripping for the original eight categories and bypasses this stripping for the newer category records. В следующем учебном курсе мы рассмотрим, как обновить существующий образ записи, и мы будем обновлять все старые рисунки категорий, чтобы они Жпгс.In our next tutorial we'll examine how to update an existing record s image, and we'll update all of the old category pictures so that they are JPGs. Но теперь используйте следующий код в DisplayCategoryPicture.aspx для чередования заголовков OLE только для тех исходных восьми категорий:For now, though, use the following code in DisplayCategoryPicture.aspx to strip the OLE headers only for those original eight categories:

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);
    }
}

После этого изменения изображение JPG теперь правильно отображается в GridView.With this change, the JPG image is now rendered correctly in the GridView.

правильное отображение изображений JPG для новых категорийThe JPG Images for New Categories are Correctly Rendered

Рис. 11. изображения в формате JPG для новых категорий отображаются правильно (щелкните, чтобы просмотреть изображение с полным размером)Figure 11: The JPG Images for New Categories are Correctly Rendered (Click to view full-size image)

Шаг 9. Удаление буклета на лицевой стороне исключенияStep 9: Deleting the Brochure in the Face of an Exception

Одной из трудностей при хранении двоичных данных в файловой системе веб-сервера является то, что она создает разрыв между моделью данных и ее двоичными данными.One of the challenges of storing binary data on the web server s file system is that it introduces a disconnect between the data model and its binary data. Таким образом, при каждом удалении записи соответствующие двоичные данные в файловой системе также должны быть удалены.Therefore, whenever a record is deleted, the corresponding binary data on the file system must also be removed. Это может быть и при вставке.This can come into play when inserting, as well. Рассмотрим следующий сценарий: пользователь добавляет новую категорию, указывая допустимую картинку и буклет.Consider the following scenario: a user adds a new category, specifying a valid picture and brochure. При нажатии кнопки "вставить" происходит обратная передача и срабатывает событие ItemInserting DetailsView s, сохранив буклет в файловой системе веб-сервера.Upon clicking the Insert button, a postback occurs and the DetailsView s ItemInserting event fires, saving the brochure to the web server s file system. Затем вызывается метод ObjectDataSource Insert(), который вызывает метод CategoriesBLL класса InsertWithPicture, который вызывает метод CategoriesTableAdapter s InsertWithPicture.Next, the ObjectDataSource s Insert() method is invoked, which calls the CategoriesBLL class s InsertWithPicture method, which calls the CategoriesTableAdapter s InsertWithPicture method.

Что произойдет, если база данных находится в автономном режиме или если в инструкции SQL INSERT возникла ошибка?Now, what happens if the database is offline, or if there is an error in the INSERT SQL statement? Очевидно, что вставка завершится ошибкой, поэтому новая строка категории не будет добавлена в базу данных.Clearly the INSERT will fail, so no new category row will be added to the database. Но у нас по-прежнему есть отправленный файл буклета, расположенный в файловой системе Web Server s!But we still have the uploaded brochure file sitting on the web server s file system! Этот файл необходимо удалить в лицевой стороне исключения во время выполнения процесса вставки.This file needs to be deleted in the face of an exception during the inserting workflow.

Как обсуждалось ранее в разделе обработка исключений BLL и DAL в учебнике по страницам ASP.NET , когда исключение создается из глубины архитектуры, она перемещается вверх по различным слоям.As discussed previously in the Handling BLL- and DAL-Level Exceptions in an ASP.NET Page tutorial, when an exception is thrown from within the depths of the architecture it is bubbled up through the various layers. На уровне представления можно определить, возникло ли исключение из события ItemInserted DetailsView s.At the Presentation Layer, we can determine if an exception has occurred from the DetailsView s ItemInserted event. Этот обработчик событий также предоставляет значения InsertParametersObjectDataSource.This event handler also provides the values of the ObjectDataSource s InsertParameters. Таким образом, можно создать обработчик события ItemInserted, который проверяет, было ли исключение, и, если это так, удаляет файл, заданный параметром brochurePath ObjectDataSource:Therefore, we can create an event handler for the ItemInserted event that checks if there was an exception and, if so, deletes the file specified by the ObjectDataSource s brochurePath parameter:

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()));
    }
}

СводкаSummary

Для предоставления веб-интерфейса для добавления записей, содержащих двоичные данные, необходимо выполнить ряд действий.There are a number of steps that must be performed in order to provide a web-based interface for adding records that include binary data. Если двоичные данные хранятся непосредственно в базе данных, то, скорее всего, потребуется обновить архитектуру, добавив определенные методы для обработки случая, когда вставляются двоичные данные.If the binary data is being stored directly into the database, chances are you'll need to update the architecture, adding specific methods to handle the case where binary data is being inserted. После обновления архитектуры следующий шаг заключается в создании интерфейса вставки, который можно выполнить с помощью элемента управления DetailsView, который был настроен для включения в него элементов интерфейса FileUpload для каждого поля двоичных данных.Once the architecture has been updated, the next step is creating the inserting interface, which can be accomplished using a DetailsView that has been customized to include a FileUpload control for each binary data field. Отправленные данные могут быть сохранены в файловой системе веб-сервера или назначены параметру источника данных в обработчике событий DetailsView s ItemInserting.The uploaded data can then be saved to the web server s file system or assigned to a data source parameter in the DetailsView s ItemInserting event handler.

Сохранение двоичных данных в файловой системе требует больше планирования, чем сохранение данных непосредственно в базе данных.Saving binary data to the file system requires more planning than saving data directly into the database. Необходимо выбрать схему именования, чтобы избежать перезаписи другой стороной с помощью другого пользователя.A naming scheme must be chosen in order to avoid one user s upload overwriting another s. Кроме того, при сбое вставки базы данных необходимо выполнить дополнительные действия для удаления отправленного файла.Also, extra steps must be taken to delete the uploaded file if the database insert fails.

Теперь у нас есть возможность добавлять новые категории в систему с помощью буклета и картинки, но мы еще не можем узнать, как обновить существующие двоичные данные категории s или как правильно удалить двоичные данные для удаленной категории.We now have the ability to add new categories to the system with a brochure and picture, but we ve yet to look at how to update an existing category s binary data or how to correctly remove the binary data for a deleted category. Мы рассмотрим эти две темы в следующем руководстве.We'll explore these two topics in the next tutorial.

Поздравляем с программированием!Happy Programming!

Об автореAbout the Author

Скотт Митчелл, автор семи книг по ASP/ASP. NET и основатель 4GuysFromRolla.com, работал с веб-технологиями Майкрософт с 1998.Scott Mitchell, author of seven ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Скотт работает как независимый консультант, преподаватель и модуль записи.Scott works as an independent consultant, trainer, and writer. Его последняя книга — Sams обучать себя ASP.NET 2,0 за 24 часа.His latest book is Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Он доступен по адресу mitchell@4GuysFromRolla.com.He can be reached at mitchell@4GuysFromRolla.com. или через его блог, который можно найти по адресу http://ScottOnWriting.NET.or via his blog, which can be found at http://ScottOnWriting.NET.

Специальная благодарностьSpecial Thanks To

Эта серия руководств была рассмотрена многими полезными рецензентами.This tutorial series was reviewed by many helpful reviewers. Потенциальные рецензенты для этого руководства: Дейв Гарднер, Терезой Мерфи и Бернадетте Леигх.Lead reviewers for this tutorial were Dave Gardner, Teresa Murphy, and Bernadette Leigh. Хотите ознакомиться с моими будущими статьями MSDN?Interested in reviewing my upcoming MSDN articles? Если это так, расположите строку в mitchell@4GuysFromRolla.com.If so, drop me a line at mitchell@4GuysFromRolla.com.