다음을 통해 공유


삽입, 업데이트 및 삭제와 연결된 이벤트 검사(C#)

스콧 미첼

PDF 다운로드

이 자습서에서는 ASP.NET 데이터 웹 컨트롤의 삽입, 업데이트 또는 삭제 작업 전, 도중 및 후에 발생하는 이벤트를 사용하여 살펴보겠습니다. 편집 인터페이스를 사용자 지정하여 제품 필드의 하위 집합만 업데이트하는 방법도 살펴보겠습니다.

소개

GridView, DetailsView 또는 FormView 컨트롤의 기본 제공 삽입, 편집 또는 삭제 기능을 사용하는 경우 최종 사용자가 새 레코드를 추가하거나 기존 레코드를 업데이트하거나 삭제하는 프로세스를 완료할 때 다양한 단계가 발생합니다. 이전 자습서에서 설명한 것처럼 GridView에서 행을 편집할 때 편집 단추가 업데이트 및 취소 단추로 바뀌고 BoundFields가 TextBoxes로 바뀝니다. 최종 사용자가 데이터를 업데이트하고 업데이트를 클릭하면 포스트백 시 다음 단계가 수행됩니다.

  1. GridView는 사용자가 입력한 값과 함께 편집된 레코드의 고유 식별 필드(속성을 통해DataKeyNames)로 ObjectDataSource UpdateParameters 를 채웁니다.
  2. GridView는 ObjectDataSource의 Update() 메서드를 호출합니다. 이 메서드는 기본 개체에서 적절한 메서드를 호출합니다(ProductsDAL.UpdateProduct이전 자습서에서는).
  3. 이제 업데이트된 변경 내용이 포함된 기본 데이터가 GridView로 다시 조정됩니다.

이 단계 시퀀스 중에는 여러 이벤트가 발생하므로 필요한 경우 사용자 지정 논리를 추가할 이벤트 처리기를 만들 수 있습니다. 예를 들어 1단계 이전에 GridView의 RowUpdating 이벤트가 발생합니다. 이 시점에서 유효성 검사 오류가 있는 경우 업데이트 요청을 취소할 수 있습니다. 메서드가 Update() 호출되면 ObjectDataSource의 Updating 이벤트가 발생하여 값을 추가하거나 사용자 지정할 UpdateParameters수 있습니다. ObjectDataSource의 기본 개체 메서드 실행이 완료되면 ObjectDataSource의 Updated 이벤트가 발생합니다. 이벤트에 대한 Updated 이벤트 처리기는 영향을 받은 행 수 및 예외가 발생했는지 여부와 같은 업데이트 작업에 대한 세부 정보를 검사할 수 있습니다. 마지막으로 2단계 후에 GridView의 RowUpdated 이벤트가 발생합니다. 이 이벤트에 대한 이벤트 처리기는 방금 수행된 업데이트 작업에 대한 추가 정보를 검사할 수 있습니다.

그림 1에서는 GridView를 업데이트할 때 이 일련의 이벤트 및 단계를 보여 줍니다. 그림 1의 이벤트 패턴은 GridView를 사용한 업데이트에 고유하지 않습니다. GridView, DetailsView 또는 FormView에서 데이터를 삽입, 업데이트 또는 삭제하면 데이터 웹 컨트롤과 ObjectDataSource 모두에 대해 동일한 시퀀스의 사전 및 사후 수준 이벤트가 발생합니다.

GridView에서 데이터를 업데이트할 때 발생하는 일련의 사전 및 사후 이벤트

그림 1: GridView에서 데이터를 업데이트할 때 발생하는 일련의 사전 및 사후 이벤트 발생(전체 크기 이미지를 보려면 클릭)

이 자습서에서는 이러한 이벤트를 사용하여 ASP.NET 데이터 웹 컨트롤의 기본 제공 삽입, 업데이트 및 삭제 기능을 확장하는 방법을 살펴봅니다. 편집 인터페이스를 사용자 지정하여 제품 필드의 하위 집합만 업데이트하는 방법도 살펴보겠습니다.

1단계: 제품ProductNameUnitPrice필드 업데이트

이전 자습서 의 편집 인터페이스에서 읽기 전용이 아닌 모든 제품 필드를 포함해야 했습니다. GridView에서 필드를 제거하려는 경우(예 QuantityPerUnit : 데이터를 업데이트할 때 데이터 웹 컨트롤이 ObjectDataSource의 QuantityPerUnit UpdateParameters 값을 설정하지 않음) 그런 다음 ObjectDataSource는 편집된 데이터베이스 레코드의 QuantityPerUnit 열을 값으로 UpdateProduct 변경하는 BLL(비즈니스 논리 계층) 메서드에 NULL 값을 전달 null 합니다. 마찬가지로 필요한 필드(예: ProductName편집 인터페이스에서 제거)가 제거되면 "열 'ProductName'에서 null을 허용하지 않음" 예외로 업데이트가 실패합니다. 이 동작의 이유는 ObjectDataSource가 각 제품 필드에 대한 입력 매개 변수를 예상하는 클래스의 UpdateProduct 메서드를 호출 ProductsBLL 하도록 구성되었기 때문입니다. 따라서 ObjectDataSource의 UpdateParameters 컬렉션에는 각 메서드의 입력 매개 변수에 대한 매개 변수가 포함되어 있습니다.

최종 사용자가 필드의 하위 집합만 업데이트할 수 있도록 하는 데이터 웹 컨트롤을 제공하려는 경우 ObjectDataSource의 Updating 이벤트 처리기에서 누락된 UpdateParameters 값을 프로그래밍 방식으로 설정하거나 필드의 하위 집합만 필요한 BLL 메서드를 만들고 호출해야 합니다. 이 후자의 방법을 살펴보겠습니다.

특히 편집 가능한 GridView에서 필드와 UnitPrice 필드만 ProductName 표시하는 페이지를 만들어 보겠습니다. 이 GridView의 편집 인터페이스는 사용자가 표시된 두 필드를 ProductName 업데이트하는 것만 허용합니다 UnitPrice. 이 편집 인터페이스는 제품 필드의 하위 집합만 제공하므로 기존 BLL의 UpdateProduct 메서드를 사용하고 누락된 제품 필드 값이 이벤트 처리기에서 Updating 프로그래밍 방식으로 설정된 ObjectDataSource를 만들어야 하거나 GridView에 정의된 필드의 하위 집합만 필요한 새 BLL 메서드를 만들어야 합니다. 이 자습서에서는 후자 옵션을 사용하고 세 개의 productNameunitPriceproductID입력 매개 변수만 사용하는 메서드의 UpdateProduct 오버로드를 만들어 보겠습니다.

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Update, false)]
public bool UpdateProduct(string productName, decimal? unitPrice, int productID)
{
    Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
    if (products.Count == 0)
        // no matching record found, return false
        return false;

    Northwind.ProductsRow product = products[0];

    product.ProductName = productName;
    if (unitPrice == null) product.SetUnitPriceNull();
      else product.UnitPrice = unitPrice.Value;

    // Update the product record
    int rowsAffected = Adapter.Update(product);

    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

원래 UpdateProduct 메서드와 마찬가지로 이 오버로드는 데이터베이스에 지정된 제품이 있는지 확인하여 시작합니다 ProductID. 그렇지 않은 경우 제품 정보 업데이트 요청이 실패했음을 나타내는 반환 false됩니다. 그렇지 않으면 기존 제품 레코드 ProductName 및 필드를 적절하게 업데이트하고 UnitPrice TableAdapter의 Update() 메서드를 호출하여 인스턴스를 ProductsRow 전달하여 업데이트를 커밋합니다.

이 클래스를 ProductsBLL 추가하면 간소화된 GridView 인터페이스를 만들 준비가 완료되었습니다. 폴더에서 DataModificationEvents.aspx EditInsertDelete 열고 페이지에 GridView를 추가합니다. 새 ObjectDataSource를 만들고 해당 메서드 매핑과 함께 클래스를 사용하도록 ProductsBLL 구성하고Update(), 해당 메서드가 , unitPriceproductID 입력 매개 변수만 productName사용하는 오버로드에 매핑 UpdateProduct 되도록 구성합니다.Select() GetProducts 그림 2는 ObjectDataSource의 메서드를 클래스의 Update()UpdateProduct 메서드 오버로드에 매핑할 ProductsBLL 때 데이터 원본 만들기 마법사를 보여줍니다.

ObjectDataSource의 Update() 메서드를 새 UpdateProduct 오버로드에 매핑

그림 2: ObjectDataSource의 Update() 메서드를 새 UpdateProduct 오버로드에 매핑(전체 크기 이미지를 보려면 클릭)

이 예제에서는 처음에는 데이터를 편집하는 기능만 필요하지만 레코드를 삽입하거나 삭제할 수는 없으므로 잠시 시간을 내어 Insert 및 DELETE 탭으로 이동하여 드롭다운 목록에서 (없음)을 선택하여 ObjectDataSource Insert()Delete() 메서드를 클래스의 메서드에 매핑 ProductsBLL 해서는 안 됨을 명시적으로 나타냅니다.

INSERT 및 DELETE 탭의 드롭다운 목록에서 선택(없음)

그림 3: INSERT 및 DELETE 탭의 드롭다운 목록에서 선택(없음)(전체 크기 이미지를 보려면 클릭)

이 마법사를 완료한 후 GridView의 스마트 태그에서 편집 사용 확인란을 선택합니다.

데이터 원본 만들기 마법사가 완료되고 GridView에 바인딩이 완료되면 Visual Studio에서 두 컨트롤에 대한 선언적 구문을 만들었습니다. 원본 보기로 이동하여 아래 표시된 ObjectDataSource의 선언적 태그를 검사합니다.

<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() 메서드에 대한 매핑이 없으므로 섹션이나 DeleteParameters 섹션이 없습니다InsertParameters. 또한 메서드는 Update() 세 개의 입력 매개 변수 UpdateParameters 만 허용하는 메서드 오버로드에 매핑 UpdateProduct 되므로 섹션에는 세 Parameter 개의 인스턴스만 있습니다.

ObjectDataSource의 OldValuesParameterFormatString 속성은 .로 original_{0}설정됩니다. 이 속성은 데이터 원본 구성 마법사를 사용할 때 Visual Studio에서 자동으로 설정됩니다. 그러나 BLL 메서드는 원래 ProductID 값이 전달될 것으로 예상하지 않으므로 ObjectDataSource의 선언적 구문에서 이 속성 할당을 모두 제거합니다.

참고 항목

디자인 뷰의 OldValuesParameterFormatString 속성 창 속성 값을 지우면 선언적 구문에 속성이 계속 존재하지만 빈 문자열로 설정됩니다. 선언적 구문에서 속성을 모두 제거하거나 속성 창 값을 기본값{0}으로 설정합니다.

ObjectDataSource는 제품의 이름, 가격 및 ID에 대해서만 있지만 UpdateParameters Visual Studio는 각 제품의 필드에 대해 GridView에 BoundField 또는 CheckBoxField를 추가했습니다.

GridView에는 각 제품의 필드에 대한 BoundField 또는 CheckBoxField가 포함되어 있습니다.

그림 4: GridView에 각 제품의 필드에 대한 BoundField 또는 CheckBoxField가 포함되어 있습니다(전체 크기 이미지를 보려면 클릭).

최종 사용자가 제품을 편집하고 업데이트 단추를 클릭하면 GridView는 읽기 전용이 아닌 필드를 열거합니다. 그런 다음 ObjectDataSource UpdateParameters 컬렉션의 해당 매개 변수 값을 사용자가 입력한 값으로 설정합니다. 해당 매개 변수가 없으면 GridView가 컬렉션에 매개 변수를 추가합니다. 따라서 GridView에 제품의 모든 필드에 대한 BoundFields 및 CheckBoxFields가 포함된 경우 ObjectDataSource의 선언적 태그가 세 개의 입력 매개 변수만 지정한다는 사실에도 불구하고 ObjectDataSource는 이러한 모든 매개 변수를 사용하는 오버로드를 호출 UpdateProduct 하게 됩니다(그림 5 참조). 마찬가지로 GridView에 오버로드에 대한 UpdateProduct 입력 매개 변수에 해당하지 않는 읽기 전용이 아닌 제품 필드의 일부 조합이 있는 경우 업데이트를 시도할 때 예외가 발생합니다.

GridView는 ObjectDataSource의 UpdateParameters 컬렉션에 매개 변수를 추가합니다.

그림 5: GridView에서 ObjectDataSource 컬렉션 UpdateParameters 에 매개 변수를 추가합니다(전체 크기 이미지를 보려면 클릭).

ObjectDataSource가 제품의 이름, 가격 및 ID만 사용하는 오버로드를 호출 UpdateProduct 하도록 하려면 GridView를 편집 가능한 필드 ProductName 로 제한해야 합니다 UnitPrice. 다른 BoundFields 및 CheckBoxFields를 제거하거나, 다른 필드의 ReadOnly 속성을 true또는 둘의 일부 조합으로 설정하여 이 작업을 수행할 수 있습니다. 이 자습서에서는 GridView의 선언적 태그가 다음과 같이 표시되는 BoundFields 및 UnitPrice BoundFields를 제외한 ProductName 모든 GridView 필드를 제거해 보겠습니다.

<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만 있습니다. productID 입력 매개 변수가 기본 키 값이고 편집된 행에 DataKeyNames 대한 속성 값을 통해 전달되기 때문입니다.

GridView를 사용하면 오버로드와 UpdateProduct 함께 사용자가 다른 제품 필드를 잃지 않고 제품의 이름과 가격만 편집할 수 있습니다.

인터페이스를 사용하면 제품의 이름과 가격만 편집할 수 있습니다.

그림 6: 인터페이스를 사용하면 제품의 이름과 가격만 편집할 수 있습니다(전체 크기 이미지를 보려면 클릭).

참고 항목

이전 자습서에서 설명한 것처럼 GridView의 뷰 상태를 사용하도록 설정하는 것이 매우 중요합니다(기본 동작). GridView의 EnableViewState 속성을 false설정하면 동시에 사용자가 의도치 않게 레코드를 삭제하거나 편집할 위험이 있습니다.

서식 개선UnitPrice

그림 6에 표시된 GridView 예제는 작동 UnitPrice 하지만 필드의 형식이 전혀 지정되지 않아 통화 기호가 부족하고 소수 자릿수가 4개인 가격 표시가 발생합니다. 편집할 수 없는 행에 통화 서식을 적용하려면 BoundField의 DataFormatString 속성을 해당 속성 {0:c} 으로 HtmlEncode 설정 UnitPrice 하기만 하면 됩니다false.

적절하게 UnitPrice의 DataFormatString 및 HtmlEncode 속성 설정

그림 7: 's DataFormatStringHtmlEncode 속성 적절하게 설정UnitPrice(전체 크기 이미지를 보려면 클릭)

이 변경으로 편집할 수 없는 행은 가격을 통화 형식으로 지정합니다. 그러나 편집된 행은 여전히 통화 기호가 없고 소수 자릿수가 4개인 값을 표시합니다.

편집할 수 없는 행이 이제 통화 값으로 서식 지정됨

그림 8: 편집할 수 없는 행이 이제 통화 값으로 서식 지정됨(전체 크기 이미지를 보려면 클릭)

속성에 DataFormatString 지정된 서식 지정 지침은 BoundField의 ApplyFormatInEditMode 속성을 (기본값: false)로 설정하여 편집 인터페이스에 적용할 true 수 있습니다. 잠시 시간을 내어 이 속성을 true.로 설정합니다.

UnitPrice BoundField의 ApplyFormatInEditMode 속성을 true로 설정합니다.

그림 9: BoundField의 ApplyFormatInEditMode 속성을 설정UnitPrice(true전체 크기 이미지를 보려면 클릭)

이렇게 변경하면 편집된 행에 표시되는 값 UnitPrice 도 통화 형식으로 지정됩니다.

통화로 서식이 지정된 편집된 행의 UnitPrice 값을 보여 주는 GridView의 스크린샷

그림 10: 편집된 행의 UnitPrice 값이 통화로 서식 지정됨(전체 크기 이미지를 보려면 클릭)

그러나 텍스트 상자에 통화 기호가 있는 제품을 업데이트하면 $19.00가 throw됩니다 FormatException. GridView에서 사용자가 제공한 값을 ObjectDataSource 컬렉션 UpdateParameters 에 할당하려고 하면 문자열 "$19.00"을 매개 변수에 필요한 값으로 decimal 변환 UnitPrice 할 수 없습니다(그림 11 참조). 이를 해결하기 위해 GridView 이벤트에 RowUpdating 대한 이벤트 처리기를 만들고 사용자가 제공한 UnitPrice 통화 형식 decimal으로 구문 분석하도록 할 수 있습니다.

GridView의 RowUpdating 이벤트는 두 번째 매개 변수로 GridViewUpdateEventArgs 형식의 개체를 허용합니다. 여기에는 ObjectDataSource UpdateParameters 컬렉션에 할당할 준비가 된 사용자 제공 값을 보유하는 속성 중 하나로 사전이 포함 NewValues 됩니다. 이벤트 처리기에서 NewValues 다음 코드 RowUpdating 줄과 통화 형식을 사용하여 구문 분석된 10진수 값으로 컬렉션의 기존 UnitPrice 값을 덮어쓸 수 있습니다.

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
  if (e.NewValues["UnitPrice"] != null)
    e.NewValues["UnitPrice"] =
        decimal.Parse(e.NewValues["UnitPrice"].ToString(),
            System.Globalization.NumberStyles.Currency);
}

사용자가 값(예: "$19.00")을 제공한 UnitPrice 경우 이 값은 Decimal.Parse에서 계산한 10진수 값으로 덮어쓰여 값을 통화로 구문 분석합니다. 이렇게 하면 통화 기호, 쉼표, 소수점 등의 경우 소수점이 올바르게 구문 분석되고 System.Globalization 네임스페이스에서 NumberStyles 열거형 이 사용됩니다.

그림 11은 사용자가 제공한 UnitPrice통화 기호로 인한 문제와 GridView의 RowUpdating 이벤트 처리기를 사용하여 이러한 입력을 올바르게 구문 분석하는 방법을 보여 줍니다.

ObjectDataSource가 UnitPrice 필드를 처리하는 방법과 GridView의 RowUpdate 이벤트 처리기가 문자열을 10진수로 변환하는 방법을 보여 주는 다이어그램

그림 11: 편집된 행의 UnitPrice 값이 통화로 서식 지정됨(전체 크기 이미지를 보려면 클릭)

2단계: 금지NULL UnitPrices

데이터베이스가 테이블 열의 값을 허용 NULL 하도록 구성되어 있는 동안 이 특정 페이지를 방문하는 사용자가 값을 지정 UnitPrice NULL 하지 못하도록 할 수 Products 있습니다.UnitPrice 즉, 사용자가 제품 행을 편집할 때 결과를 데이터베이스에 저장하지 않고 값을 입력 UnitPrice 하지 못하는 경우 이 페이지를 통해 편집된 제품에는 가격이 지정되어 있어야 한다는 메시지를 표시하려고 합니다.

GridViewUpdateEventArgs GridView의 RowUpdating 이벤트 처리기에 전달된 개체에는 업데이트 프로세스를 종료하는 true속성이 포함되어 Cancel 있습니다. 이벤트 처리기를 확장 RowUpdating 하여 설정 e.Cancel 하여 true 컬렉션null의 값 NewValues 이 있는 이유를 UnitPrice 설명하는 메시지를 표시해 보겠습니다.

먼저 레이블 웹 컨트롤을 이름이 지정된 MustProvideUnitPriceMessage페이지에 추가합니다. 사용자가 제품을 업데이트할 때 값을 지정 UnitPrice 하지 못하면 이 레이블 컨트롤이 표시됩니다. 레이블의 Text 속성을 "제품에 대한 가격을 제공해야 합니다."로 설정합니다. 또한 다음 정의를 사용하여 명명 WarningStyles.css 새 CSS 클래스를 만들었습니다.

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

마지막으로 Label의 CssClass 속성을 Warning.로 설정합니다. 이때 디자이너는 그림 12와 같이 GridView 위에 빨간색, 굵게, 기울이며 매우 큰 글꼴 크기로 경고 메시지를 표시해야 합니다.

GridView 위에 레이블이 추가되었습니다.

그림 12: GridView 위에 레이블이 추가되었습니다(전체 크기 이미지를 보려면 클릭).

기본적으로 이 레이블은 숨겨야 하므로 이벤트 처리기에서 Page_Load 해당 Visible 속성을 false 설정합니다.

protected void Page_Load(object sender, EventArgs e)
{
    MustProvideUnitPriceMessage.Visible = false;
}

사용자가 제품을 지정 UnitPrice하지 않고 업데이트하려고 하면 업데이트를 취소하고 경고 레이블을 표시하려고 합니다. 다음과 같이 GridView의 RowUpdating 이벤트 처리기를 보강합니다.

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    if (e.NewValues["UnitPrice"] != null)
    {
        e.NewValues["UnitPrice"] =
            decimal.Parse(e.NewValues["UnitPrice"].ToString(),
                System.Globalization.NumberStyles.Currency);
    }
    else
    {
        // Show the Label
        MustProvideUnitPriceMessage.Visible = true;

        // Cancel the update
        e.Cancel = true;
    }
}

사용자가 가격을 지정하지 않고 제품을 저장하려고 하면 업데이트가 취소되고 유용한 메시지가 표시됩니다. 데이터베이스(및 비즈니스 논리)는 허용하지만 이 특정 ASP.NET 페이지는 허용하지 NULL UnitPrice 않습니다.

사용자는 UnitPrice를 비워 둘 수 없습니다.

그림 13: 사용자가 비워 둘 UnitPrice 수 없음(전체 크기 이미지를 보려면 클릭)

지금까지 GridView의 이벤트를 사용하여 ObjectDataSource UpdateParameters 컬렉션 RowUpdating 에 할당된 매개 변수 값을 프로그래밍 방식으로 변경하는 방법과 업데이트 프로세스를 완전히 취소하는 방법을 알아보았습니다. 이러한 개념은 DetailsView 및 FormView 컨트롤로 이월되며 삽입 및 삭제에도 적용됩니다.

이러한 작업은 ObjectDataSource 수준에서 해당 InsertingUpdatingDeleting 이벤트에 대한 이벤트 처리기를 통해 수행할 수도 있습니다. 이러한 이벤트는 기본 개체의 연결된 메서드가 호출되기 전에 발생하며 입력 매개 변수 컬렉션을 수정하거나 작업을 완전히 취소할 수 있는 마지막 기회를 제공합니다. 이러한 세 이벤트에 대한 이벤트 처리기는 관심 있는 두 가지 속성이 있는 ObjectDataSourceMethodEventArgs 형식의 개체를 전달합니다.

ObjectDataSource 수준에서 매개 변수 값을 사용하는 방법을 설명하기 위해 사용자가 새 제품을 추가할 수 있는 DetailsView를 페이지에 포함해 보겠습니다. 이 DetailsView는 데이터베이스에 새 제품을 빠르게 추가하기 위한 인터페이스를 제공하는 데 사용됩니다. 새 제품을 추가할 때 일관된 사용자 인터페이스를 유지하기 위해 사용자가 해당 필드 UnitPrice 의 값 ProductName 만 입력하도록 허용해 보겠습니다. 기본적으로 DetailsView의 삽입 인터페이스에 제공되지 않는 값은 데이터베이스 값으로 NULL 설정됩니다. 그러나 ObjectDataSource의 Inserting 이벤트를 사용하여 곧 볼 수 있듯이 다른 기본값을 삽입할 수 있습니다.

3단계: 새 제품을 추가하기 위한 인터페이스 제공

Toolbox에서 GridView 위의 디자이너로 DetailsView를 끌어서 해당 Height 속성과 속성을 지우고 Width 페이지에 이미 있는 ObjectDataSource에 바인딩합니다. 그러면 각 제품의 필드에 대한 BoundField 또는 CheckBoxField가 추가됩니다. 이 DetailsView를 사용하여 새 제품을 추가하려고 하므로 스마트 태그에서 삽입 사용 옵션을 확인해야 합니다. 그러나 ObjectDataSource의 메서드가 클래스의 Insert() 메서드에 ProductsBLL 매핑되지 않았기 때문에 이러한 옵션은 없습니다(데이터 원본을 구성할 때 이 매핑을 (없음)으로 설정했음을 기억하세요 그림 3 참조).

ObjectDataSource를 구성하려면 스마트 태그에서 데이터 원본 구성 링크를 선택하고 마법사를 시작합니다. 첫 번째 화면에서는 ObjectDataSource가 바인딩된 기본 개체를 변경할 수 있습니다. 로 설정된 상태로 둡 ProductsBLL니다. 다음 화면에는 ObjectDataSource의 메서드에서 기본 개체로의 매핑이 나열됩니다. 메서드와 Delete() 메서드를 메서드에 Insert() 매핑해서는 안 됨을 명시적으로 표시했지만 INSERT 및 DELETE 탭으로 이동하면 매핑이 있음을 알 수 있습니다. ProductsBLL이는 's AddProductDeleteProduct 메서드가 특성을 사용하여 DataObjectMethodAttribute 각각에 대한 Insert() 기본 메서드임을 나타내기 Delete()때문입니다. 따라서 다른 값이 명시적으로 지정되지 않은 한 ObjectDataSource 마법사는 마법사를 실행할 때마다 이러한 값을 선택합니다.

메서드를 Insert() 가리키는 메서드를 AddProduct 그대로 두고 DELETE 탭의 드롭다운 목록을 다시 (없음)으로 설정합니다.

INSERT 탭의 드롭다운 목록을 AddProduct 메서드로 설정

그림 14: INSERT 탭의 드롭다운 목록을 메서드로 AddProduct 설정(전체 크기 이미지를 보려면 클릭)

DELETE 탭의 드롭다운 목록을 (없음)으로 설정

그림 15: DELETE 탭의 드롭다운 목록을 (없음)으로 설정(전체 크기 이미지를 보려면 클릭)

이러한 변경을 수행한 후 아래와 같이 ObjectDataSource의 선언적 구문이 컬렉션을 포함 InsertParameters 하도록 확장됩니다.

<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 . 이 속성을 기본값({0})으로 설정하거나 선언적 구문에서 완전히 제거하여 이 속성을 지웁니다.

ObjectDataSource에서 삽입 기능을 제공하면 DetailsView의 스마트 태그에 삽입 사용 확인란이 포함됩니다. 디자이너로 돌아가서 이 옵션을 선택합니다. 다음으로, DetailsView를 구문 분석하여 BoundField와 ProductName UnitPrice CommandField가 두 개만 있도록 합니다. 이 시점에서 DetailsView의 선언적 구문은 다음과 같습니다.

<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은 이 시점에서 브라우저를 통해 볼 때 이 페이지를 보여 줍니다. 볼 수 있듯이 DetailsView는 첫 번째 제품(차이)의 이름과 가격을 나열합니다. 그러나 원하는 것은 사용자가 데이터베이스에 새 제품을 빠르게 추가할 수 있는 수단을 제공하는 삽입 인터페이스입니다.

DetailsView가 현재 읽기 전용 모드로 렌더링됨

그림 16: DetailsView가 현재 읽기 전용 모드로 렌더링됨(전체 크기 이미지를 보려면 클릭)

삽입 모드에서 DetailsView를 표시하려면 속성을 Inserting.로 설정 DefaultMode 해야 합니다. 이렇게 하면 처음 방문했을 때 DetailsView가 삽입 모드로 렌더링되고 새 레코드를 삽입한 후 해당 위치에 유지됩니다. 그림 17에서 알 수 있듯이 이러한 DetailsView는 새 레코드를 추가하기 위한 빠른 인터페이스를 제공합니다.

DetailsView는 새 제품을 빠르게 추가하기 위한 인터페이스를 제공합니다.

그림 17: DetailsView는 새 제품을 빠르게 추가하기 위한 인터페이스를 제공합니다(전체 크기 이미지를 보려면 클릭).

사용자가 제품 이름과 가격(예: 그림 17과 같이 "Acme Water" 및 1.99)을 입력하고 삽입을 클릭하면 포스트백이 계속되고 삽입 워크플로가 시작되어 데이터베이스에 새 제품 레코드가 추가됩니다. DetailsView는 삽입 인터페이스를 유지 관리하며 GridView는 그림 18과 같이 새 제품을 포함하기 위해 자동으로 데이터 원본으로 다시 설정됩니다.

제품

그림 18: 제품 "Acme Water"가 데이터베이스에 추가되었습니다.

그림 18의 GridView는 표시되지 않지만 DetailsView 인터페이스CategoryIDSupplierIDQuantityPerUnit, 등에서 부족한 제품 필드는 데이터베이스 값이 할당됩니다.NULL 다음 단계를 수행하여 이를 확인할 수 있습니다.

  1. Visual Studio에서 서버 탐색기로 이동
  2. NORTHWND.MDF 데이터베이스 노드 확장
  3. 데이터베이스 테이블 노드를 마우스 오른쪽 단추로 Products 클릭합니다.
  4. 테이블 데이터 표시 선택

그러면 테이블의 모든 레코드가 Products 나열됩니다. 그림 19에서 알 수 있듯이, 새로운 제품의 모든 열은 이외의 ProductID값이 있습니다 NULL UnitPrice. ProductName

DetailsView에 제공되지 않는 제품 필드에 NULL 값이 할당됨

그림 19: DetailsView에 제공되지 않는 제품 필드가 할당된 NULL 값입니다(전체 크기 이미지를 보려면 클릭).

최상의 기본 옵션이 NULL 아니거나 데이터베이스 열 자체가 허용하지 NULL 않기 때문에 NULL 이러한 열 값 중 하나 이상이 아닌 기본값을 제공할 수 있습니다. 이를 위해 DetailsView InputParameters 컬렉션의 매개 변수 값을 프로그래밍 방식으로 설정할 수 있습니다. 이 할당은 DetailsView ItemInserting 의 이벤트 또는 ObjectDataSource Inserting 이벤트에 대한 이벤트 처리기에서 수행할 수 있습니다. 데이터 웹 제어 수준에서 사전 및 사후 수준 이벤트를 사용하는 것을 이미 살펴보았으므로 이번에는 ObjectDataSource의 이벤트를 사용하여 살펴보겠습니다.

4단계: 값 및SupplierID매개 변수에CategoryID값 할당

이 자습서에서는 이 인터페이스를 통해 새 제품을 추가할 때 애플리케이션에 1 값이 SupplierID 할당 CategoryID 되어야 한다고 생각해 보겠습니다. 앞에서 설명한 것처럼 ObjectDataSource에는 데이터 수정 프로세스 중에 발생하는 사전 및 사후 수준 이벤트 쌍이 있습니다. 메서드 Insert() 가 호출되면 ObjectDataSource는 먼저 해당 이벤트를 발생 Inserting 시킨 다음 메서드가 Insert() 매핑된 메서드를 호출하고 마지막으로 이벤트를 발생합니다 Inserted . Inserting 이벤트 처리기는 입력 매개 변수를 조정하거나 작업을 완전히 취소할 수 있는 마지막 기회를 제공합니다.

참고 항목

실제 애플리케이션에서는 사용자가 범주 및 공급업체를 지정하도록 하거나 일부 기준 또는 비즈니스 논리에 따라 이 값을 선택할 수 있습니다(ID 1을 맹목적으로 선택하는 대신). 그럼에도 불구하고 이 예제에서는 ObjectDataSource의 사전 수준 이벤트에서 입력 매개 변수의 값을 프로그래밍 방식으로 설정하는 방법을 보여 줍니다.

잠시 시간을 내어 ObjectDataSource 이벤트에 Inserting 대한 이벤트 처리기를 만듭니다. 이벤트 처리기의 두 번째 입력 매개 변수는 매개 변수 컬렉션()에 액세스할 속성과 작업을 취소하는 속성(InputParametersCancel)이 있는 형식ObjectDataSourceMethodEventArgs의 개체입니다.

protected void ObjectDataSource1_Inserting
    (object sender, ObjectDataSourceMethodEventArgs e)
{

}

이때 속성에는 InputParameters DetailsView에서 할당된 값이 있는 ObjectDataSource 컬렉션 InsertParameters 이 포함됩니다. 이러한 매개 변수 중 하나의 값을 변경하려면 다음을 사용합니다 e.InputParameters["paramName"] = value. 따라서 값 1을 CategoryID SupplierID 설정하려면 이벤트 처리기를 다음과 같이 조정 Inserting 합니다.

protected void ObjectDataSource1_Inserting
    (object sender, ObjectDataSourceMethodEventArgs e)
{
    e.InputParameters["CategoryID"] = 1;
    e.InputParameters["SupplierID"] = 1;
}

이번에는 새 제품(예: Acme Soda) CategoryID 을 추가할 때 새 제품의 열과 SupplierID 열이 1로 설정됩니다(그림 20 참조).

이제 새 제품에 해당 CategoryID 및 SupplierID 값이 1로 설정됩니다.

그림 20: 이제 CategoryID 새 제품에 해당 제품 및 SupplierID 값이 1로 설정됨(전체 크기 이미지를 보려면 클릭)

요약

편집, 삽입 및 삭제 프로세스 중에 데이터 웹 컨트롤과 ObjectDataSource는 모두 여러 사전 및 사후 수준 이벤트를 진행합니다. 이 자습서에서는 사전 수준 이벤트를 검사하고 이를 사용하여 입력 매개 변수를 사용자 지정하거나 데이터 웹 컨트롤과 ObjectDataSource의 이벤트에서 데이터 수정 작업을 모두 취소하는 방법을 알아보았습니다. 다음 자습서에서는 사후 수준 이벤트에 대한 이벤트 처리기를 만들고 사용하는 방법에 대해 살펴보겠습니다.

행복한 프로그래밍!

작성자 정보

7개의 ASP/ASP.NET 책의 저자이자 4GuysFromRolla.com 창립자인 Scott Mitchell은 1998년부터 Microsoft 웹 기술을 연구해 왔습니다. Scott은 독립 컨설턴트, 트레이너 및 작가로 일합니다. 그의 최신 책은 샘스 티치 자신 ASP.NET 24 시간에 2.0입니다. 그는 에서 mitchell@4GuysFromRolla.com찾을 http://ScottOnWriting.NET수있는 자신의 블로그를 통해 도달 할 수 있습니다 .

특별 감사

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 재키 구어와 리즈 슐록이었습니다. 예정된 MSDN 문서를 검토하는 데 관심이 있으신가요? 그렇다면 선을 놓습니다 mitchell@4GuysFromRolla.com.