삽입, 업데이트 및 삭제와 연결된 이벤트 검사(VB)Examining the Events Associated with Inserting, Updating, and Deleting (VB)

Scott Mitchellby Scott Mitchell

샘플 앱 다운로드 또는 PDF 다운로드Download Sample App or Download PDF

이 자습서에서는 ASP.NET data 웹 컨트롤의 삽입, 업데이트 또는 삭제 작업 전후에 발생 하는 이벤트를 사용 하 여 검토 합니다.In this tutorial we'll examine using the events that occur before, during, and after an insert, update, or delete operation of an ASP.NET data Web control. 제품 필드의 하위 집합만 업데이트 하도록 편집 인터페이스를 사용자 지정 하는 방법에 대해서도 살펴봅니다.We'll also see how to customize the editing interface to only update a subset of the product fields.

소개Introduction

GridView, DetailsView 또는 FormView 컨트롤의 기본 제공 삽입, 편집 또는 삭제 기능을 사용 하는 경우 최종 사용자가 새 레코드를 추가 하거나 기존 레코드를 업데이트 또는 삭제 하는 프로세스를 완료할 때 다양 한 단계가 발생 합니다.When using the built-in inserting, editing, or deleting features of the GridView, DetailsView, or FormView controls, a variety of steps transpire when the end user completes the process of adding a new record or updating or deleting an existing record. 이전 자습서에서 설명한 대로 GridView에서 행을 편집 하면 편집 단추가 업데이트 및 취소 단추로 바뀌고 BoundFields 텍스트 상자로 바뀝니다.As we discussed in the previous tutorial, when a row is edited in the GridView the Edit button is replaced by Update and Cancel buttons and the BoundFields turn into TextBoxes. 최종 사용자가 데이터를 업데이트 하 고 업데이트를 클릭 하면 다시 게시 시 다음 단계가 수행 됩니다.After the end user updates the data and clicks Update, the following steps are performed on postback:

  1. GridView는 DataKeyNames 속성을 통해 사용자가 입력 한 값과 함께 ObjectDataSource의 UpdateParameters를 편집 된 레코드의 고유 식별 필드로 채웁니다.The GridView populates its ObjectDataSource's UpdateParameters with the edited record's unique identifying field(s) (via the DataKeyNames property) along with the values entered by the user
  2. GridView는 ObjectDataSource의 Update() 메서드를 호출 하며,이 메서드는 기본 개체 (ProductsDAL.UpdateProduct이전 자습서의)에서 적절 한 메서드를 호출 합니다.The GridView invokes its ObjectDataSource's Update() method, which in turn invokes the appropriate method in the underlying object (ProductsDAL.UpdateProduct, in our previous tutorial)
  3. 이제 업데이트 된 변경 내용을 포함 하는 기본 데이터가 GridView에 바인딩 되었습니다.The underlying data, which now includes the updated changes, is rebound to the GridView

이러한 단계를 수행 하는 동안 많은 이벤트가 발생 하 여 필요에 따라 사용자 지정 논리를 추가 하는 이벤트 처리기를 만들 수 있습니다.During this sequence of steps, a number of events fire, enabling us to create event handlers to add custom logic where needed. 예를 들어 1 단계 전에 GridView의 RowUpdating 이벤트가 발생 합니다.For example, prior to Step 1, the GridView's RowUpdating event fires. 지금은 유효성 검사 오류가 발생 하는 경우 업데이트 요청을 취소할 수 있습니다.We can, at this point, cancel the update request if there is some validation error. Update() 메서드가 호출 되 면 ObjectDataSource의 Updating 이벤트가 발생 하 여 UpdateParameters의 값을 추가 하거나 사용자 지정할 수 있습니다.When the Update() method is invoked, the ObjectDataSource's Updating event fires, providing an opportunity to add or customize the values of any of the UpdateParameters. ObjectDataSource의 내부 개체의 메서드가 실행을 완료 하면 ObjectDataSource의 Updated 이벤트가 발생 합니다.After the ObjectDataSource's underlying object's method has completed executing, the ObjectDataSource's Updated event is raised. Updated 이벤트에 대 한 이벤트 처리기는 업데이트 작업에 대 한 세부 정보 (예: 영향을 받는 행 수 및 예외 발생 여부)를 검사할 수 있습니다.An event handler for the Updated event can inspect the details about the update operation, such as how many rows were affected and whether or not an exception occurred. 마지막으로 2 단계 이후에 GridView의 RowUpdated 이벤트가 발생 합니다. 이 이벤트에 대 한 이벤트 처리기는 수행 된 업데이트 작업에 대 한 추가 정보를 확인할 수 있습니다.Finally, after Step 2, the GridView's RowUpdated event fires; an event handler for this event can examine additional information about the update operation just performed.

그림 1에서는 GridView를 업데이트할 때 발생 하는 이러한 일련의 이벤트와 단계를 보여 줍니다.Figure 1 depicts this series of events and steps when updating a GridView. 그림 1의 이벤트 패턴은 GridView로 업데이트 하는 데 고유 하지 않습니다.The event pattern in Figure 1 is not unique to updating with a GridView. GridView, DetailsView 또는 FormView의 데이터를 삽입, 업데이트 또는 삭제 하는 것은 데이터 웹 컨트롤과 ObjectDataSource 모두에 대해 사전 및 사후 수준 이벤트의 동일한 순서를 precipitates 합니다.Inserting, updating, or deleting data from the GridView, DetailsView, or FormView precipitates the same sequence of pre- and post-level events for both the data Web control and the ObjectDataSource.

GridView에서 데이터를 업데이트할 때 일련의 사전 및 사후 이벤트 발생 A Series of Pre- and Post-Events Fire When Updating Data in a GridView

그림 1: GridView에서 데이터를 업데이트할 때의 일련의 사전 및 사후 이벤트 발생 (전체 크기 이미지를 보려면 클릭)Figure 1: A Series of Pre- and Post-Events Fire When Updating Data in a GridView (Click to view full-size image)

이 자습서에서는 이러한 이벤트를 사용 하 여 기본 제공 되는 ASP.NET 데이터 웹 컨트롤의 삽입, 업데이트 및 삭제 기능을 확장 하는 방법을 살펴보겠습니다.In this tutorial we'll examine using these events to extend the built-in inserting, updating, and deleting capabilities of the ASP.NET data Web controls. 제품 필드의 하위 집합만 업데이트 하도록 편집 인터페이스를 사용자 지정 하는 방법에 대해서도 살펴봅니다.We'll also see how to customize the editing interface to only update a subset of the product fields.

1 단계: 제품의ProductNameUnitPrice필드 업데이트Step 1: Updating a Product'sProductNameandUnitPriceFields

이전 자습서의 편집 인터페이스에서 읽기 전용이 아닌 모든 제품 필드를 포함 해야 했습니다.In the editing interfaces from the previous tutorial all product fields that were not read-only had to be included. GridView에서 필드를 제거 하는 경우 QuantityPerUnit-데이터를 업데이트할 때 데이터 웹 컨트롤이 ObjectDataSource의 QuantityPerUnit UpdateParameters 값을 설정 하지 않습니다.If we were to remove a field from the GridView - say QuantityPerUnit - when updating the data the data Web control would not set the ObjectDataSource's QuantityPerUnit UpdateParameters value. 그러면 ObjectDataSource는 Nothing 값을 UpdateProduct BLL (비즈니스 논리 계층) 메서드로 전달 하 여 편집 된 데이터베이스 레코드의 QuantityPerUnit 열을 NULL 값으로 변경 합니다.The ObjectDataSource would then pass in a value of Nothing into the UpdateProduct Business Logic Layer (BLL) method, which would change the edited database record's QuantityPerUnit column to a NULL value. 마찬가지로 ProductName와 같은 필수 필드가 편집 인터페이스에서 제거 되는 경우 " ' ProductName ' 열이 null을 허용 하지않습니다." 라는 오류와 함께 업데이트가 실패 합니다.Similarly, if a required field, such as ProductName, is removed from the editing interface, the update will fail with a "Column 'ProductName' does not allow nulls" exception. 이 동작의 이유는 ObjectDataSource가 각 product 필드에 대 한 입력 매개 변수를 예상 하는 ProductsBLL 클래스의 UpdateProduct 메서드를 호출 하도록 구성 되었기 때문입니다.The reason for this behavior was because the ObjectDataSource was configured to call the ProductsBLL class's UpdateProduct method, which expected an input parameter for each of the product fields. 따라서 ObjectDataSource의 UpdateParameters 컬렉션은 메서드의 각 입력 매개 변수에 대 한 매개 변수를 포함 합니다.Therefore, the ObjectDataSource's UpdateParameters collection contained a parameter for each of the method's input parameters.

최종 사용자가 필드의 하위 집합만 업데이트할 수 있는 데이터 웹 컨트롤을 제공 하려는 경우 ObjectDataSource의 Updating 이벤트 처리기에서 누락 된 UpdateParameters 값을 프로그래밍 방식으로 설정 하거나 필드의 하위 집합만 필요한 BLL 메서드를 만들고 호출 해야 합니다.If we want to provide a data Web control that allows the end user to only update a subset of fields, then we need to either programmatically set the missing UpdateParameters values in the ObjectDataSource's Updating event handler or create and call a BLL method that expects only a subset of the fields. 이러한 후자의 방법을 살펴보겠습니다.Let's explore this latter approach.

특히 편집 가능한 GridView의 ProductNameUnitPrice 필드를 표시 하는 페이지를 만들어 보겠습니다.Specifically, let's create a page that displays just the ProductName and UnitPrice fields in an editable GridView. 이 GridView의 편집 인터페이스에서는 사용자가 두 개의 표시 된 필드인 ProductNameUnitPrice만 업데이트할 수 있습니다.This GridView's editing interface will only allow the user to update the two displayed fields, ProductName and UnitPrice. 이 편집 인터페이스는 제품 필드의 하위 집합만 제공 하므로 기존 BLL의 UpdateProduct 메서드를 사용 하 고 누락 된 product 필드 값이 Updating 이벤트 처리기에서 프로그래밍 방식으로 설정 되어 있거나 GridView에 정의 된 필드의 하위 집합만 필요한 새 BLL 메서드를 만들어야 하는 ObjectDataSource를 만들어야 합니다.Since this editing interface only provides a subset of a product's fields, we either need to create an ObjectDataSource that uses the existing BLL's UpdateProduct method and has the missing product field values set programmatically in its Updating event handler, or we need to create a new BLL method that expects only the subset of fields defined in the GridView. 이 자습서에서는 두 번째 옵션을 사용 하 여 입력 매개 변수 productName, unitPrice, productID에 사용 되는 UpdateProduct 메서드의 오버 로드를 만듭니다.For this tutorial, let's use the latter option and create an overload of the UpdateProduct method, one that takes in just three input parameters: productName, unitPrice, and productID:

<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Update, False)> _
    Public Function UpdateProduct(productName As String, _
        unitPrice As Nullable(Of Decimal), productID As Integer) _
        As Boolean

    Dim products As Northwind.ProductsDataTable = _
        Adapter.GetProductByProductID(productID)

    If products.Count = 0 Then
        Return False
    End If

    Dim product As Northwind.ProductsRow = products(0)

    product.ProductName = productName
    If Not unitPrice.HasValue Then
        product.SetUnitPriceNull()
    Else
        product.UnitPrice = unitPrice.Value
    End If

    Dim rowsAffected As Integer = Adapter.Update(product)

    Return rowsAffected = 1
End Function

원래 UpdateProduct 메서드와 마찬가지로이 오버 로드는 데이터베이스에 지정 된 ProductID제품이 있는지 확인 하 여 시작 합니다.Like the original UpdateProduct method, this overload starts by checking to see if there is a product in the database with the specified ProductID. 그렇지 않으면 제품 정보 업데이트 요청이 실패 했음을 나타내는 False를 반환 합니다.If not, it returns False, indicating that the request to update the product information failed. 그렇지 않으면 기존 제품 레코드의 ProductNameUnitPrice 필드를 적절 하 게 업데이트 하 고 TableAdapter의 Update() 메서드를 호출 하 여 ProductsRow 인스턴스를 전달 하 여 업데이트를 커밋합니다.Otherwise it updates the existing product record's ProductName and UnitPrice fields accordingly and commits the update by calling the TableAdapter's Update() method, passing in the ProductsRow instance.

이 외에도 ProductsBLL 클래스를 사용 하 여 간소화 된 GridView 인터페이스를 만들 준비가 되었습니다.With this addition to our ProductsBLL class, we're ready to create the simplified GridView interface. EditInsertDelete 폴더에서 DataModificationEvents.aspx를 열고 페이지에 GridView를 추가 합니다.Open the DataModificationEvents.aspx in the EditInsertDelete folder and add a GridView to the page. 새 ObjectDataSource를 만들고 GetProductsSelect() 메서드 매핑을 사용 하 여 ProductsBLL 클래스를 사용 하도록 구성 하 고 UpdateProduct, productNameunitPrice입력 매개 변수만 사용 하는 productID 오버 로드에 해당 Update() 메서드 매핑을 구성 합니다.Create a new ObjectDataSource and configure it to use the ProductsBLL class with its Select() method mapping to GetProducts and its Update() method mapping to the UpdateProduct overload that takes in only the productName, unitPrice, and productID input parameters. 그림 2에서는 ObjectDataSource의 Update() 메서드를 ProductsBLL 클래스의 새 UpdateProduct 메서드 오버 로드에 매핑할 때 데이터 원본 만들기 마법사를 보여 줍니다.Figure 2 shows the Create Data Source wizard when mapping the ObjectDataSource's Update() method to the ProductsBLL class's new UpdateProduct method overload.

ObjectDataSource의 Update () 메서드를 새 UpdateProduct 오버 로드에 매핑합니다.Map the ObjectDataSource's Update() Method to the New UpdateProduct Overload

그림 2: ObjectDataSource의 Update() 메서드를 새 UpdateProduct 오버 로드에 매핑 (전체 크기 이미지를 보려면 클릭)Figure 2: Map the ObjectDataSource's Update() Method to the New UpdateProduct Overload (Click to view full-size image)

이 예제에서는 처음에는 데이터를 편집 하는 기능만 필요 하지만 레코드를 삽입 하거나 삭제 하는 것은 필요 하지 않습니다. 삽입 및 삭제 탭으로 이동 하 고 드롭다운 목록에서 (없음)을 선택 하 여 ObjectDataSource의 Insert()Delete() 메서드가 ProductsBLL 클래스의 메서드에 매핑되지 않도록 명시적으로 지정 합니다.Since our example will initially just need the ability to edit data, but not to insert or delete records, take a moment to explicitly indicate that the ObjectDataSource's Insert() and Delete() methods shouldn't be mapped to any of the ProductsBLL class's methods by going to the INSERT and DELETE tabs and choosing (None) from the drop-down list.

삽입 및 삭제 탭의 드롭다운 목록에서 (없음)을 선택 .Choose (None) From the Drop-Down List for the INSERT and DELETE Tabs

그림 3: 삽입 및 삭제 탭의 드롭다운 목록에서 (없음) 선택 (전체 크기 이미지를 보려면 클릭)Figure 3: Choose (None) From the Drop-Down List for the INSERT and DELETE Tabs (Click to view full-size image)

이 마법사를 완료 한 후 GridView의 스마트 태그에서 편집 사용 확인란을 선택 합니다.After completing this wizard check the Enable Editing checkbox from the GridView's smart tag.

데이터 소스 만들기 마법사를 완료 하 고 GridView에 바인딩한 경우 Visual Studio에서 두 컨트롤에 대 한 선언적 구문을 만들었습니다.With the completion of the Create Data Source wizard and binding that to the GridView, Visual Studio has created the declarative syntax for both controls. 원본 뷰로 이동 하 여 아래와 같이 ObjectDataSource의 선언 태그를 검사 합니다.Go to the Source view to inspect the ObjectDataSource's declarative markup, which is shown below:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
    TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

ObjectDataSource의 Insert()Delete() 메서드에 대 한 매핑이 없으므로 InsertParameters 또는 DeleteParameters 섹션이 없습니다.Since there are no mappings for the ObjectDataSource's Insert() and Delete() methods, there are no InsertParameters or DeleteParameters sections. 또한 Update() 메서드는 세 개의 입력 매개 변수만 허용 하는 UpdateProduct 메서드 오버 로드에 매핑되므로 UpdateParameters 섹션에는 Parameter 인스턴스가 3 개만 있습니다.Furthermore, since the Update() method is mapped to the UpdateProduct method overload that only accepts three input parameters, the UpdateParameters section has just three Parameter instances.

ObjectDataSource의 OldValuesParameterFormatString 속성은 original_{0}로 설정 됩니다.Note that the ObjectDataSource's OldValuesParameterFormatString property is set to original_{0}. 이 속성은 데이터 소스 구성 마법사를 사용 하는 경우 Visual Studio에서 자동으로 설정 됩니다.This property is set automatically by Visual Studio when using the Configure Data Source wizard. 그러나 BLL 메서드에 원래 ProductID 값이 전달 되는 것으로 간주 되지 않으므로 ObjectDataSource의 선언적 구문에서이 속성 할당을 모두 제거 합니다.However, since our BLL methods don't expect the original ProductID value to be passed in, remove this property assignment altogether from the ObjectDataSource's declarative syntax.

Note

디자인 뷰에 있는 속성 창에서 OldValuesParameterFormatString 속성 값을 지우면 속성은 여전히 선언 구문에 있지만 빈 문자열로 설정 됩니다.If you simply clear out the OldValuesParameterFormatString property value from the Properties window in the Design view, the property will still exist in the declarative syntax, but will be set to an empty string. 선언적 구문에서 속성을 완전히 제거 하거나 속성 창에서 값을 기본값인 {0}로 설정 합니다.Either remove the property altogether from the declarative syntax or, from the Properties window, set the value to the default, {0}.

ObjectDataSource에는 제품 이름, 가격 및 ID에 대 한 UpdateParameters 포함 되어 있지만 Visual Studio는 각 제품의 필드에 대해 GridView에서 BoundField 또는 CheckBoxField를 추가 했습니다.While the ObjectDataSource only has UpdateParameters for the product's name, price, and ID, Visual Studio has added a BoundField or CheckBoxField in the GridView for each of the product's fields.

GridView 각 제품의 필드에 대 한 BoundField 또는 CheckBoxField를 포함 합니다.The GridView Contains a BoundField or CheckBoxField for Each of the Product's Fields

그림 4: GridView에 각 제품의 필드에 대 한 BoundField 또는 CheckBoxField 포함 (전체 크기 이미지를 보려면 클릭)Figure 4: The GridView Contains a BoundField or CheckBoxField for Each of the Product's Fields (Click to view full-size image)

최종 사용자가 제품을 편집 하 고 업데이트 단추를 클릭 하면 GridView는 읽기 전용이 아닌 필드를 열거 합니다.When the end user edits a product and clicks its Update button, the GridView enumerates those fields that were not read-only. 그런 다음 ObjectDataSource의 UpdateParameters 컬렉션에 있는 해당 매개 변수 값을 사용자가 입력 한 값으로 설정 합니다.It then sets the value of the corresponding parameter in the ObjectDataSource's UpdateParameters collection to the value entered by the user. 해당 하는 매개 변수가 없는 경우 GridView는 컬렉션에 하나를 추가 합니다.If there is not a corresponding parameter, the GridView adds one to the collection. 따라서 GridView에 모든 제품의 필드에 대 한 BoundFields 및 CheckBoxFields가 포함 되어 있으면 objectdatasource의 선언적 태그가 3 개의 입력 매개 변수만 지정 한다는 사실에도 ObjectDataSource는 이러한 모든 매개 변수를 사용 하는 UpdateProduct 오버 로드를 호출 합니다 (그림 5 참조).Therefore, if our GridView contains BoundFields and CheckBoxFields for all of the product's fields, the ObjectDataSource will end up invoking the UpdateProduct overload that takes in all of these parameters, despite the fact that the ObjectDataSource's declarative markup specifies only three input parameters (see Figure 5). 마찬가지로 GridView에 UpdateProduct 오버 로드에 대 한 입력 매개 변수에 해당 하지 않는 읽기 전용 product 필드가 일부 조합 되어 있으면 업데이트를 시도할 때 예외가 발생 합니다.Similarly, if there is some combination of non-read-only product fields in the GridView that doesn't correspond to the input parameters for a UpdateProduct overload, an exception will be raised when attempting to update.

GridView가 ObjectDataSource의 UpdateParameters 컬렉션에 매개 변수를 추가 합니다.The GridView Will Add Parameters to the ObjectDataSource's UpdateParameters Collection

그림 5: GridView가 ObjectDataSource의 UpdateParameters 컬렉션에 매개 변수 추가 (전체 크기 이미지를 보려면 클릭)Figure 5: The GridView Will Add Parameters to the ObjectDataSource's UpdateParameters Collection (Click to view full-size image)

ObjectDataSource에서 제품의 이름, 가격 및 ID만 사용 하는 UpdateProduct 오버 로드를 호출 하도록 하려면 ProductNameUnitPrice에 대 한 편집 가능한 필드가 있도록 GridView를 제한 해야 합니다.To ensure that the ObjectDataSource invokes the UpdateProduct overload that takes in just the product's name, price, and ID, we need to restrict the GridView to having editable fields for just the ProductName and UnitPrice. 다른 BoundFields 및 CheckBoxFields을 제거 하거나, 다른 필드의 ReadOnly 속성을 True로 설정 하거나, 둘 중 일부를 조합 하 여이를 수행할 수 있습니다.This can be accomplished by removing the other BoundFields and CheckBoxFields, by setting those other fields' ReadOnly property to True, or by some combination of the two. 이 자습서에서는 ProductNameUnitPrice BoundFields를 제외한 모든 GridView 필드를 단순히 제거 하 고 그 후에 GridView의 선언적 태그가 다음과 같이 표시 되도록 합니다.For this tutorial let's simply remove all GridView fields except the ProductName and UnitPrice BoundFields, after which the GridView's declarative markup will look like:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:BoundField DataField="ProductName"
          HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
          SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>

UpdateProduct 오버 로드에는 세 개의 입력 매개 변수가 필요 하지만 GridView에는 두 개의 BoundFields 있습니다.Even though the UpdateProduct overload expects three input parameters, we only have two BoundFields in our GridView. productID 입력 매개 변수가 기본 키 값이 고 편집 된 행의 DataKeyNames 속성 값을 통해 전달 되기 때문입니다.This is because the productID input parameter is a primary key value and passed in through the value of the DataKeyNames property for the edited row.

UpdateProduct 오버 로드와 함께 GridView를 사용 하 여 사용자는 다른 제품 필드를 잃지 않고 제품의 이름과 가격만 편집할 수 있습니다.Our GridView, along with the UpdateProduct overload, allows a user to edit just the name and price of a product without losing any of the other product fields.

인터페이스 제품의 이름과 가격만 편집할 수 있습니다.The Interface Allows Editing Just the Product's Name and Price

그림 6: 인터페이스에서 제품의 이름과 가격만 편집할 수 있음 (전체 크기 이미지를 보려면 클릭)Figure 6: The Interface Allows Editing Just the Product's Name and Price (Click to view full-size image)

Note

이전 자습서에서 설명한 대로 GridView의 뷰 상태를 사용 하도록 설정 하는 것이 매우 중요 합니다 (기본 동작).As discussed in the previous tutorial, it is vitally important that the GridView s view state be enabled (the default behavior). GridView s EnableViewState 속성을 false로 설정 하면 동시 사용자가 실수로 레코드를 삭제 하거나 편집 하는 위험을 발생 시킬 수 있습니다.If you set the GridView s EnableViewState property to false, you run the risk of having concurrent users unintentionally deleting or editing records. 자세한 내용은 경고: 편집 및/또는 삭제를 지원 하 고 해당 뷰 상태를 사용할 수 없는 ASP.NET 2.0 gridviews/DetailsView/FormViews의 동시성 문제 를 참조 하세요.See WARNING: Concurrency Issue with ASP.NET 2.0 GridViews/DetailsView/FormViews that Support Editing and/or Deleting and Whose View State is Disabled for more information.

UnitPrice서식 향상Improving theUnitPriceFormatting

그림 6에 표시 된 GridView 예제가 작동 하는 반면 UnitPrice 필드는 서식이 지정 되지 않으므로 통화 기호가 없고 소수 자릿수가 네 자리에 있는 가격 표시가 표시 됩니다.While the GridView example shown in Figure 6 works, the UnitPrice field is not formatted at all, resulting in a price display that lacks any currency symbols and has four decimal places. 편집할 수 없는 행에 통화 서식을 적용 하려면 UnitPrice BoundField의 DataFormatString 속성을 {0:c}로 설정 하 고 해당 HtmlEncode 속성을 False로 설정 하면 됩니다.To apply a currency formatting for the non-editable rows, simply set the UnitPrice BoundField's DataFormatString property to {0:c} and its HtmlEncode property to False.

UnitPrice의 DataFormatString 및 HtmlEncode 속성을 적절 하 게 설정 Set the UnitPrice's DataFormatString and HtmlEncode Properties Accordingly

그림 7: UnitPriceDataFormatStringHtmlEncode 속성을 적절하 게 설정 (전체 크기 이미지를 보려면 클릭)Figure 7: Set the UnitPrice's DataFormatString and HtmlEncode Properties Accordingly (Click to view full-size image)

이러한 변경으로 편집할 수 없는 행은 가격의 서식을 통화로 지정 합니다. 그러나 편집 된 행은 통화 기호 없이 네 개의 소수 자릿수로 값을 계속 표시 합니다.With this change, the non-editable rows format the price as a currency; the edited row, however, still displays the value without the currency symbol and with four decimal places.

편집할 수 없는 행을 통화 값으로 서식 지정 The Non-Editable Rows are Now Formatted as Currency Values

그림 8: 편집할 수 없는 행의 서식이 통화 값으로 지정 되었습니다 (전체 크기 이미지를 보려면 클릭).Figure 8: The Non-Editable Rows are Now Formatted as Currency Values (Click to view full-size image)

DataFormatString 속성에 지정 된 서식 지정 지침은 BoundField의 ApplyFormatInEditMode 속성을 True (기본값은 False)로 설정 하 여 편집 인터페이스에 적용할 수 있습니다.The formatting instructions specified in the DataFormatString property can be applied to the editing interface by setting the BoundField's ApplyFormatInEditMode property to True (the default is False). 잠시 시간을 사용 하 여이 속성을 True설정 합니다.Take a moment to set this property to True.

UnitPrice BoundField의 ApplyFormatInEditMode 속성을 True로 설정 합니다.Set the UnitPrice BoundField's ApplyFormatInEditMode property to True

그림 9: UnitPrice BoundField의 ApplyFormatInEditMode 속성을 True로 설정 (전체 크기 이미지를 보려면 클릭)Figure 9: Set the UnitPrice BoundField's ApplyFormatInEditMode property to True (Click to view full-size image)

이와 같이 변경 하면 편집 된 행에 표시 되는 UnitPrice 값도 통화로 형식이 지정 됩니다.With this change, the value of the UnitPrice displayed in the edited row is also formatted as a currency.

편집 된 행의 UnitPrice 값이 현재 통화로 서식 지정 된 The Edited Row's UnitPrice Value is Now Formatted as a Currency

그림 10: 편집 된 행의 UnitPrice 값이 통화 형식으로 지정 됩니다 (전체 크기 이미지를 보려면 클릭).Figure 10: The Edited Row's UnitPrice Value is Now Formatted as a Currency (Click to view full-size image)

그러나 $19.00 등의 텍스트 상자에서 통화 기호를 사용 하 여 제품을 업데이트 하면 FormatException발생 합니다.However, updating a product with the currency symbol in the textbox such as $19.00 throws a FormatException. GridView가 사용자 제공 값을 ObjectDataSource의 UpdateParameters 컬렉션에 할당 하려고 하면 UnitPrice 문자열 "$19.00"을 매개 변수에 필요한 Decimal으로 변환할 수 없습니다 (그림 11 참조).When the GridView attempts to assign the user-supplied values to the ObjectDataSource's UpdateParameters collection it is unable to convert the UnitPrice string "$19.00" into the Decimal required by the parameter (see Figure 11). 이를 해결 하기 위해 GridView의 RowUpdating 이벤트에 대 한 이벤트 처리기를 만들고 사용자 제공 UnitPrice를 통화 형식 Decimal로 구문 분석 합니다.To remedy this we can create an event handler for the GridView's RowUpdating event and have it parse the user-supplied UnitPrice as a currency-formatted Decimal.

GridView의 RowUpdating 이벤트는 GridViewUpdateEventArgs형식의 개체를 두 번째 매개 변수로 받아들입니다. 여기에는 NewValues 사전을 ObjectDataSource의 UpdateParameters 컬렉션에 할당할 준비가 된 사용자 제공 값을 보유 하는 속성 중 하나로 포함 됩니다.The GridView's RowUpdating event accepts as its second parameter an object of type GridViewUpdateEventArgs, which includes a NewValues dictionary as one of its properties that holds the user-supplied values ready to be assigned to the ObjectDataSource's UpdateParameters collection. RowUpdating 이벤트 처리기에서 다음 코드 줄과 함께 통화 형식을 사용 하 여 구문 분석 된 10 진수 값을 사용 하 여 NewValues 컬렉션의 기존 UnitPrice 값을 덮어쓸 수 있습니다.We can overwrite the existing UnitPrice value in the NewValues collection with a decimal value parsed using the currency format with the following lines of code in the RowUpdating event handler:

Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
    Handles GridView1.RowUpdating
    If e.NewValues("UnitPrice") IsNot Nothing Then
        e.NewValues("UnitPrice") = _
            Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
                System.Globalization.NumberStyles.Currency)
    End If
End Sub

사용자가 UnitPrice 값 (예: "$19.00")을 제공한 경우 Decimal로 계산 된 10 진수 값으로이 값을 덮어씁니다 . 구문분석 하 고 값을 통화로 구문 분석 합니다.If the user has supplied a UnitPrice value (such as "$19.00"), this value is overwritten with the decimal value computed by Decimal.Parse, parsing the value as a currency. 이렇게 하면 통화 기호, 쉼표, 소수점 등의 경우 decimal을 올바르게 구문 분석 하 고, NumberStyles 네임 스페이스에서 열거형 을 사용 합니다.This will correctly parse the decimal in the event of any currency symbols, commas, decimal points, and so on, and uses the NumberStyles enumeration in the System.Globalization namespace.

그림 11은 사용자가 제공 하는 UnitPrice의 통화 기호로 인 한 문제를 모두 보여 주며, GridView의 RowUpdating 이벤트 처리기를 활용 하 여 이러한 입력을 올바르게 구문 분석 하는 방법을 보여 줍니다.Figure 11 shows both the problem caused by currency symbols in the user-supplied UnitPrice, along with how the GridView's RowUpdating event handler can be utilized to correctly parse such input.

편집 된 행의 UnitPrice 값이 현재 통화로 서식 지정 된 The Edited Row's UnitPrice Value is Now Formatted as a Currency

그림 11: 편집한 행의 UnitPrice 값이 통화 형식으로 지정 됨 (전체 크기 이미지를 보려면 클릭)Figure 11: The Edited Row's UnitPrice Value is Now Formatted as a Currency (Click to view full-size image)

2 단계:NULL UnitPrices 금지Step 2: ProhibitingNULL UnitPrices

데이터베이스가 Products 테이블의 UnitPrice 열에서 NULL 값을 허용 하도록 구성 되어 있는 동안이 특정 페이지를 방문 하는 사용자가 NULL UnitPrice 값을 지정 하지 못하게 할 수 있습니다.While the database is configured to allow NULL values in the Products table's UnitPrice column, we may want to prevent users visiting this particular page from specifying a NULL UnitPrice value. 즉, 사용자가 제품 행을 편집할 때 UnitPrice 값을 입력 하지 못한 경우에는 데이터베이스에 결과를 저장 하는 대신,이 페이지를 통해 편집 된 모든 제품에 지정 된 가격이 있어야 한다는 메시지를 사용자에 게 알리는 메시지를 표시 하려는 메시지를 표시 하려고 합니다.That is, if a user fails to enter a UnitPrice value when editing a product row, rather than save the results to the database we want to display a message informing the user that, through this page, any edited products must have a price specified.

GridView의 RowUpdating 이벤트 처리기에 전달 되는 GridViewUpdateEventArgs 개체에는 True로 설정 된 경우 업데이트 프로세스가 종료 되는 Cancel 속성이 포함 되어 있습니다.The GridViewUpdateEventArgs object passed into the GridView's RowUpdating event handler contains a Cancel property that, if set to True, terminates the updating process. RowUpdating 이벤트 처리기를 확장 하 여 e.CancelTrue로 설정 하 고 NewValues 컬렉션의 UnitPrice 값에 Nothing값이 있는 이유를 설명 하는 메시지를 표시 해 보겠습니다.Let's extend the RowUpdating event handler to set e.Cancel to True and display a message explaining why if the UnitPrice value in the NewValues collection has a value of Nothing.

MustProvideUnitPriceMessage이라는 페이지에 Label 웹 컨트롤을 추가 하 여 시작 합니다.Start by adding a Label Web control to the page named MustProvideUnitPriceMessage. 사용자가 제품을 업데이트할 때 UnitPrice 값을 지정 하지 못하면이 레이블 컨트롤이 표시 됩니다.This Label control will be displayed if the user fails to specify a UnitPrice value when updating a product. 레이블의 Text 속성을 "제품에 대 한 가격을 제공 해야 합니다."로 설정 합니다.Set the Label's Text property to "You must provide a price for the product." 또한 다음과 같은 정의를 사용 하 여 Warning 이라는 Styles.css 새 CSS 클래스를 만들었습니다.I've also created a new CSS class in Styles.css named Warning with the following definition:

.Warning
{
    color: Red;
    font-style: italic;
    font-weight: bold;
    font-size: x-large;
}

마지막으로 레이블의 CssClass 속성을 Warning로 설정 합니다.Finally, set the Label's CssClass property to Warning. 이 시점에서 디자이너는 그림 12와 같이 GridView 위에 빨간색, 굵게, 기울임꼴, 매우 큰 글꼴 크기로 경고 메시지를 표시 해야 합니다.At this point the Designer should show the warning message in a red, bold, italic, extra large font size above the GridView, as shown in Figure 12.

레이블이 GridView 위에 추가 된 A Label Has Been Added Above the GridView

그림 12: GridView 위에 레이블이 추가 됨 (전체 크기 이미지를 보려면 클릭)Figure 12: A Label Has Been Added Above the GridView (Click to view full-size image)

기본적으로이 레이블은 숨겨야 하므로 Visible 속성을 Page_Load 이벤트 처리기에서 False로 설정 합니다.By default, this Label should be hidden, so set its Visible property to False in the Page_Load event handler:

Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    MustProvideUnitPriceMessage.Visible = False
End Sub

사용자가 UnitPrice지정 하지 않고 제품을 업데이트 하려고 시도 하는 경우 업데이트를 취소 하 고 경고 레이블을 표시 하려고 합니다.If the user attempts to update a product without specifying the UnitPrice, we want to cancel the update and display the warning label. 다음과 같이 GridView의 RowUpdating 이벤트 처리기를 확대 합니다.Augment the GridView's RowUpdating event handler as follows:

Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
    Handles GridView1.RowUpdating

    If e.NewValues("UnitPrice") IsNot Nothing Then
        e.NewValues("UnitPrice") = _
            Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
                System.Globalization.NumberStyles.Currency)
    Else
        MustProvideUnitPriceMessage.Visible = True

        e.Cancel = True
    End If
End Sub

사용자가 가격을 지정 하지 않고 제품을 저장 하려고 하면 업데이트가 취소 되 고 유용한 메시지가 표시 됩니다.If a user attempts to save a product without specifying a price, the update is cancelled and a helpful message is displayed. 데이터베이스 및 비즈니스 논리는 NULL UnitPrice s를 허용 하지만이 특정 ASP.NET 페이지는 그렇지 않습니다.While the database (and business logic) allows for NULL UnitPrice s, this particular ASP.NET page does not.

사용자가 단가를 비워 둘 수 없음A User Cannot Leave UnitPrice Blank

그림 13: 사용자가 UnitPrice 비워 둘 수 없음 (전체 크기 이미지를 보려면 클릭)Figure 13: A User Cannot Leave UnitPrice Blank (Click to view full-size image)

지금까지 GridView의 RowUpdating 이벤트를 사용 하 여 ObjectDataSource의 UpdateParameters 컬렉션에 할당 된 매개 변수 값을 프로그래밍 방식으로 변경 하 고 업데이트 프로세스를 모두 취소 하는 방법을 살펴보았습니다.So far we have seen how to use the GridView's RowUpdating event to programmatically alter the parameter values assigned to the ObjectDataSource's UpdateParameters collection as well as how to cancel the updating process altogether. 이러한 개념은 DetailsView 및 FormView 컨트롤로 전달 되며 삽입 및 삭제에도 적용 됩니다.These concepts carry over to the DetailsView and FormView controls and also apply to inserting and deleting.

이러한 작업은 Inserting, UpdatingDeleting 이벤트에 대 한 이벤트 처리기를 통해 ObjectDataSource 수준에서 수행할 수도 있습니다.These tasks can also be done at the ObjectDataSource level through event handlers for its Inserting, Updating, and Deleting events. 이러한 이벤트는 기본 개체의 연결 된 메서드를 호출 하기 전에 발생 하며 입력 매개 변수 컬렉션을 수정 하거나 작업을 완전히 취소할 수 있는 마지막 기회를 제공 합니다.These events fire before the associated method of the underlying object is invoked and provide a last-chance opportunity to modify the input parameters collection or cancel the operation outright. 이러한 세 이벤트에 대 한 이벤트 처리기에는 두 가지 대상 속성이 있는 ObjectDataSourceMethodEventArgs 형식의 개체가 전달 됩니다.The event handlers for these three events are passed an object of type ObjectDataSourceMethodEventArgs that has two properties of interest:

  • Cancel(True로 설정 된 경우 수행 중인 작업을 취소 합니다.Cancel, which, if set to True, cancels the operation being performed
  • InputParameters는 이벤트 처리기가 Inserting, Updating또는 Deleting 이벤트에 대 한 것인지에 따라 InsertParameters, UpdateParameters또는 DeleteParameters의 컬렉션입니다.InputParameters, which is the collection of InsertParameters, UpdateParameters, or DeleteParameters, depending on whether the event handler is for the Inserting, Updating, or Deleting event

ObjectDataSource 수준에서 매개 변수 값을 사용 하 여 작업 하는 방법을 설명 하기 위해 사용자가 새 제품을 추가할 수 있는 DetailsView을 페이지에 포함 하겠습니다.To illustrate working with the parameter values at the ObjectDataSource level, let's include a DetailsView in our page that allows the users to add a new product. 이 DetailsView은 데이터베이스에 새 제품을 빠르게 추가 하기 위한 인터페이스를 제공 하는 데 사용 됩니다.This DetailsView will be used to provide an interface for quickly adding a new product to the database. 새 제품을 추가할 때 사용자 인터페이스를 일관 되 게 유지 하려면 사용자가 ProductNameUnitPrice 필드 값만 입력할 수 있도록 합니다.To keep a consistent user interface when adding a new product let's allow the user to only enter values for the ProductName and UnitPrice fields. 기본적으로 DetailsView의 삽입 인터페이스에 지정 되지 않은 값은 NULL 데이터베이스 값으로 설정 됩니다.By default, those values that aren't supplied in the DetailsView's inserting interface will be set to a NULL database value. 그러나 ObjectDataSource의 Inserting 이벤트를 사용 하 여 다른 기본값을 삽입할 수 있습니다. 잠시 후에 표시 됩니다.However, we can use the ObjectDataSource's Inserting event to inject different default values, as we'll see shortly.

3 단계: 새 제품을 추가 하기 위한 인터페이스 제공Step 3: Providing an Interface to Add New Products

도구 상자의 DetailsView을 GridView 위의 디자이너로 끌어다 놓고 HeightWidth 속성을 지우고 페이지에 이미 있는 ObjectDataSource에 바인딩합니다.Drag a DetailsView from the Toolbox onto the Designer above the GridView, clear out its Height and Width properties, and bind it to the ObjectDataSource already present on the page. 이렇게 하면 각 제품의 필드에 대 한 BoundField 또는 CheckBoxField이 추가 됩니다.This will add a BoundField or CheckBoxField for each of the product's fields. 이 DetailsView을 사용 하 여 새 제품을 추가 하려고 하므로 스마트 태그에서 삽입 사용 옵션을 선택 해야 합니다. 그러나 ObjectDataSource의 Insert() 메서드가 ProductsBLL 클래스의 메서드에 매핑되지 않았기 때문에 이러한 옵션은 없습니다. (데이터 원본을 구성할 때이 매핑을 (없음)으로 설정 한다는 것을 기억 하십시오).Since we want to use this DetailsView to add new products, we need to check the Enable Inserting option from the smart tag; however, there's no such option because the ObjectDataSource's Insert() method is not mapped to a method in the ProductsBLL class (recall that we set this mapping to (None) when configuring the data source see Figure 3).

ObjectDataSource를 구성 하려면 스마트 태그에서 데이터 소스 구성 링크를 선택 하 여 마법사를 시작 합니다.To configure the ObjectDataSource, select the Configure Data Source link from its smart tag, launching the wizard. 첫 번째 화면에서는 ObjectDataSource가 바인딩되는 기본 개체를 변경할 수 있습니다. ProductsBLL로 설정 합니다.The first screen allows you to change the underlying object the ObjectDataSource is bound to; leave it set to ProductsBLL. 다음 화면은 ObjectDataSource의 메서드에서 기본 개체의에 대 한 매핑을 나열 합니다.The next screen lists the mappings from the ObjectDataSource's methods to the underlying object's. Insert()Delete() 메서드가 메서드에 매핑되지 않아야 한다는 것을 명시적으로 표시 했지만 삽입 및 삭제 탭으로 이동 하면 매핑이 있는 것을 볼 수 있습니다.Even though we explicitly indicated that the Insert() and Delete() methods should not be mapped to any methods, if you go to the INSERT and DELETE tabs you'll see that a mapping is there. 이는 ProductsBLLAddProductDeleteProduct 메서드가 DataObjectMethodAttribute 특성을 사용 하 여 각각 Insert()Delete()에 대 한 기본 메서드 임을 나타내는 것 이기 때문입니다.This is because the ProductsBLL's AddProduct and DeleteProduct methods use the DataObjectMethodAttribute attribute to indicate that they are the default methods for Insert() and Delete(), respectively. 따라서 일부 다른 값이 명시적으로 지정 되어 있지 않으면 마법사를 실행할 때마다 ObjectDataSource 마법사에서이를 선택 합니다.Hence, the ObjectDataSource wizard selects these each time you run the wizard unless there's some other value explicitly specified.

Insert() 메서드를 AddProduct 메서드를 가리키는 상태로 두고 삭제 탭의 드롭다운 목록을 (없음)로 다시 설정 합니다.Leave the Insert() method pointing to the AddProduct method, but again set the DELETE tab's drop-down list to (None).

삽입 탭의 드롭다운 목록을 AddProduct 메서드로 설정 합니다.Set the INSERT Tab's Drop-Down List to the AddProduct Method

그림 14: 삽입 탭의 드롭다운 목록을 AddProduct 메서드로 설정 (전체 크기 이미지를 보려면 클릭)Figure 14: Set the INSERT Tab's Drop-Down List to the AddProduct Method (Click to view full-size image)

삭제 탭의 드롭다운 목록을 (없음)으로 설정 합니다.Set the DELETE Tab's Drop-Down List to (None)

그림 15: 삭제 탭의 드롭다운 목록을 (없음)로 설정 (전체 크기 이미지를 보려면 클릭)Figure 15: Set the DELETE Tab's Drop-Down List to (None) (Click to view full-size image)

이러한 변경을 수행한 후 아래와 같이 ObjectDataSource의 선언 구문이 InsertParameters 컬렉션을 포함 하도록 확장 됩니다.After making these changes, the ObjectDataSource's declarative syntax will be expanded to include an InsertParameters collection, as shown below:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL"
    UpdateMethod="UpdateProduct" OnUpdating="ObjectDataSource1_Updating"
    InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
    <InsertParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
        <asp:Parameter Name="categoryID" Type="Int32" />
        <asp:Parameter Name="quantityPerUnit" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="unitsInStock" Type="Int16" />
        <asp:Parameter Name="unitsOnOrder" Type="Int16" />
        <asp:Parameter Name="reorderLevel" Type="Int16" />
        <asp:Parameter Name="discontinued" Type="Boolean" />
    </InsertParameters>
</asp:ObjectDataSource>

마법사를 다시 실행 하면 OldValuesParameterFormatString 속성이 다시 추가 됩니다.Rerunning the wizard added back the OldValuesParameterFormatString property. 이 속성을 기본값 ({0})으로 설정 하거나 선언적 구문에서 완전히 제거 하 여이 속성을 지우십시오.Take a moment to clear this property by setting it to the default value ({0}) or removing it altogether from the declarative syntax.

ObjectDataSource는 삽입 기능을 제공 하므로 DetailsView의 스마트 태그에는 삽입 가능 확인란이 포함 됩니다. 디자이너로 돌아가서이 옵션을 선택 합니다.With the ObjectDataSource providing inserting capabilities, the DetailsView's smart tag will now include the Enable Inserting checkbox; return to the Designer and check this option. 그런 다음 두 개의 BoundFields ProductNameUnitPrice와 CommandField만 갖도록 DetailsView을 줄이려면 상당한 합니다.Next, pare down the DetailsView so that it only has two BoundFields - ProductName and UnitPrice - and the CommandField. 이 시점에서 DetailsView의 선언 구문은 다음과 같습니다.At this point the DetailsView's declarative syntax should look like:

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Fields>
        <asp:BoundField DataField="ProductName"
          HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
          SortExpression="UnitPrice" />
        <asp:CommandField ShowInsertButton="True" />
    </Fields>
</asp:DetailsView>

그림 16은이 시점에서 브라우저를 통해 볼 때이 페이지를 보여 줍니다.Figure 16 shows this page when viewed through a browser at this point. 여기에서 볼 수 있듯이 DetailsView에는 첫 번째 제품의 이름과 가격이 나열 됩니다 (Chai).As you can see, the DetailsView lists the name and price of the first product (Chai). 그러나 원하는 것은 사용자가 데이터베이스에 새 제품을 신속 하 게 추가할 수 있는 방법을 제공 하는 삽입 인터페이스입니다.What we want, however, is an inserting interface that provides a means for the user to quickly add a new product to the database.

DetailsView은 현재 읽기 전용 모드에서 렌더링 됩니다.The DetailsView is Currently Rendered in Read-Only Mode

그림 16: DetailsView은 현재 읽기 전용 모드에서 렌더링 됩니다 (전체 크기 이미지를 보려면 클릭).Figure 16: The DetailsView is Currently Rendered in Read-Only Mode (Click to view full-size image)

삽입 모드에서 DetailsView을 표시 하려면 DefaultMode 속성을 Inserting으로 설정 해야 합니다.In order to show the DetailsView in its inserting mode we need to set the DefaultMode property to Inserting. 이렇게 하면 처음 방문할 때 DetailsView이 삽입 모드로 렌더링 되어 새 레코드를 삽입 한 후에도 삽입 모드로 유지 됩니다.This renders the DetailsView in insert mode when first visited and keeps it there after inserting a new record. 그림 17에 나와 있는 것 처럼 이러한 DetailsView은 새 레코드를 추가 하기 위한 빠른 인터페이스를 제공 합니다.As Figure 17 shows, such a DetailsView provides a quick interface for adding a new record.

DetailsView은 새 제품을 빠르게 추가 하기 위한 인터페이스를 제공 합니다.The DetailsView Provides an Interface for Quickly Adding a New Product

그림 17: DetailsView은 새 제품을 빠르게 추가 하기 위한 인터페이스를 제공 합니다 (전체 크기 이미지를 보려면 클릭).Figure 17: The DetailsView Provides an Interface for Quickly Adding a New Product (Click to view full-size image)

사용자가 제품 이름 및 가격 (예: 그림 17에서와 같이 "Acme 물" 및 1.99)을 입력 하 고 삽입을 클릭 하면 ensues 및 삽입 워크플로 시작 됩니다가 데이터베이스에 추가 되는 새 제품 레코드에 culminating.When the user enters a product name and price (such as "Acme Water" and 1.99, as in Figure 17) and clicks Insert, a postback ensues and the inserting workflow commences, culminating in a new product record being added to the database. DetailsView은 삽입 인터페이스를 유지 하며, GridView는 그림 18과 같이 새 제품을 포함 하기 위해 데이터 원본에 자동으로 자동으로 바인딩 됩니다.The DetailsView maintains its inserting interface and the GridView is automatically rebound to its data source in order to include the new product, as shown in Figure 18.

제품

그림 18: "Acme 워터" 제품이 데이터베이스에 추가 되었습니다.Figure 18: The Product "Acme Water" Has Been Added to the Database

그림 18의 GridView가 표시 되지 않지만 DetailsView 인터페이스 CategoryID, SupplierID, QuantityPerUnit등에 없는 product 필드는 데이터베이스 값 NULL 할당 됩니다.While the GridView in Figure 18 doesn't show it, the product fields lacking from the DetailsView interface CategoryID, SupplierID, QuantityPerUnit, and so on are assigned NULL database values. 다음 단계를 수행 하 여이를 확인할 수 있습니다.You can see this by performing the following steps:

  1. Visual Studio에서 서버 탐색기로 이동 합니다.Go to the Server Explorer in Visual Studio
  2. NORTHWND.MDF database 노드 확장Expanding the NORTHWND.MDF database node
  3. Products 데이터베이스 테이블 노드를 마우스 오른쪽 단추로 클릭 합니다.Right-click on the Products database table node
  4. 테이블 데이터 표시 선택Select Show Table Data

그러면 Products 테이블의 모든 레코드가 나열 됩니다.This will list all of the records in the Products table. 그림 19에 나와 있는 것 처럼 ProductID, ProductNameUnitPrice 이외의 모든 새 제품 열에는 NULL 값이 있습니다.As Figure 19 shows, all of our new product's columns other than ProductID, ProductName, and UnitPrice have NULL values.

DetailsView에서 제공 되지 않은 제품 필드에 NULL 값이 할당 됩니다.The Product Fields Not Provided in the DetailsView are Assigned NULL Values

그림 19: DetailsView에서 제공 하지 않는 제품 필드에 값 NULL 할당 (전체 크기 이미지를 보려면 클릭)Figure 19: The Product Fields Not Provided in the DetailsView are Assigned NULL Values (Click to view full-size image)

NULL가 최상의 기본 옵션이 아니거나 데이터베이스 열 자체에서 NULL를 허용 하지 않기 때문에 이러한 열 값 중 하나 이상에 대해 NULL 이외의 기본값을 제공할 수 있습니다.We may want to provide a default value other than NULL for one or more of these column values, either because NULL isn't the best default option or because the database column itself doesn't allow NULL s. 이를 위해 DetailsView의 InputParameters 컬렉션에 대 한 매개 변수 값을 프로그래밍 방식으로 설정할 수 있습니다.To accomplish this we can programmatically set the values of the parameters of the DetailsView's InputParameters collection. 이 할당은 DetailsView의 ItemInserting 이벤트에 대 한 이벤트 처리기 또는 ObjectDataSource의 Inserting 이벤트에서 수행할 수 있습니다.This assignment can be done either in the event handler for the DetailsView's ItemInserting event or the ObjectDataSource's Inserting event. 데이터 웹 컨트롤 수준에서 사전 및 사후 수준 이벤트를 사용 하는 것을 이미 살펴보았습니다. 이번에는 ObjectDataSource의 이벤트를 사용 하는 방법을 살펴보겠습니다.Since we've already looked at using the pre- and post-level events at the data Web control level, let's explore using the ObjectDataSource's events this time.

4 단계:CategoryIDSupplierID매개 변수에 값 할당Step 4: Assigning Values to theCategoryIDandSupplierIDParameters

이 자습서에서는이 인터페이스를 통해 새 제품을 추가할 때 응용 프로그램에 대해 CategoryIDSupplierID 값 1을 할당 해야 한다고 가정 합니다.For this tutorial let's imagine that for our application when adding a new product through this interface it should be assigned a CategoryID and SupplierID value of 1. 앞서 언급 했 듯이 ObjectDataSource는 데이터 수정 프로세스 중에 발생 하는 한 쌍의 사전 및 사후 수준 이벤트를 포함 합니다.As mentioned earlier, the ObjectDataSource has a pair of pre- and post-level events that fire during the data modification process. Insert() 메서드가 호출 되 면 ObjectDataSource는 먼저 Inserting 이벤트를 발생 시킨 다음 해당 Insert() 메서드가 매핑되는 메서드를 호출 하 고 마지막으로 Inserted 이벤트를 발생 시킵니다.When its Insert() method is invoked, the ObjectDataSource first raises its Inserting event, then calls the method that its Insert() method has been mapped to, and finally raises the Inserted event. Inserting 이벤트 처리기는 입력 매개 변수를 조정 하거나 작업을 완전히 취소할 수 있는 마지막 기회를 하나 이상 활용 합니다.The Inserting event handler affords us one last opportunity to tweak the input parameters or cancel the operation outright.

Note

실제 응용 프로그램에서는 사용자가 범주 및 공급자를 지정 하거나, 일부 조건 또는 비즈니스 논리 (ID 1을 무조건 선택 하는 것이 아님)에 따라이 값을 선택 하는 것이 좋습니다.In a real-world application you would likely want to either let the user specify the category and supplier or would pick this value for them based on some criteria or business logic (rather than blindly selecting an ID of 1). 예를 들어,이 예제에서는 ObjectDataSource의 사전 수준 이벤트에서 입력 매개 변수의 값을 프로그래밍 방식으로 설정 하는 방법을 보여 줍니다.Regardless, the example illustrates how to programmatically set the value of an input parameter from the ObjectDataSource's pre-level event.

잠시를 사용 하 여 ObjectDataSource의 Inserting 이벤트에 대 한 이벤트 처리기를 만듭니다.Take a moment to create an event handler for the ObjectDataSource's Inserting event. 이벤트 처리기의 두 번째 입력 매개 변수는 매개 변수 컬렉션에 액세스 하는 속성 (InputParameters) 및 작업을 취소 하는 속성 (Cancel)을 포함 하는 ObjectDataSourceMethodEventArgs형식의 개체입니다.Notice that the event handler's second input parameter is an object of type ObjectDataSourceMethodEventArgs, which has a property to access the parameters collection (InputParameters) and a property to cancel the operation (Cancel).

Protected Sub ObjectDataSource1_Inserting _
    (sender As Object, e As ObjectDataSourceMethodEventArgs) _
    Handles ObjectDataSource1.Inserting

End Sub

이 시점에서 InputParameters 속성은 DetailsView에서 할당 된 값을 가진 ObjectDataSource의 InsertParameters 컬렉션을 포함 합니다.At this point, the InputParameters property contains the ObjectDataSource's InsertParameters collection with the values assigned from the DetailsView. 이러한 매개 변수 중 하나의 값을 변경 하려면 e.InputParameters("paramName") = value을 사용 하면 됩니다.To change the value of one of these parameters, simply use: e.InputParameters("paramName") = value. 따라서 CategoryID을 설정 하 고 값을 1로 SupplierID Inserting 이벤트 처리기를 다음과 같이 조정 합니다.Therefore, to set the CategoryID and SupplierID to values of 1, adjust the Inserting event handler to look like the following:

Protected Sub ObjectDataSource1_Inserting _
    (sender As Object, e As ObjectDataSourceMethodEventArgs) _
    Handles ObjectDataSource1.Inserting

    e.InputParameters("CategoryID") = 1
    e.InputParameters("SupplierID") = 1
End Sub

이번에는 새 제품 (예: Acme)을 추가할 때 새 제품의 CategoryIDSupplierID 열이 1로 설정 됩니다 (그림 20 참조).This time when adding a new product (such as Acme Soda), the CategoryID and SupplierID columns of the new product are set to 1 (see Figure 20).

새 제품 이제 CategoryID 및 공급자 값을 1로 설정 합니다.New Products Now Have Their CategoryID and SupplierID Values Set to 1

그림 20: 이제 새 제품의 CategoryIDSupplierID 값이 1로 설정 (전체 크기 이미지를 보려면 클릭)Figure 20: New Products Now Have Their CategoryID and SupplierID Values Set to 1 (Click to view full-size image)

요약Summary

편집, 삽입 및 삭제 프로세스를 수행 하는 동안 데이터 웹 컨트롤과 ObjectDataSource는 다 수의 사전 및 사후 수준 이벤트를 처리 합니다.During the editing, inserting, and deleting process, both the data Web control and the ObjectDataSource proceed through a number of pre- and post-level events. 이 자습서에서는 사전 수준 이벤트를 검사 하 고 이러한 이벤트를 사용 하 여 입력 매개 변수를 사용자 지정 하거나 데이터 수정 작업을 데이터 웹 컨트롤과 ObjectDataSource의 이벤트 둘 다에서 취소 하는 방법을 살펴보았습니다.In this tutorial we examined the pre-level events and saw how to use these to customize the input parameters or cancel the data modification operation altogether both from the data Web control and ObjectDataSource's events. 다음 자습서에서는 사후 수준 이벤트에 대 한 이벤트 처리기를 만들고 사용 하는 방법을 살펴봅니다.In the next tutorial we'll look at creating and using event handlers for the post-level events.

행복 한 프로그래밍Happy Programming!

저자 정보About the Author

Scott Mitchell(7 개의 ASP/ASP. NET books 및 4GuysFromRolla.com창립자)은 1998부터 Microsoft 웹 기술을 사용 하 여 작업 했습니다.Scott Mitchell, author of seven ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Scott은 독립 컨설턴트, 강사 및 기록기로 작동 합니다.Scott works as an independent consultant, trainer, and writer. 최신 책은 24 시간 이내에 ASP.NET 2.0을 sams teach yourself것입니다.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. 이 자습서의 리드 검토자는 Jackie Goor 및 Liz Shulok 였습니다.Lead reviewers for this tutorial were Jackie Goor and Liz Shulok. 예정 된 MSDN 문서를 검토 하는 데 관심이 있나요?Interested in reviewing my upcoming MSDN articles? 그렇다면mitchell@4GuysFromRolla.com에서 줄을 삭제 합니다.If so, drop me a line at mitchell@4GuysFromRolla.com.