추가 사용자 정보 저장(C#)

작성자 : Scott Mitchell

참고

이 문서가 작성된 이후 ASP.NET 멤버 자격 공급자는 ASP.NET ID로 대체되었습니다. 이 문서를 작성할 때 추천한 멤버 자격 공급자가 아닌 ASP.NET ID 플랫폼을 사용하도록 앱을 업데이트하는 것이 좋습니다. ASP.NET ID는 를 포함하여 ASP.NET 멤버 자격 시스템에 비해 여러 가지 이점이 있습니다.

  • 성능 향상
  • 향상된 확장성 및 테스트 가능성
  • OAuth, OpenID Connect 및 2단계 인증 지원
  • 클레임 기반 ID 지원
  • ASP.Net Core와의 상호 운용성 향상

코드 다운로드 또는 PDF 다운로드

이 자습서에서는 매우 기본적인 게스트북 애플리케이션을 빌드하여 이 질문에 답합니다. 이렇게 하면 데이터베이스에서 사용자 정보를 모델링하기 위한 다양한 옵션을 살펴본 다음 멤버 자격 프레임워크에서 만든 사용자 계정과 이 데이터를 연결하는 방법을 알아봅니다.

소개

Asp. NET의 멤버 자격 프레임워크는 사용자를 관리하기 위한 유연한 인터페이스를 제공합니다. 멤버 자격 API에는 자격 증명의 유효성을 검사하고, 현재 로그온한 사용자에 대한 정보를 검색하고, 새 사용자 계정을 만들고, 사용자 계정을 삭제하는 메서드가 포함됩니다. 멤버 자격 프레임워크의 각 사용자 계정에는 자격 증명의 유효성을 검사하고 필수 사용자 계정 관련 작업을 수행하는 데 필요한 속성만 포함됩니다. 이는 멤버 자격 프레임워크에서 사용자 계정을 모델링하는 클래스의 MembershipUser메서드 및 속성에 의해 입증됩니다. 이 클래스에는 , 및 와 같은 UserName속성과 IsLockedOutUnlockUser와 같은 GetPassword 메서드가 Email있습니다.

종종 애플리케이션은 멤버 자격 프레임워크에 포함되지 않은 추가 사용자 정보를 저장해야 합니다. 예를 들어 온라인 소매점은 각 사용자가 배송 및 청구 주소, 결제 정보, 배달 기본 설정 및 연락처 전화 번호를 저장하도록 해야 할 수 있습니다. 또한 시스템의 각 주문은 특정 사용자 계정과 연결됩니다.

클래스에는 MembershipUser 또는 DeliveryPreferencesPastOrders와 같은 PhoneNumber 속성이 포함되지 않습니다. 그렇다면 애플리케이션에 필요한 사용자 정보를 추적하고 멤버 자격 프레임워크와 통합하려면 어떻게 해야 할까요? 이 자습서에서는 매우 기본적인 게스트북 애플리케이션을 빌드하여 이 질문에 답합니다. 이렇게 하면 데이터베이스에서 사용자 정보를 모델링하기 위한 다양한 옵션을 살펴본 다음 멤버 자격 프레임워크에서 만든 사용자 계정과 이 데이터를 연결하는 방법을 알아봅니다. 그럼 시작하겠습니다.

1단계: 게스트북 애플리케이션의 데이터 모델 만들기

데이터베이스에서 사용자 정보를 캡처하고 멤버 자격 프레임워크에서 만든 사용자 계정과 연결하는 데 사용할 수 있는 다양한 기술이 있습니다. 이러한 기술을 설명하기 위해 일종의 사용자 관련 데이터를 캡처하도록 자습서 웹 애플리케이션을 보강해야 합니다. (현재 애플리케이션의 데이터 모델에는 에 필요한 애플리케이션 서비스 테이블만 포함됩니다 SqlMembershipProvider.)

인증된 사용자가 주석을 남길 수 있는 매우 간단한 게스트북 애플리케이션을 만들어 보겠습니다. 게스트북 주석을 저장하는 것 외에도 각 사용자가 자신의 고향, 홈페이지 및 서명을 저장할 수 있도록 허용해 보겠습니다. 제공된 경우 사용자의 홈타운, 홈페이지 및 서명이 게스트북에 남긴 각 메시지에 표시됩니다.

GuestbookComments테이블 추가

게스트 북 주석을 캡처하려면 , , SubjectBodyCommentDate과 같은 CommentId열이 있는 라는 GuestbookComments 데이터베이스 테이블을 만들어야 합니다. 또한 테이블의 각 레코드가 주석을 GuestbookComments 남긴 사용자를 참조하도록 해야 합니다.

이 테이블을 데이터베이스에 추가하려면 Visual Studio의 데이터베이스 Explorer 이동하여 데이터베이스로 드릴다운합니다SecurityTutorials. Tables 폴더를 마우스 오른쪽 단추로 클릭하고 새 테이블 추가를 선택합니다. 그러면 새 테이블의 열을 정의할 수 있는 인터페이스가 표시됩니다.

SecurityTutorials 데이터베이스에 새 테이블 추가

그림 1: 데이터베이스에 SecurityTutorials 새 테이블 추가(전체 크기 이미지를 보려면 클릭)

다음으로, 의 열을 정의 GuestbookComments합니다. 먼저 라는 CommentId 형식 uniqueidentifier의 열을 추가합니다. 이 열은 게스트북의 각 주석을 고유하게 식별하므로 을 허용하지 NULL 않으며 테이블의 기본 키로 표시합니다. 각 INSERT의 필드에 대한 CommentId 값을 제공하는 대신 열의 기본값을 로 설정하여 이 필드에 INSERT 대해 새 uniqueidentifier 값을 NEWID()자동으로 생성해야 함을 나타낼 수 있습니다. 이 첫 번째 필드를 추가하고 기본 키로 표시하고 기본값을 설정하면 화면이 그림 2에 표시된 스크린샷과 유사하게 표시됩니다.

CommentId라는 기본 열 추가

그림 2: 라는 CommentId 기본 열 추가(전체 크기 이미지를 보려면 클릭)

다음으로 형식의 열 Subject 과 라는 열을 추가합니다. 두 열 nvarchar(MAX)Body 모두에 을 허용하지 NULLnvarchar(50) 않습니다. 그런 다음 형식의 라는 CommentDate 열을 추가합니다 datetime. 을 허용하지 NULL 않으며 열의 기본값을 CommentDategetdate()설정합니다.

남은 것은 사용자 계정을 각 게스트 북 주석과 연결하는 열을 추가하는 것입니다. 한 가지 옵션은 형식nvarchar(256)의 라는 UserName 열을 추가하는 것입니다. 이 옵션은 이외의 멤버 자격 공급자를 사용할 때 적합합니다 SqlMembershipProvider. 그러나 이 자습서 시리즈에서와 같이 를 사용하는 SqlMembershipProvider경우 테이블의 UserNameaspnet_Users 열이 고유하도록 보장되지는 않습니다. aspnet_Users 테이블의 기본 키는 이며 UserId 형식uniqueidentifier입니다. 따라서 GuestbookComments 테이블에 형식(값 허용 안 됨)이라는 UserIduniqueidentifier 열이 NULL 필요합니다. 계속 진행하여 이 열을 추가합니다.

참고

SQL Server 멤버 자격 스키마 만들기 자습서에서 설명한 것처럼 Membership 프레임워크는 서로 다른 사용자 계정을 가진 여러 웹 애플리케이션이 동일한 사용자 저장소를 공유할 수 있도록 설계되었습니다. 사용자 계정을 다른 애플리케이션으로 분할하여 이 작업을 수행합니다. 또한 각 사용자 이름은 애플리케이션 내에서 고유하도록 보장되지만 동일한 사용자 저장소를 사용하는 다른 애플리케이션에서 동일한 사용자 이름을 사용할 수 있습니다. 및 ApplicationId 필드의 aspnet_Users 테이블에 UserName 는 복합 UNIQUE 제약 조건이 있지만 필드에는 복합 제약 조건이 UserName 없습니다. 따라서 aspnet_Users 테이블에 동일한 UserName 값을 가진 두 개 이상의 레코드가 있을 수 있습니다. 그러나 UNIQUE 테이블 UserId 의 필드에는 기본 키이므로 제약 aspnet_Users 조건이 있습니다. UNIQUE 제약 조건이 없으면 및 aspnet_Users 테이블 간에 GuestbookComments 외래 키 제약 조건을 설정할 수 없으므로 제약 조건이 중요합니다.

열을 추가한 UserId 후 도구 모음에서 저장 아이콘을 클릭하여 테이블을 저장합니다. 새 테이블의 이름을 로 지정합니다 GuestbookComments.

테이블에 참석 GuestbookComments 해야 하는 마지막 문제가 하나 있습니다. 열과 aspnet_Users.UserId 열 사이에 GuestbookComments.UserId외래 키 제약 조건을 만들어야 합니다. 이렇게 하려면 도구 모음에서 관계 아이콘을 클릭하여 외래 키 관계 대화 상자를 시작합니다. 또는 테이블 Designer 메뉴로 이동하고 관계를 선택하여 이 대화 상자를 시작할 수 있습니다.

외래 키 관계 대화 상자의 왼쪽 아래 모서리에 있는 추가 단추를 클릭합니다. 그러면 관계에 참여하는 테이블을 정의해야 하지만 새 외래 키 제약 조건이 추가됩니다.

외래 키 관계 대화 상자를 사용하여 테이블의 외래 키 제약 조건 관리

그림 3: 외래 키 관계 대화 상자를 사용하여 테이블의 외래 키 제약 조건 관리(전체 크기 이미지를 보려면 클릭)

그런 다음 오른쪽의 "테이블 및 열 사양" 행에서 줄임표 아이콘을 클릭합니다. 그러면 테이블 및 열 대화 상자가 시작됩니다. 이 대화 상자에서 기본 키 테이블 및 열과 테이블의 외래 키 열을 GuestbookComments 지정할 수 있습니다. 특히 및 를 기본 키 테이블 및 열 UserIdGuestbookComments 로 선택하고 테이블에서 외래 키 열로 선택합니다 aspnet_UsersUserId(그림 4 참조). 기본 및 외래 키 테이블과 열을 정의한 후 확인을 클릭하여 외래 키 관계 대화 상자로 돌아갑니다.

aspnet_Users 및 GuesbookComments 테이블 간에 외래 키 제약 조건 설정

그림 4: 및 GuesbookComments 테이블 간에 aspnet_Users 외래 키 제약 조건 설정(전체 크기 이미지를 보려면 클릭)

이 시점에서 외래 키 제약 조건이 설정되었습니다. 이 제약 조건이 있으면 존재하지 않는 사용자 계정을 참조하는 게스트 북 항목이 없을 것을 보장하여 두 테이블 간의 관계형 무결성 을 보장합니다. 기본적으로 외래 키 제약 조건은 해당 자식 레코드가 있는 경우 부모 레코드를 삭제할 수 없습니다. 즉, 사용자가 하나 이상의 게스트 북 주석을 만든 다음 해당 사용자 계정을 삭제하려고 하면 게스트 북 주석이 먼저 삭제되지 않는 한 삭제가 실패합니다.

부모 레코드가 삭제될 때 연결된 자식 레코드를 자동으로 삭제하도록 외래 키 제약 조건을 구성할 수 있습니다. 즉, 사용자 계정이 삭제되면 사용자의 게스트북 항목이 자동으로 삭제되도록 이 외래 키 제약 조건을 설정할 수 있습니다. 이렇게 하려면 "INSERT 및 UPDATE 사양" 섹션을 확장하고 "규칙 삭제" 속성을 Cascade로 설정합니다.

Cascade 삭제에 대한 외래 키 제약 조건 구성

그림 5: 연속 삭제로 외래 키 제약 조건 구성(전체 크기 이미지를 보려면 클릭)

외래 키 제약 조건을 저장하려면 닫기 단추를 클릭하여 외래 키 관계에서 종료합니다. 그런 다음 도구 모음에서 저장 아이콘을 클릭하여 테이블과 이 관계를 저장합니다.

사용자의 홈타운, 홈페이지 및 서명 저장

이 표에서는 GuestbookComments 사용자 계정과 일대다 관계를 공유하는 정보를 저장하는 방법을 보여 줍니다. 각 사용자 계정에는 임의의 수의 연결된 주석이 있을 수 있으므로 이 관계는 각 주석을 특정 사용자에게 다시 연결하는 열이 포함된 주석 집합을 보관하는 테이블을 만들어 모델링됩니다. 를 SqlMembershipProvider사용하는 경우 이 링크는 형식 uniqueidentifier 이라는 UserId 열과 이 aspnet_Users.UserId열과 사이에 외래 키 제약 조건을 만들어 설정하는 것이 가장 좋습니다.

이제 사용자의 홈타운, 홈페이지 및 서명을 저장하려면 세 개의 열을 각 사용자 계정과 연결해야 합니다. 이 열은 그의 게스트 북 주석에 표시됩니다. 이 작업을 수행하는 방법에는 여러 가지가 있습니다.

  • 에 새 열aspnet_Users 추가또는aspnet_Membership테이블. 에서 사용하는 SqlMembershipProvider스키마를 수정하므로 이 방법은 권장하지 않습니다. 이 결정은 길을 따라 당신을 괴롭히기 위해 돌아올 수 있습니다. 예를 들어 향후 버전의 ASP.NET 다른 SqlMembershipProvider 스키마를 사용하는 경우 어떻게 해야 합니다. Microsoft는 ASP.NET 2.0 SqlMembershipProvider 데이터를 새 스키마로 마이그레이션하는 도구를 포함할 수 있지만 ASP.NET 2.0 SqlMembershipProvider 스키마를 수정한 경우 이러한 변환이 불가능할 수 있습니다.

  • ASP를 사용합니다. 홈 타운, 홈페이지 및 서명에 대한 프로필 속성을 정의하는 NET의 프로필 프레임워크입니다. ASP.NET 추가 사용자별 데이터를 저장하도록 설계된 프로필 프레임워크가 포함되어 있습니다. 멤버 자격 프레임워크와 마찬가지로 Profile 프레임워크는 공급자 모델 위에 빌드됩니다. .NET Framework sthat와 함께 SqlProfileProvider 제공되어 프로필 데이터를 SQL Server 데이터베이스에 저장합니다. 실제로 데이터베이스에는 SQL Server 멤버 자격 스키마 만들기 자습서에서 애플리케이션 서비스를 다시 추가할 때 추가된 (aspnet_Profile)에서 사용하는 SqlProfileProvider 테이블이 이미 있습니다.
    Profile 프레임워크의 기본 이점은 개발자가 에서 프로필 속성을 Web.config 정의할 수 있다는 것입니다. 기본 데이터 저장소에서 프로필 데이터를 직렬화하기 위해 코드를 작성할 필요가 없다는 것입니다. 즉, 프로필 속성 집합을 정의하고 코드에서 작업하는 것은 매우 쉽습니다. 그러나 프로필 시스템은 버전 관리와 관련하여 많은 것을 원하므로 나중에 새 사용자별 속성이 추가되거나 기존 속성을 제거하거나 수정할 것으로 예상되는 애플리케이션이 있는 경우 프로필 프레임워크가 최선의 옵션이 아닐 수 있습니다. 또한 SqlProfileProvider 는 프로필 속성을 비정규화된 방식으로 저장하므로 프로필 데이터에 대해 직접 쿼리를 실행할 수 없습니다(예: 뉴욕의 고향이 있는 사용자 수).
    프로필 프레임워크에 대한 자세한 내용은 이 자습서의 끝에 있는 "추가 읽기" 섹션을 참조하세요.

  • 데이터베이스의 새 테이블에 이러한 세 열을 추가하고 이 테이블과aspnet_Users 이 테이블 간에 일대일 관계를 설정합니다.. 이 방법은 Profile 프레임워크보다 약간 더 많은 작업을 포함하지만, 데이터베이스에서 추가 사용자 속성을 모델링하는 방법에 대한 최대 유연성을 제공합니다. 이 자습서에서 사용할 옵션입니다.

각 사용자에 대한 홈 타운, 홈페이지 및 서명을 저장하는 라는 UserProfiles 새 테이블을 만듭니다. 데이터베이스 Explorer 창에서 Tables 폴더를 마우스 오른쪽 단추로 클릭하고 새 테이블을 만들도록 선택합니다. 첫 번째 열 UserId 의 이름을 지정하고 해당 형식을 로 uniqueidentifier설정합니다. 값을 허용하지 NULL 않으며 열을 기본 키로 표시합니다. 다음으로 형식의 , 형식의 및 형식 nvarchar(50)HomepageUrlnvarchar(100)의 서명이라는 HomeTown 열을 추가합니다.nvarchar(500) 이러한 세 열 각각은 값을 수락할 NULL 수 있습니다.

UserProfiles 테이블 만들기

그림 6: 테이블 만들기 UserProfiles (전체 크기 이미지를 보려면 클릭)

테이블을 저장하고 이름을 로 지정합니다 UserProfiles. 마지막으로 테이블의 UserId 필드와 필드 간에 UserProfiles 외래 키 제약 조건을 aspnet_Users.UserId 설정합니다. 와 테이블 간의 GuestbookComments 외래 키 제약 조건과 aspnet_Users 마찬가지로 이 제약 조건은 연속 삭제됩니다. 의 UserIdUserProfiles 필드가 기본 키이므로 각 사용자 계정에 대해 테이블에 레코드 UserProfiles 가 두 개 이상 없도록 합니다. 이러한 유형의 관계를 일대일 관계라고 합니다.

이제 데이터 모델을 만들었으므로 사용할 준비가 되었습니다. 2단계와 3단계에서는 현재 로그온한 사용자가 홈타운, 홈페이지 및 서명 정보를 보고 편집하는 방법을 살펴봅니다. 4단계에서는 인증된 사용자가 게스트북에 새 주석을 제출하고 기존 주석을 볼 수 있는 인터페이스를 만듭니다.

2단계: 사용자의 홈타운, 홈페이지 및 서명 표시

현재 로그온한 사용자가 자신의 고향, 홈페이지 및 서명 정보를 보고 편집할 수 있는 다양한 방법이 있습니다. TextBox 및 레이블 컨트롤을 사용하여 사용자 인터페이스를 수동으로 만들거나 DetailsView 컨트롤과 같은 데이터 웹 컨트롤 중 하나를 사용할 수 있습니다. 데이터베이스 SELECTUPDATE 문을 수행하려면 페이지의 코드 숨김 클래스에 ADO.NET 코드를 작성하거나 SqlDataSource를 사용하여 선언적 접근 방식을 사용할 수 있습니다. 이상적으로 애플리케이션에는 페이지의 코드 숨김 클래스에서 프로그래밍 방식으로 호출하거나 ObjectDataSource 컨트롤을 통해 선언적으로 호출할 수 있는 계층화된 아키텍처가 포함되어 있습니다.

이 자습서 시리즈는 양식 인증, 권한 부여, 사용자 계정 및 역할에 중점을 두므로 이러한 다양한 데이터 액세스 옵션이나 계층화된 아키텍처가 ASP.NET 페이지에서 직접 SQL 문을 실행하는 데 선호되는 이유에 대해 자세히 논의하지 않습니다. 가장 빠르고 쉬운 옵션인 DetailsView 및 SqlDataSource를 사용하는 방법을 살펴보겠습니다. 하지만 설명된 개념은 대체 웹 컨트롤 및 데이터 액세스 논리에 확실히 적용될 수 있습니다. ASP.NET 데이터 작업에 대한 자세한 내용은 ASP.NET 2.0에서 데이터 작업 자습서 시리즈를 참조하세요.

폴더에서 AdditionalUserInfo.aspxMembership 페이지를 열고 DetailsView 컨트롤을 페이지에 추가하여 해당 ID 속성을 로 UserProfile 설정하고 및 Height 속성을 지 Width 웁습니다. DetailsView의 스마트 태그를 확장하고 새 데이터 원본 컨트롤에 바인딩하도록 선택합니다. 그러면 DataSource 구성 마법사가 시작됩니다(그림 7 참조). 첫 번째 단계에서는 데이터 원본 형식을 지정하도록 요청합니다. 데이터베이스에 직접 SecurityTutorials 연결하려면 데이터베이스 아이콘을 선택하고 를 로 UserProfileDataSource지정합니다ID.

UserProfileDataSource라는 새 SqlDataSource 컨트롤 추가

그림 7: 명명 UserProfileDataSource 된 새 SqlDataSource 컨트롤 추가(전체 크기 이미지를 보려면 클릭)

다음 화면에서는 데이터베이스를 사용할지 묻는 메시지를 표시합니다. 데이터베이스에 대한 연결 문자열을 Web.config 이미 정의했습니다 SecurityTutorials . 이 연결 문자열 이름 – SecurityTutorialsConnectionString 드롭다운 목록에 있어야 합니다. 이 옵션을 선택하고 다음을 클릭합니다.

Drop-Down 목록에서 SecurityTutorialsConnectionString을 선택합니다.

그림 8: Drop-Down 목록에서 선택 SecurityTutorialsConnectionString (전체 크기 이미지를 보려면 클릭)

후속 화면에서 쿼리할 테이블과 열을 지정하도록 요청합니다. UserProfiles 드롭다운 목록에서 테이블을 선택하고 모든 열을 검사.

UserProfiles 테이블에서 모든 열 다시 가져오기

그림 9: 테이블에서 모든 열 UserProfiles 다시 가져오기(전체 크기 이미지를 보려면 클릭)

그림 9의 현재 쿼리는 의 모든 레코드 UserProfiles를 반환하지만 현재 로그온한 사용자의 레코드에만 관심이 있습니다. 절을 WHERE 추가하려면 단추를 클릭하여 WHERE 절 추가 WHERE 대화 상자를 표시합니다(그림 10 참조). 여기에서 필터링할 열, 연산자 및 필터 매개 변수의 원본을 선택할 수 있습니다. 열로 선택하고 연산자로 "="를 선택합니다 UserId .

아쉽게도 현재 로그온한 사용자의 값을 반환하는 기본 제공 매개 변수 원본이 UserId 없습니다. 우리는 프로그래밍 방식으로이 값을 잡아해야합니다. 따라서 원본 드롭다운 목록을 "없음"으로 설정하고 추가 단추를 클릭하여 매개 변수를 추가한 다음 확인을 클릭합니다.

UserId 열에 필터 매개 변수 추가

그림 10: 열에 UserId 필터 매개 변수 추가(전체 크기 이미지를 보려면 클릭)

확인을 클릭하면 그림 9에 표시된 화면으로 돌아갑니다. 그러나 이번에는 화면 맨 아래에 있는 SQL 쿼리에 절이 WHERE 포함되어야 합니다. 다음을 클릭하여 "테스트 쿼리" 화면으로 이동합니다. 여기에서 쿼리를 실행하고 결과를 볼 수 있습니다. 마침을 클릭하여 마법사를 완료합니다.

DataSource 구성 마법사를 완료하면 Visual Studio는 마법사에 지정된 설정에 따라 SqlDataSource 컨트롤을 만듭니다. 또한 SqlDataSource SelectCommand의 에서 반환하는 각 열의 DetailsView에 BoundFields를 수동으로 추가합니다. 사용자가 이 값을 알 필요가 없으므로 DetailsView에 필드를 표시 UserId 할 필요가 없습니다. DetailsView 컨트롤의 선언적 태그에서 직접 이 필드를 제거하거나 스마트 태그에서 "필드 편집" 링크를 클릭하여 제거할 수 있습니다.

이 시점에서 페이지의 선언적 태그는 다음과 유사하게 표시됩니다.

<asp:DetailsView ID="UserProfile" runat="server"
     AutoGenerateRows="False" DataKeyNames="UserId"
     DataSourceID="UserProfileDataSource">
     <Fields>
          <asp:BoundField DataField="HomeTown" HeaderText="HomeTown"
               SortExpression="HomeTown" />
          <asp:BoundField DataField="HomepageUrl" HeaderText="HomepageUrl"
               SortExpression="HomepageUrl" />
          <asp:BoundField DataField="Signature" HeaderText="Signature"
               SortExpression="Signature" />
     </Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="UserProfileDataSource" runat="server"
          ConnectionString="<%$ ConnectionStrings:SecurityTutorialsConnectionString %>"
          SelectCommand="SELECT [UserId], [HomeTown], [HomepageUrl], [Signature] FROM
          [UserProfiles] WHERE ([UserId] = @UserId)">
     <SelectParameters>
          <asp:Parameter Name="UserId" Type="Object" />
     </SelectParameters>
</asp:SqlDataSource>

데이터를 선택하기 전에 SqlDataSource 컨트롤의 UserId 매개 변수를 현재 로그인한 사용자 UserId 로 프로그래밍 방식으로 설정해야 합니다. SqlDataSource Selecting 의 이벤트에 대한 이벤트 처리기를 만들고 다음 코드를 추가하여 이 작업을 수행할 수 있습니다.

protected void UserProfileDataSource_Selecting(object sender, 
          SqlDataSourceSelectingEventArgs e)
{
     // Get a reference to the currently logged on user
     MembershipUser currentUser = Membership.GetUser();
 
     // Determine the currently logged on user's UserId value
     Guid currentUserId = (Guid)currentUser.ProviderUserKey;
 
     // Assign the currently logged on user's UserId to the @UserId parameter
     e.Command.Parameters["@UserId"].Value = currentUserId;
}

위의 코드는 클래스의 GetUser 메서드를 호출하여 현재 로그온한 사용자에 대한 참조를 Membership 가져오는 것으로 시작합니다. 그러면 속성에 가 MembershipUser 포함된 개체 ProviderUserKeyUserId반환됩니다. UserId 그런 다음 값이 SqlDataSource의 @UserId 매개 변수에 할당됩니다.

참고

메서드는 Membership.GetUser() 현재 로그온한 사용자에 대한 정보를 반환합니다. 익명 사용자가 페이지를 방문하는 경우 값 null이 반환됩니다. 이 경우 속성을 읽으 ProviderUserKey 려고 할 NullReferenceException 때 다음 코드 줄의 가 발생합니다. 물론 인증된 사용자만 이 폴더의 ASP.NET 리소스에 AdditionalUserInfo.aspx 액세스할 수 있도록 이전 자습서에서 URL 권한 부여를 구성했기 때문에 페이지에서 값을 반환 null 하는 것에 대해 Membership.GetUser() 걱정할 필요가 없습니다. 익명 액세스가 허용되는 페이지에서 현재 로그온한 사용자에 대한 정보에 액세스해야 하는 경우 속성을 참조하기 전에 메서드에서 GetUser() 비 개체null MembershipUser가 반환되는지 검사 합니다.

브라우저를 AdditionalUserInfo.aspx 통해 페이지를 방문하는 경우 아직 테이블에 행을 추가하지 않았기 때문에 빈 페이지가 UserProfiles 표시됩니다. 6단계에서는 새 사용자 계정을 만들 때 테이블에 새 행을 자동으로 추가하도록 CreateUserWizard 컨트롤을 사용자 지정하는 UserProfiles 방법을 살펴보겠습니다. 그러나 지금은 테이블에 레코드를 수동으로 만들어야 합니다.

Visual Studio의 데이터베이스 Explorer 이동하여 Tables 폴더를 확장합니다. 테이블을 마우스 오른쪽 단추로 aspnet_Users 클릭하고 "테이블 데이터 표시"를 선택하여 테이블의 레코드를 확인합니다. 테이블에 대해 UserProfiles 동일한 작업을 수행합니다. 그림 11은 세로로 타일화할 때 이러한 결과를 보여줍니다. 내 데이터베이스에는 현재 aspnet_Users Bruce, Fred 및 Tito에 대한 레코드가 있지만 테이블에는 레코드가 UserProfiles 없습니다.

aspnet_Users 및 UserProfiles 테이블의 내용이 표시됩니다.

그림 11: 및 UserProfiles 테이블의 aspnet_Users 내용이 표시됩니다(전체 크기 이미지를 보려면 클릭).

, HomepageUrlSignature 필드에 대한 값을 수동으로 입력하여 테이블에 새 레코드 UserProfilesHomeTown추가합니다. 새 UserProfiles 레코드에서 유효한 UserId 값을 가져오는 가장 쉬운 방법은 테이블의 UserId 특정 사용자 계정 aspnet_Users 에서 필드를 선택하고 복사하여 의 필드에 UserProfiles붙여넣는 UserId 것입니다. 그림 12는 Bruce에 UserProfiles 대한 새 레코드가 추가된 후의 테이블을 보여줍니다.

Bruce용 UserProfiles에 레코드가 추가됨

그림 12: Bruce에 UserProfiles 대한 레코드가 에 추가됨(전체 크기 이미지를 보려면 클릭)

브루스로 AdditionalUserInfo.aspx 로그인한 페이지로 돌아갑니다. 그림 13에서 보여 주듯이 Bruce의 설정이 표시됩니다.

현재 방문하는 사용자에게 자신의 설정이 표시됩니다.

그림 13: 현재 방문하는 사용자에게 자신의 설정이 표시됩니다(전체 크기 이미지를 보려면 클릭).

참고

계속 진행하여 각 멤버 자격 사용자에 대한 레코드를 UserProfiles 테이블에 수동으로 추가합니다. 6단계에서는 새 사용자 계정을 만들 때 테이블에 새 행을 자동으로 추가하도록 CreateUserWizard 컨트롤을 사용자 지정하는 UserProfiles 방법을 살펴보겠습니다.

3단계: 사용자가 홈타운, 홈페이지 및 서명을 편집할 수 있도록 허용

이 시점에서 현재 로그인한 사용자는 홈타운, 홈페이지 및 서명 설정을 볼 수 있지만 아직 수정할 수는 없습니다. 데이터를 편집할 수 있도록 DetailsView 컨트롤을 업데이트해 보겠습니다.

먼저 실행할 문과 해당 매개 변수를 지정하여 UPDATE SqlDataSource에 대한 를 추가 UpdateCommand 해야 합니다. SqlDataSource를 선택하고 속성 창 UpdateQuery 속성 옆에 있는 줄임표를 클릭하여 명령 및 매개 변수 편집기 대화 상자를 표시합니다. 텍스트 상자에 다음 UPDATE 문을 입력합니다.

UPDATE UserProfiles SET
     HomeTown = @HomeTown,
     HomepageUrl = @HomepageUrl,
     Signature = @Signature
WHERE UserId = @UserId

다음으로, "매개 변수 새로 고침" 단추를 클릭하면 문의 각 매개 변수에 대한 SqlDataSource 컨트롤의 UpdateParameters 컬렉션에 매개 변수가 UPDATE 만들어집니다. 모든 매개 변수의 원본을 없음으로 설정하고 확인 단추를 클릭하여 대화 상자를 완료합니다.

SqlDataSource의 UpdateCommand 및 UpdateParameters 지정

그림 14: SqlDataSource 및 UpdateCommandUpdateParameters 지정(전체 크기 이미지를 보려면 클릭)

SqlDataSource 컨트롤에 추가되었으므로 DetailsView 컨트롤은 이제 편집을 지원할 수 있습니다. DetailsView의 스마트 태그에서 "편집 사용" 확인란을 검사. 이렇게 하면 속성이 True로 설정된 CommandField가 ShowEditButton 컨트롤의 Fields 컬렉션에 추가됩니다. 이렇게 하면 DetailsView가 읽기 전용 모드로 표시되고 편집 모드로 표시될 때 업데이트 및 취소 단추가 표시되면 편집 단추가 렌더링됩니다. 하지만 사용자가 편집을 클릭하도록 요구하는 대신 DetailsView 컨트롤의 DefaultMode 속성을 로 설정하여 DetailsView가 "항상 편집 가능한" 상태로 렌더링되도록 할 Edit수 있습니다.

이러한 변경 내용으로 DetailsView 컨트롤의 선언적 태그는 다음과 유사하게 표시됩니다.

<asp:DetailsView ID="UserProfile" runat="server"
          AutoGenerateRows="False" DataKeyNames="UserId"
          DataSourceID="UserProfileDataSource" DefaultMode="Edit">
     <Fields>
          <asp:BoundField DataField="HomeTown" HeaderText="HomeTown"
               SortExpression="HomeTown" />
          <asp:BoundField DataField="HomepageUrl" HeaderText="HomepageUrl"
               SortExpression="HomepageUrl" />
          <asp:BoundField DataField="Signature" HeaderText="Signature"
               SortExpression="Signature" />
          <asp:CommandField ShowEditButton="True" />
     </Fields>
</asp:DetailsView>

CommandField 및 속성이 추가되었습니다 DefaultMode .

계속 진행하여 브라우저를 통해 이 페이지를 테스트합니다. 에 UserProfiles해당 레코드가 있는 사용자를 방문할 때 사용자의 설정은 편집 가능한 인터페이스에 표시됩니다.

DetailsView는 편집 가능한 인터페이스를 렌더링합니다.

그림 15: DetailsView 편집 가능한 인터페이스 렌더링(전체 크기 이미지를 보려면 클릭)

값을 변경하고 업데이트 단추를 클릭합니다. 아무 일도 일어나지 않는 것처럼 보입니다. 포스트백이 있고 값이 데이터베이스에 저장되지만 저장이 발생했다는 시각적 피드백은 없습니다.

이 문제를 해결하려면 Visual Studio로 돌아가서 DetailsView 위에 레이블 컨트롤을 추가합니다. 를 ID 로 설정하고 해당 Text 속성을 "설정이 업데이트되었습니다"로 설정하고 및 VisibleEnableViewState 속성을 로 falseSettingsUpdatedMessage설정합니다.

<asp:Label ID="SettingsUpdatedMessage" runat="server"
     Text="Your settings have been updated."
     EnableViewState="false"
     Visible="false"></asp:Label>

DetailsView를 SettingsUpdatedMessage 업데이트할 때마다 레이블을 표시해야 합니다. 이렇게 하려면 DetailsView의 ItemUpdated 이벤트에 대한 이벤트 처리기를 만들고 다음 코드를 추가합니다.

protected void UserProfile_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e)
{
     SettingsUpdatedMessage.Visible = true;
}

브라우저를 AdditionalUserInfo.aspx 통해 페이지로 돌아가 데이터를 업데이트합니다. 이번에는 유용한 상태 메시지가 표시됩니다.

설정이 업데이트되면 짧은 메시지가 표시됩니다.

그림 16: 설정이 업데이트되면 짧은 메시지가 표시됩니다(전체 크기 이미지를 보려면 클릭).

참고

DetailsView 컨트롤의 편집 인터페이스는 원하는 것이 많습니다. 표준 크기의 텍스트 상자를 사용하지만 서명 필드는 여러 줄 텍스트 상자일 수 있습니다. Homepage URL을 입력한 경우 "http://" 또는 "https://"로 시작하는 데 RegularExpressionValidator를 사용해야 합니다. 또한 DetailsView 컨트롤의 속성이 DefaultMode 로 설정되어 Edit있으므로 취소 단추는 아무 작업도 수행하지 않습니다. 제거하거나 클릭할 때 사용자를 다른 페이지(예: )로 ~/Default.aspx리디렉션해야 합니다. 나는 독자를위한 연습으로 이러한 향상을 떠난다.

현재 웹 사이트는 페이지에 대한 링크를 AdditionalUserInfo.aspx 제공하지 않습니다. 이 URL에 도달하는 유일한 방법은 브라우저의 주소 표시줄에 페이지의 URL을 직접 입력하는 것입니다. master 페이지에서 이 페이지에 Site.master 대한 링크를 추가해 보겠습니다.

master 페이지에는 인증된 방문자와 익명 방문자에 LoginContent 대해 서로 다른 태그를 표시하는 LoginView 웹 컨트롤이 ContentPlaceHolder에 포함되어 있습니다. 페이지에 대한 링크를 포함하도록 LoginView 컨트롤 LoggedInTemplate 을 업데이트합니다 AdditionalUserInfo.aspx . 이러한 변경을 수행한 후 LoginView 컨트롤의 선언적 태그는 다음과 유사하게 표시됩니다.

<asp:LoginView ID="LoginView1" runat="server">
     <LoggedInTemplate>
          Welcome back,
          <asp:LoginName ID="LoginName1" runat="server" />.
          <br />
          <asp:HyperLink ID="lnkUpdateSettings" runat="server" 
               NavigateUrl="~/Membership/AdditionalUserInfo.aspx">
               Update Your Settings</asp:HyperLink>
     </LoggedInTemplate>
     <AnonymousTemplate>
          Hello, stranger.
     </AnonymousTemplate>
</asp:LoginView>

에 HyperLink 컨트롤이 lnkUpdateSettings 추가되었습니다 LoggedInTemplate. 이 링크를 사용하면 인증된 사용자가 빠르게 페이지로 이동하여 홈페이지, 홈페이지 및 서명 설정을 보고 수정할 수 있습니다.

4단계: 새 게스트 북 주석 추가

Guestbook.aspx 페이지에서는 인증된 사용자가 방명록을 보고 메모를 남길 수 있습니다. 먼저 인터페이스를 만들어 새 게스트북 주석을 추가해 보겠습니다.

Guestbook.aspx Visual Studio에서 페이지를 열고 두 개의 TextBox 컨트롤로 구성된 사용자 인터페이스를 생성합니다. 하나는 새 주석의 제목용이고 다른 하나는 본문용입니다. 첫 번째 TextBox 컨트롤의 ID 속성을 로 설정하고 해당 Columns 속성을 Subject 40으로 설정하고, 두 번째 컨트롤을 BodyID 로 설정하고, 및 WidthTextModeMultiLineRows 속성을 각각 "95%"와 8로 설정합니다. 사용자 인터페이스를 완료하려면 라는 PostCommentButton Button Web 컨트롤을 추가하고 해당 Text 속성을 "메모 게시"로 설정합니다.

각 게스트 북 주석에는 제목과 본문이 필요하므로 각 TextBox에 대해 RequiredFieldValidator를 추가합니다. ValidationGroup 이러한 컨트롤의 속성을 "EnterComment"로 설정하고, 마찬가지로 컨트롤의 ValidationGroup 속성을 "EnterComment"로 설정합니다PostCommentButton. ASP에 대한 자세한 내용을 참조하세요. NET의 유효성 검사 컨트롤은 ASP.NET 양식 유효성 검사를 검사.

사용자 인터페이스를 만든 후 페이지의 선언적 태그는 다음과 같이 표시됩니다.

<h3>Leave a Comment</h3>
<p>
     <b>Subject:</b>
     <asp:RequiredFieldValidator ID="SubjectReqValidator" runat="server"
          ErrorMessage="You must provide a value for Subject"
          ControlToValidate="Subject" ValidationGroup="EnterComment">
     </asp:RequiredFieldValidator><br/>
     <asp:TextBox ID="Subject" Columns="40" runat="server"></asp:TextBox>
</p>
<p>
     <b>Body:</b>
     <asp:RequiredFieldValidator ID="BodyReqValidator" runat="server"
          ControlToValidate="Body"
          ErrorMessage="You must provide a value for Body" ValidationGroup="EnterComment">
     </asp:RequiredFieldValidator><br/>
     <asp:TextBox ID="Body" TextMode="MultiLine" Width="95%"
          Rows="8" runat="server"></asp:TextBox>
</p>
<p>
     <asp:Button ID="PostCommentButton" runat="server" 
          Text="Post Your Comment"
          ValidationGroup="EnterComment" />
</p>

사용자 인터페이스가 완료되면 다음 작업은 를 클릭할 때 PostCommentButton 테이블에 새 레코드를 GuestbookComments 삽입하는 것입니다. 이 작업은 여러 가지 방법으로 수행할 수 있습니다. 단추의 Click 이벤트 처리기에서 ADO.NET 코드를 작성하거나, 페이지에 SqlDataSource 컨트롤을 추가하고, 를 InsertCommand구성한 다음, 이벤트 처리기에서 Click 메서드를 Insert 호출하거나, 새 게스트북 주석을 삽입하는 중간 계층을 빌드하고 이벤트 처리기에서 Click 이 기능을 호출할 수 있습니다. 3단계에서 SqlDataSource를 사용하는 것을 살펴보았습니다. 여기서는 ADO.NET 코드를 사용하겠습니다.

참고

Microsoft SQL Server 데이터베이스에서 프로그래밍 방식으로 데이터에 액세스하는 데 사용되는 ADO.NET 클래스는 네임스페이 System.Data.SqlClient 스에 있습니다. 이 네임스페이스를 페이지의 코드 숨김 클래스(즉, using System.Data.SqlClient;)로 가져와야 할 수 있습니다.

Click 이벤트에 대한 PostCommentButton이벤트 처리기를 만들고 다음 코드를 추가합니다.

protected void PostCommentButton_Click(object sender, EventArgs e)
{
     if (!Page.IsValid)
          return;
 
     // Determine the currently logged on user's UserId
     MembershipUser currentUser = Membership.GetUser();
     Guid currentUserId = (Guid)currentUser.ProviderUserKey;
 
     // Insert a new record into GuestbookComments
     string connectionString = 
          ConfigurationManager.ConnectionStrings["SecurityTutorialsConnectionString"].ConnectionString;
     string insertSql = "INSERT INTO GuestbookComments(Subject, Body, UserId) VALUES(@Subject,
               @Body, @UserId)";
 
     using (SqlConnection myConnection = new SqlConnection(connectionString))
     {
          myConnection.Open();
          SqlCommand myCommand = new SqlCommand(insertSql, myConnection);
          myCommand.Parameters.AddWithValue("@Subject", Subject.Text.Trim());
          myCommand.Parameters.AddWithValue("@Body", Body.Text.Trim());
          myCommand.Parameters.AddWithValue("@UserId", currentUserId);
          myCommand.ExecuteNonQuery();
          myConnection.Close();
     }
 
     // "Reset" the Subject and Body TextBoxes
     Subject.Text = string.Empty;
     Body.Text = string.Empty;
}

Click 이벤트 처리기는 사용자가 제공한 데이터가 유효한지 확인하여 시작합니다. 그렇지 않으면 레코드를 삽입하기 전에 이벤트 처리기가 종료됩니다. 제공된 데이터가 유효하다고 가정하면 현재 로그온한 사용자의 UserId 값이 검색되어 지역 변수에 currentUserId 저장됩니다. 레코드를 에 GuestbookComments삽입할 때 값을 제공해야 UserId 하므로 이 값이 필요합니다.

그런 다음 데이터베이스에 대한 연결 문자열이 SecurityTutorials 검색 Web.config 되고 INSERT SQL 문이 지정됩니다. SqlConnection 그런 다음 개체가 만들어지고 열립니다. 다음으로 개체가 SqlCommand 생성되고 쿼리에 사용되는 매개 변수의 값이 INSERT 할당됩니다. INSERT 그런 다음 문이 실행되고 연결이 닫힙니다. 이벤트 처리기의 Subject 끝에서 사용자의 값이 포스트백에서 유지되지 않도록 및 Body TextBoxes Text 의 속성이 지워집니다.

브라우저에서 이 페이지를 테스트합니다. 이 페이지는 폴더에 Membership 있으므로 익명 방문자가 액세스할 수 없습니다. 따라서 먼저 로그온해야 합니다(아직 로그온하지 않은 경우). 및 Body TextBoxes에 Subject 값을 입력하고 단추를 클릭합니다PostCommentButton. 그러면 새 레코드가 에 추가 GuestbookComments됩니다. 포스트백 시 제공한 제목과 본문이 TextBox에서 초기화됩니다.

단추를 클릭한 PostCommentButton 후에는 주석이 게스트북에 추가되었다는 시각적 피드백이 없습니다. 5단계에서 수행할 기존 방명록 주석을 표시하려면 이 페이지를 업데이트해야 합니다. 이렇게 하면 메모 목록에 방금 추가된 주석이 표시되어 적절한 시각적 피드백을 제공합니다. 지금은 테이블의 GuestbookComments 내용을 검사하여 게스트 북 주석이 저장되었는지 확인합니다.

그림 17은 두 개의 주석이 GuestbookComments 남아 있는 후 테이블의 내용을 보여 줍니다.

GuestbookComments 테이블에서 게스트 북 주석을 볼 수 있습니다.

그림 17: 표에서 방명록 주석을 GuestbookComments 볼 수 있습니다(전체 크기 이미지를 보려면 클릭).

참고

사용자가 잠재적으로 위험한 태그(예: HTML)가 포함된 게스트 북 주석을 삽입하려고 하면 ASP.NET 을 HttpRequestValidationExceptionthrow합니다. 이 예외가 throw된 이유 및 사용자가 잠재적으로 위험한 값을 제출하도록 허용하는 방법에 대한 자세한 내용은 요청 유효성 검사 백서를 참조하세요.

5단계: 기존 게스트 북 주석 나열

댓글을 남기는 것 외에도 페이지를 방문하는 Guestbook.aspx 사용자는 게스트 북의 기존 메모를 볼 수 있어야 합니다. 이렇게 하려면 라는 ListView 컨트롤 CommentList 을 페이지 아래쪽에 추가합니다.

참고

ListView 컨트롤은 ASP.NET 버전 3.5의 새로운 기능입니다. 매우 사용자 지정 가능하고 유연한 레이아웃으로 항목 목록을 표시하도록 설계되어 있지만 여전히 GridView와 같은 기본 제공 편집, 삽입, 삭제, 페이징 및 정렬 기능을 제공합니다. ASP.NET 2.0을 사용하는 경우 DataList 또는 Repeater 컨트롤을 대신 사용해야 합니다. ListView 사용에 대한 자세한 내용은 Scott Guthrie의 블로그 항목인 Asp:ListView 컨트롤 및 ListView 컨트롤을 사용하여 데이터 표시 문서를 참조하세요.

ListView의 스마트 태그를 열고 데이터 원본 선택 드롭다운 목록에서 컨트롤을 새 데이터 원본에 바인딩합니다. 2단계에서 확인한 것처럼 데이터 원본 구성 마법사가 시작됩니다. 데이터베이스 아이콘을 선택하고 결과 SqlDataSource CommentsDataSource의 이름을 지정한 다음 확인을 클릭합니다. 그런 다음 드롭다운 목록에서 연결 문자열을 선택하고 SecurityTutorialsConnectionString 다음을 클릭합니다.

2단계의 이 시점에서 드롭다운 목록에서 테이블을 선택하고 UserProfiles 반환할 열을 선택하여 쿼리할 데이터를 지정했습니다(그림 9 참조). 그러나 이번에는 의 레코드 GuestbookComments뿐만 아니라 주석 작성자의 홈페이지, 홈페이지, 서명 및 사용자 이름도 다시 가져오는 SQL 문을 작성하려고 합니다. 따라서 "사용자 지정 SQL 문 또는 저장 프로시저 지정" 라디오 단추를 선택하고 다음을 클릭합니다.

그러면 "사용자 지정 문 또는 저장 프로시저 정의" 화면이 표시됩니다. 쿼리 작성기 단추를 클릭하여 쿼리를 그래픽으로 작성합니다. 쿼리 작성기에서는 쿼리할 테이블을 지정하라는 메시지를 표시하여 시작합니다. GuestbookComments, UserProfilesaspnet_Users 테이블을 선택하고 확인을 클릭합니다. 이렇게 하면 세 개의 테이블이 모두 디자인 화면에 추가됩니다. , 및 테이블 사이에 GuestbookComments외래 키 제약 조건이 있으므로 쿼리 작성기에서 이러한 테이블을 자동으로 지정합니다JOIN.aspnet_UsersUserProfiles

반환할 열을 지정하기만 하면 됩니다. GuestbookComments 테이블에서 , BodyCommentDate 열을 선택하고 Subject테이블에서 , HomepageUrl및 열을 반환HomeTown하고 Signature 에서 UserProfilesaspnet_Users를 반환 UserName 합니다. 또한 가장 최근 게시물이 먼저 반환되도록 쿼리 끝에 SELECT "ORDER BY CommentDate DESC"를 추가합니다. 이러한 항목을 선택한 후 쿼리 작성기 인터페이스는 그림 18의 스크린샷과 유사하게 표시됩니다.

생성된 쿼리는 GuestbookComments, UserProfiles 및 aspnet_Users 테이블을 조인합니다.

그림 18: 생성된 쿼리 JOINGuestbookComments, UserProfilesaspnet_Users 테이블(전체 크기 이미지를 보려면 클릭)

확인을 클릭하여 쿼리 작성기 창을 닫고 "사용자 지정 문 또는 저장 프로시저 정의" 화면으로 돌아갑니다. 다음을 클릭하여 "쿼리 테스트" 화면으로 이동하여 쿼리 테스트 단추를 클릭하여 쿼리 결과를 볼 수 있습니다. 준비가 되면 마침을 클릭하여 데이터 원본 구성 마법사를 완료합니다.

2단계에서 데이터 원본 구성 마법사를 완료하면 연결된 DetailsView 컨트롤의 Fields 컬렉션이 에서 반환 SelectCommand된 각 열에 대한 BoundField를 포함하도록 업데이트되었습니다. 그러나 ListView는 변경되지 않습니다. 레이아웃을 정의해야 합니다. ListView의 레이아웃은 선언적 태그를 통해 또는 스마트 태그의 "ListView 구성" 옵션을 통해 수동으로 생성할 수 있습니다. 나는 일반적으로 손으로 태그를 정의하는 것을 선호하지만, 당신에게 가장 자연스러운 방법을 사용합니다.

ListView 컨트롤에 대해 다음 LayoutTemplate, ItemTemplateItemSeparatorTemplate 를 사용하게 되었습니다.

<asp:ListView ID="CommentList" runat="server" DataSourceID="CommentsDataSource">
     <LayoutTemplate>
          <span ID="itemPlaceholder" runat="server" />
          <p>
               <asp:DataPager ID="DataPager1" runat="server">
                    <Fields>
                         <asp:NextPreviousPagerField ButtonType="Button" 
                              ShowFirstPageButton="True"
                              ShowLastPageButton="True" />
                    </Fields>
               </asp:DataPager>
          </p>
     </LayoutTemplate>
     <ItemTemplate>
          <h4><asp:Label ID="SubjectLabel" runat="server" 
               Text='<%# Eval("Subject") %>' /></h4>
          <asp:Label ID="BodyLabel" runat="server" 
               Text='<%# Eval("Body").ToString().Replace(Environment.NewLine, "<br />") %>' />
          <p>
               ---<br />
               <asp:Label ID="SignatureLabel" Font-Italic="true" runat="server"
                    Text='<%# Eval("Signature") %>' />
               <br />
               <br />
               My Home Town:
               <asp:Label ID="HomeTownLabel" runat="server" 
                    Text='<%# Eval("HomeTown") %>' />
               <br />
               My Homepage:
               <asp:HyperLink ID="HomepageUrlLink" runat="server" 
                    NavigateUrl='<%# Eval("HomepageUrl") %>' 
                    Text='<%# Eval("HomepageUrl") %>' />
          </p>
          <p align="center">
               Posted by
               <asp:Label ID="UserNameLabel" runat="server" 
                    Text='<%# Eval("UserName") %>' /> on
               <asp:Label ID="CommentDateLabel" runat="server" 
                    Text='<%# Eval("CommentDate") %>' />
          </p>
     </ItemTemplate>
     <ItemSeparatorTemplate>
          <hr />
     </ItemSeparatorTemplate>
</asp:ListView>

LayoutTemplate 컨트롤에서 내보낸 태그를 정의하고 ItemTemplate 는 SqlDataSource에서 반환된 각 항목을 렌더링합니다. ItemTemplate의 결과 태그는 의 itemPlaceholder 컨트롤에 LayoutTemplate배치됩니다. 외에도 itemPlaceholderLayoutTemplate 에는 DataPager 컨트롤이 포함되어 있습니다. 이 컨트롤은 ListView가 페이지당 10개의 게스트북 주석만 표시하도록 제한하고(기본값) 페이징 인터페이스를 렌더링합니다.

제목 ItemTemplate 아래에 본문이 있는 요소에 <h4> 각 게스트북 주석의 제목이 표시됩니다. 본문을 표시하는 데 사용되는 구문은 databinding 문에서 반환된 Eval("Body") 데이터를 가져와 문자열로 변환하고 줄 바꿈을 <br /> 요소로 바꿉니다. HTML에서 공백을 무시하므로 주석을 제출할 때 입력한 줄 바꿈을 표시하려면 이 변환이 필요합니다. 사용자의 서명은 기울임꼴로 본문 아래에 표시되고, 그 뒤에 사용자의 홈페이지, 홈페이지에 대한 링크, 댓글이 만들어진 날짜 및 시간 및 댓글을 남긴 사람의 사용자 이름이 표시됩니다.

잠시 시간을 내어 브라우저를 통해 페이지를 봅니다. 여기에 표시된 5단계에서 게스트 문서에 추가한 주석이 표시됩니다.

Guestbook.aspx 이제 게스트 북의 메모를 표시합니다.

그림 19: Guestbook.aspx 이제 방명록의 메모를 표시합니다(전체 크기 이미지를 보려면 클릭).

게스트북에 새 주석을 추가해 보세요. 단추를 클릭하면 PostCommentButton 페이지가 다시 게시되고 메모가 데이터베이스에 추가되지만 ListView 컨트롤은 새 주석을 표시하도록 업데이트되지 않습니다. 이 작업은 다음 중 하나를 통해 해결할 수 있습니다.

  • 데이터베이스에 새 주석을 PostCommentButton 삽입한 후 ListView 컨트롤의 메서드를 호출할 수 있도록 단추 ClickDataBind() 이벤트 처리기를 업데이트하거나
  • ListView 컨트롤의 EnableViewState 속성을 로 false설정합니다. 이 방법은 컨트롤의 뷰 상태를 사용하지 않도록 설정하여 모든 포스트백의 기본 데이터에 다시 바인딩해야 하기 때문에 작동합니다.

이 자습서에서 다운로드할 수 있는 자습서 웹 사이트는 두 가지 기술을 모두 보여 줍니다. ListView 컨트롤의 EnableViewState 속성 false 과 프로그래밍 방식으로 데이터를 ListView에 다시 바인딩하는 데 필요한 코드는 Click 이벤트 처리기에 있지만 주석 처리됩니다.

참고

현재 페이지에서 AdditionalUserInfo.aspx 는 홈타운, 홈페이지 및 서명 설정을 보고 편집할 수 있습니다. 로그인한 사용자의 게스트 북 주석을 표시하도록 업데이트 AdditionalUserInfo.aspx 하는 것이 좋을 수 있습니다. 즉, 사용자는 자신의 정보를 검사하고 수정하는 것 외에도 페이지를 방문하여 AdditionalUserInfo.aspx 과거에 어떤 게스트 북 댓글을 작성했는지 확인할 수 있습니다. 나는 관심있는 독자를위한 운동으로 이것을 떠난다.

6단계: 홈타운, 홈페이지 및 서명에 대한 인터페이스를 포함하도록 CreateUserWizard 컨트롤 사용자 지정

페이지에서 사용하는 Guestbook.aspx 쿼리는 SELECTINNER JOIN 사용하여 , UserProfilesaspnet_Users 테이블 간에 관련 레코드를 GuestbookComments결합합니다. 에 UserProfiles 레코드가 없는 사용자가 게스트북 주석을 만드는 경우 및 에 일치하는 레코드가 있을 때 만 레코드를 반환 GuestbookComments 하기 때문에 INNER JOIN 주석이 ListView에 UserProfilesaspnet_Users표시되지 않습니다. 3단계에서 보았듯이 사용자가 에 레코드 UserProfiles 가 없는 경우 페이지에서 설정을 AdditionalUserInfo.aspx 보거나 편집할 수 없습니다.

물론 디자인 결정으로 인해 멤버 자격 시스템의 모든 사용자 계정에 테이블의 일치하는 레코드 UserProfiles 가 있어야 합니다. 원하는 것은 CreateUserWizard를 UserProfiles 통해 새 멤버 자격 사용자 계정을 만들 때마다 해당 레코드를 에 추가하는 것입니다.

사용자 계정 만들기 자습서에서 설명한 대로 새 멤버 자격 사용자 계정을 만든 후 CreateUserWizard 컨트롤은 해당CreatedUser 이벤트를 발생합니다. 이 이벤트에 대한 이벤트 처리기를 만들고 방금 만든 사용자의 UserId를 가져와서 , HomepageUrlSignature 열의 UserProfiles 기본값을 사용하여 테이블에 레코드를 HomeTown삽입할 수 있습니다. 또한 추가 TextBox를 포함하도록 CreateUserWizard 컨트롤의 인터페이스를 사용자 지정하여 사용자에게 이러한 값을 묻는 메시지를 표시할 수 있습니다.

먼저 기본값을 사용하여 이벤트 처리기의 테이블에 새 행 UserProfilesCreatedUser 추가하는 방법을 살펴보겠습니다. 그런 다음 CreateUserWizard 컨트롤의 사용자 인터페이스를 사용자 지정하여 새 사용자의 홈페이지, 홈페이지 및 서명을 수집하는 추가 양식 필드를 포함하는 방법을 알아보세요.

에 기본 행 추가UserProfiles

사용자 계정 만들기 자습서에서는 폴더의 페이지에 CreateUserWizard 컨트롤을 CreatingUserAccounts.aspxMembership 추가했습니다. CreateUserWizard 컨트롤이 사용자 계정을 만들 때 테이블에 레코드를 UserProfiles 추가하도록 하려면 CreateUserWizard 컨트롤의 기능을 업데이트해야 합니다. 페이지를 변경하는 CreatingUserAccounts.aspx 대신 페이지에 새 CreateUserWizard 컨트롤 EnhancedCreateUserWizard.aspx 을 추가하고 이 자습서를 수정해 보겠습니다.

EnhancedCreateUserWizard.aspx Visual Studio에서 페이지를 열고 도구 상자에서 CreateUserWizard 컨트롤을 페이지로 끌어옵니다. CreateUserWizard 컨트롤의 ID 속성을 로 NewUserWizard설정합니다. 사용자 계정 만들기 자습서에서 설명한 것처럼 CreateUserWizard의 기본 사용자 인터페이스는 방문자에게 필요한 정보를 묻는 메시지를 표시합니다. 이 정보가 제공되면 컨트롤은 멤버 자격 프레임워크에서 내부적으로 새 사용자 계정을 만듭니다. 단 한 줄의 코드를 작성할 필요가 없습니다.

CreateUserWizard 컨트롤은 워크플로 중에 여러 이벤트를 발생합니다. 방문자가 요청 정보를 제공하고 양식을 제출하면 CreateUserWizard 컨트롤이 처음에 해당 이벤트를 발생합니다CreatingUser. 만들기 프로세스 CreateUserError 중에 문제가 발생하면 이벤트가 발생합니다. 그러나 사용자가 성공적으로 만들어 CreatedUser 지면 이벤트가 발생합니다. 사용자 계정 만들기 자습서에서는 제공된 사용자 이름에 선행 또는 후행 공백이 포함되지 않고 사용자 이름이 암호의 아무 곳에도 표시되지 않도록 이벤트에 대한 CreatingUser 이벤트 처리기를 만들었습니다.

방금 만든 사용자에 대한 테이블에 행 UserProfiles 을 추가하려면 이벤트에 대한 CreatedUser 이벤트 처리기를 만들어야 합니다. 이벤트가 발생할 때까지 CreatedUser 멤버 자격 프레임워크에서 사용자 계정이 이미 생성되어 계정의 UserId 값을 검색할 수 있습니다.

CreatedUser 이벤트에 대한 NewUserWizard이벤트 처리기를 만들고 다음 코드를 추가합니다.

protected void NewUserWizard_CreatedUser(object sender, EventArgs e)
{
     // Get the UserId of the just-added user
     MembershipUser newUser = Membership.GetUser(NewUserWizard.UserName);
     Guid newUserId = (Guid)newUser.ProviderUserKey;
 
     // Insert a new record into UserProfiles
     string connectionString = 
          ConfigurationManager.ConnectionStrings["SecurityTutorialsConnectionString"].ConnectionString;
     string insertSql = "INSERT INTO UserProfiles(UserId, HomeTown, HomepageUrl,
          Signature) VALUES(@UserId, @HomeTown, @HomepageUrl, @Signature)";
 
     using (SqlConnection myConnection = new SqlConnection(connectionString))
     {
          myConnection.Open();
          SqlCommand myCommand = new SqlCommand(insertSql, myConnection);
          myCommand.Parameters.AddWithValue("@UserId", newUserId);
          myCommand.Parameters.AddWithValue("@HomeTown", DBNull.Value);
          myCommand.Parameters.AddWithValue("@HomepageUrl", DBNull.Value);
          myCommand.Parameters.AddWithValue("@Signature", DBNull.Value);
          myCommand.ExecuteNonQuery();
          myConnection.Close();
     }
}

위의 코드는 방금 추가한 사용자 계정의 UserId를 검색하여 생성됩니다. 이 작업은 메서드를 Membership.GetUser(username) 사용하여 특정 사용자에 대한 정보를 반환한 다음 속성을 사용하여 ProviderUserKey UserId를 검색하여 수행됩니다. CreateUserWizard 컨트롤에서 사용자가 입력한 사용자 이름은 해당UserName 속성을 통해 사용할 수 있습니다.

다음으로 연결 문자열이 검색 Web.config 되고 INSERT 문이 지정됩니다. 필요한 ADO.NET 개체가 인스턴스화되고 명령이 실행됩니다. 코드는 , @HomepageUrl@Signature 매개 변수에 @HomeTowninstance 할당 DBNull 합니다. 이 매개 변수는 , HomepageUrlSignature 필드에 대한 HomeTown데이터베이스 NULL 값을 삽입하는 효과가 있습니다.

브라우저를 EnhancedCreateUserWizard.aspx 통해 페이지를 방문하여 새 사용자 계정을 만듭니다. 이렇게 한 후 Visual Studio로 돌아가서 및 UserProfiles 테이블의 aspnet_Users 내용을 검사합니다(그림 12에서 수행한 것처럼). 에 새 사용자 계정 aspnet_Users 및 해당 UserProfiles 행(NULL, HomepageUrlSignature에 대한 HomeTown값 포함)이 표시됩니다.

새 사용자 계정 및 UserProfiles 레코드가 추가되었습니다.

그림 20: 새 사용자 계정 및 UserProfiles 레코드가 추가되었습니다(전체 크기 이미지를 보려면 클릭).

방문자가 새 계정 정보를 제공하고 "사용자 만들기" 단추를 클릭하면 사용자 계정이 만들어지고 테이블에 행이 UserProfiles 추가됩니다. 그런 다음 CreateUserWizard는 성공 메시지와 계속 단추를 표시하는 을 표시 CompleteWizardStep합니다. 계속 단추를 클릭하면 포스트백이 발생하지만 아무 작업도 수행되지 않고 사용자가 페이지에서 중단됩니다 EnhancedCreateUserWizard.aspx .

CreateUserWizard 컨트롤의 ContinueDestinationPageUrl 속성을 통해 계속 단추를 클릭할 때 사용자를 보낼 URL을 지정할 수 있습니다. ContinueDestinationPageUrl 속성을 "~/Membership/AdditionalUserInfo.aspx"로 설정합니다. 그러면 새 사용자가 로 이동하여 AdditionalUserInfo.aspx설정을 보고 업데이트할 수 있습니다.

CreateUserWizard의 인터페이스를 사용자 지정하여 새 사용자의 홈 타운, 홈페이지 및 서명을 묻는 메시지를 표시합니다.

CreateUserWizard 컨트롤의 기본 인터페이스는 사용자 이름, 암호 및 전자 메일과 같은 핵심 사용자 계정 정보만 수집해야 하는 간단한 계정 만들기 시나리오에 충분합니다. 하지만 계정을 만드는 동안 방문자에게 홈페이지, 홈페이지 및 서명을 입력하라는 메시지를 표시하려면 어떻게 해야 할까요? CreateUserWizard 컨트롤의 인터페이스를 사용자 지정하여 등록 시 추가 정보를 수집할 수 있으며, 이 정보는 이벤트 처리기에서 CreatedUser 기본 데이터베이스에 추가 레코드를 삽입하는 데 사용될 수 있습니다.

CreateUserWizard 컨트롤은 페이지 개발자가 정렬된 WizardSteps일련의 를 정의할 수 있는 컨트롤인 ASP.NET 마법사 컨트롤을 확장합니다. 마법사 컨트롤은 활성 단계를 렌더링하고 방문자가 이러한 단계를 통해 이동할 수 있도록 하는 탐색 인터페이스를 제공합니다. 마법사 컨트롤은 긴 작업을 몇 가지 짧은 단계로 나누는 데 적합합니다. 마법사 컨트롤에 대한 자세한 내용은 ASP.NET 2.0 마법사 컨트롤을 사용하여 단계별 사용자 인터페이스 만들기를 참조하세요.

CreateUserWizard 컨트롤의 기본 태그는 및 CompleteWizardStep의 두 WizardSteps가지를 CreateUserWizardStep 정의합니다.

<asp:CreateUserWizard ID="NewUserWizard" runat="server"
     ContinueDestinationPageUrl="~/Membership/AdditionalUserInfo.aspx">
     <WizardSteps>
          <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server">
          </asp:CreateUserWizardStep>
          <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server">
          </asp:CompleteWizardStep>
     </WizardSteps>
</asp:CreateUserWizard>

첫 번째 WizardStep, 는 CreateUserWizardStep사용자 이름, 암호, 전자 메일 등을 묻는 인터페이스를 렌더링합니다. 방문자가 이 정보를 제공하고 "사용자 만들기"를 클릭하면 성공 메시지와 계속 단추를 보여 주는 가 표시됩니다 CompleteWizardStep.

추가 양식 필드를 포함하도록 CreateUserWizard 컨트롤의 인터페이스를 사용자 지정하려면 다음을 수행할 수 있습니다.

  • 하나 이상의 새WizardStep 만들기추가 사용자 인터페이스 요소를 포함할 수 있습니다. CreateUserWizard에 새 WizardStep 을 추가하려면 스마트 태그에서 "추가/제거 WizardSteps" 링크를 클릭하여 컬렉션 편집기를 시작 WizardStep 합니다. 여기에서 마법사의 단계를 추가, 제거 또는 다시 정렬할 수 있습니다. 이 자습서에 사용할 방법입니다.

  • 다음을 변환합니다.CreateUserWizardStep편집 가능한WizardStep 항목으로. 이렇게 하면 가 CreateUserWizardStepWizardStep 와 일치하는 사용자 인터페이스를 정의하는 해당 태그로 CreateUserWizardStep바뀝니다. 를 로 WizardStep 변환하여 CreateUserWizardStep 컨트롤의 위치를 변경하거나 이 단계에 사용자 인터페이스 요소를 추가할 수 있습니다. 또는 CompleteWizardStepCreateUserWizardStep 편집 가능한 WizardStep로 변환하려면 컨트롤의 스마트 태그에서 "사용자 만들기 단계 사용자 지정" 또는 "완료 단계 사용자 지정" 링크를 클릭합니다.

  • 위의 두 옵션 중 일부 조합을 사용합니다.

유의해야 할 중요한 사항 중 하나는 내에서 "사용자 만들기" 단추를 클릭할 때 CreateUserWizard 컨트롤이 사용자 계정 만들기 프로세스를 실행한다는 것입니다 CreateUserWizardStep. 이후 CreateUserWizardStep 추가 가 있는지 WizardStep 여부는 중요하지 않습니다.

추가 사용자 입력을 수집하기 위해 CreateUserWizard 컨트롤에 사용자 WizardStep 지정을 추가할 때 사용자 지정 WizardStep 을 앞이나 다음에 CreateUserWizardStep배치할 수 있습니다. 앞에 오는 CreateUserWizardStep 경우 사용자 지정 WizardStep 에서 수집된 추가 사용자 입력을 이벤트 처리기에 사용할 수 있습니다 CreatedUser . 그러나 이후에 사용자 지정이 제공 CreateUserWizardStep 되면 사용자 WizardStep 지정 WizardStep 이 표시될 때까지 새 사용자 계정이 이미 생성 CreatedUser 되었으며 이벤트가 이미 발생했습니다.

그림 21은 추가 WizardStep 된 가 앞에 있을 때의 워크플로를 보여 줍니다 CreateUserWizardStep. 이벤트가 발생할 때까지 CreatedUser 추가 사용자 정보가 수집되었으므로 이벤트 처리기를 업데이트 CreatedUser 하여 이러한 입력을 검색하고 문의 매개 변수 값(가 아닌DBNull.Value)에 사용하기만 INSERT 하면 됩니다.

CreateUserWizard 워크플로 추가 마법사가 CreateUserWizardStep 앞에 오는 경우

그림 21: CreateUserWizard 워크플로 앞에 추가 WizardStep 가 있을 CreateUserWizardStep 때(전체 크기 이미지를 보려면 클릭)

그러나 사용자 지정 WizardStep에 배치CreateUserWizardStep된 경우 사용자가 홈페이지, 홈페이지 또는 서명을 입력하기 전에 사용자 계정 만들기 프로세스가 발생합니다. 이러한 경우 그림 22와 같이 사용자 계정을 만든 후에 이 추가 정보를 데이터베이스에 삽입해야 합니다.

CreateUserWizardStep 이후에 추가 마법사가 제공되면 CreateUserWizard 워크플로

그림 22: CreateUserWizard 워크플로 다음에 추가 WizardStep 가 제공 CreateUserWizardStep 되면(전체 크기 이미지를 보려면 클릭)

그림 22에 표시된 워크플로는 2단계가 완료될 때까지 테이블에 레코드를 UserProfiles 삽입할 때까지 기다립니다. 그러나 방문자가 1단계 후에 브라우저를 닫으면 사용자 계정이 만들어졌지만 에 레코드가 추가되지 않은 상태에 도달하게 UserProfiles됩니다. 한 가지 해결 방법은 이벤트 처리기에 또는 기본값이 삽입된 UserProfilesCreatedUser 레코드 NULL 를 이벤트 처리기(1단계 후에 발생)로 지정한 다음, 2단계가 완료된 후 이 레코드를 업데이트하는 것입니다. 이렇게 하면 UserProfiles 사용자가 중간에 등록 프로세스를 종료하더라도 사용자 계정에 대한 레코드가 추가됩니다.

이 자습서에서는 다음에 CreateUserWizardStep 발생하지만 CompleteWizardStep앞에 발생하는 새 WizardStep 를 만들어 보겠습니다. 먼저 WizardStep을 배치하고 구성한 다음 코드를 살펴보겠습니다.

CreateUserWizard 컨트롤의 스마트 태그에서 컬렉션 편집기 대화 상자를 표시하는 WizardStep "추가/제거WizardStep"를 선택합니다. 새 WizardStep를 로 설정하고, 를 Title "사용자 설정"으로, 를 StepTypeStep설정합니다 IDUserSettings. 그런 다음 그림 23과 같이 ("새 계정에 등록") 뒤 CreateUserWizardStep 와 ("완료") 앞에 CompleteWizardStep 오도록 배치합니다.

CreateUserWizard 컨트롤에 새 마법사 추가

그림 23: CreateUserWizard 컨트롤에 새로 WizardStep 만들기 추가(전체 크기 이미지를 보려면 클릭)

확인을 클릭하여 컬렉션 편집기 WizardStep 대화 상자를 닫습니다. 새 WizardStep 는 CreateUserWizard 컨트롤의 업데이트된 선언적 태그에 의해 입증됩니다.

<asp:CreateUserWizard ID="NewUserWizard" runat="server"
     ContinueDestinationPageUrl="~/Membership/AdditionalUserInfo.aspx">
     <WizardSteps>
          <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server">
          </asp:CreateUserWizardStep>
          <asp:WizardStep runat="server" ID="UserSettings" StepType="Step"
               Title="Your Settings">
          </asp:WizardStep>
          <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server">
          </asp:CompleteWizardStep>
     </WizardSteps>
</asp:CreateUserWizard>

<asp:WizardStep> 요소를 확인합니다. 여기에서 새 사용자의 홈페이지, 홈페이지 및 서명을 수집하기 위해 사용자 인터페이스를 추가해야 합니다. 선언적 구문 또는 Designer 통해 이 콘텐츠를 입력할 수 있습니다. Designer 사용하려면 스마트 태그의 드롭다운 목록에서 "설정" 단계를 선택하여 Designer 단계를 확인합니다.

참고

스마트 태그의 드롭다운 목록을 통해 단계를 선택하면 시작 단계의 인덱스를 지정하는 CreateUserWizard 컨트롤의 ActiveStepIndex 속성이 업데이트됩니다. 따라서 이 드롭다운 목록을 사용하여 Designer "설정" 단계를 편집하는 경우 사용자가 페이지를 처음 방문할 EnhancedCreateUserWizard.aspx 때 이 단계가 표시되도록 "새 계정에 등록"으로 다시 설정해야 합니다.

, HomepageUrlSignature라는 HomeTown세 개의 TextBox 컨트롤이 포함된 "사용자 설정" 단계 내에 사용자 인터페이스를 만듭니다. 이 인터페이스를 생성한 후 CreateUserWizard의 선언적 태그는 다음과 유사하게 표시됩니다.

<asp:CreateUserWizard ID="NewUserWizard" runat="server"
     ContinueDestinationPageUrl="~/Membership/AdditionalUserInfo.aspx">
     <WizardSteps>
          <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server">
          </asp:CreateUserWizardStep>
          <asp:WizardStep runat="server" ID="UserSettings" StepType="Step"
               Title="Your Settings">
               <p>
                    <b>Home Town:</b><br />
                    <asp:TextBox ID="HomeTown" runat="server"></asp:TextBox>
               </p>
               <p>
                    <b>Homepage URL:</b><br />
                    <asp:TextBox ID="HomepageUrl" Columns="40" runat="server"></asp:TextBox>
               </p>
               <p>
                    <b>Signature:</b><br />
                    <asp:TextBox ID="Signature" TextMode="MultiLine" Width="95%"
                         Rows="5" runat="server"></asp:TextBox>
               </p>
          </asp:WizardStep>
          <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server">
          </asp:CompleteWizardStep>
     </WizardSteps>
</asp:CreateUserWizard>

브라우저를 통해 이 페이지를 방문하여 홈타운, 홈페이지 및 서명에 대한 값을 지정하는 새 사용자 계정을 만듭니다. 완료한 CreateUserWizardStep 후 사용자 계정은 Membership 프레임워크에서 만들어지고 CreatedUser 이벤트 처리기가 실행되어 에 새 행UserProfiles을 추가하지만 , 및 HomepageUrlSignature에 대한 HomeTown데이터베이스 NULL 값이 있습니다. 홈타운, 홈페이지 및 서명에 입력된 값은 사용되지 않습니다. 순 결과는 , HomepageUrlSignature 필드가 아직 지정되지 않은 HomeTown레코드가 있는 새 사용자 계정 UserProfiles 입니다.

사용자가 입력한 홈타운, honepage 및 서명 값을 가져와 적절한 UserProfiles 레코드를 업데이트하는 "설정" 단계 후에 코드를 실행해야 합니다. 사용자가 마법사 컨트롤의 단계 간에 이동할 때마다 마법사의 ActiveStepChanged 이벤트가 발생합니다. 이 이벤트에 대한 이벤트 처리기를 만들고 "설정" 단계가 UserProfiles 완료되면 테이블을 업데이트할 수 있습니다.

CreateUserWizard의 ActiveStepChanged 이벤트에 대한 이벤트 처리기를 추가하고 다음 코드를 추가합니다.

protected void NewUserWizard_ActiveStepChanged(object sender, EventArgs e)
{
     // Have we JUST reached the Complete step?
     if (NewUserWizard.ActiveStep.Title == "Complete")
     {
          WizardStep UserSettings = NewUserWizard.FindControl("UserSettings") as
          WizardStep;
 
          // Programmatically reference the TextBox controls
          TextBox HomeTown = UserSettings.FindControl("HomeTown") as TextBox;
          TextBox HomepageUrl = UserSettings.FindControl("HomepageUrl") as TextBox;
          TextBox Signature = UserSettings.FindControl("Signature") as TextBox;
 
          // Update the UserProfiles record for this user
          // Get the UserId of the just-added user
          MembershipUser newUser = Membership.GetUser(NewUserWizard.UserName);
          Guid newUserId = (Guid)newUser.ProviderUserKey;
 
          // Insert a new record into UserProfiles
          string connectionString = 
               ConfigurationManager.ConnectionStrings["SecurityTutorialsConnectionString"].ConnectionString;
          string updateSql = "UPDATE UserProfiles SET HomeTown = @HomeTown, HomepageUrl
               = @HomepageUrl, Signature = @Signature WHERE UserId = @UserId";
 
          using (SqlConnection myConnection = new SqlConnection(connectionString))
          {
               myConnection.Open();
               SqlCommand myCommand = new SqlCommand(updateSql, myConnection);
               myCommand.Parameters.AddWithValue("@HomeTown", HomeTown.Text.Trim());
               myCommand.Parameters.AddWithValue("@HomepageUrl", HomepageUrl.Text.Trim());
               myCommand.Parameters.AddWithValue("@Signature", Signature.Text.Trim());
               myCommand.Parameters.AddWithValue("@UserId", newUserId);
               myCommand.ExecuteNonQuery();
               myConnection.Close();
          }
     }
}

위의 코드는 "완료" 단계에 도달했는지 확인하는 것으로 시작합니다. "완료" 단계는 "설정" 단계 직후에 발생하므로 방문자가 "완료" 단계에 도달하면 "설정" 단계를 방금 완료했음을 의미합니다.

이러한 경우 내에서 TextBox 컨트롤 UserSettings WizardStep을 프로그래밍 방식으로 참조해야 합니다. 이 작업은 먼저 메서드를 FindControl 사용하여 프로그래밍 방식으로 를 참조한 UserSettings WizardStep다음, 내에서 WizardStepTextBoxes를 다시 참조하여 수행됩니다. TextBoxes가 참조되면 문을 실행할 UPDATE 준비가 되었습니다. 문은 UPDATE 이벤트 처리기의 문 CreatedUserINSERT 동일한 수의 매개 변수를 가지고 있지만 여기서는 사용자가 제공한 홈 타운, 홈페이지 및 서명 값을 사용합니다.

이 이벤트 처리기가 준비되면 브라우저를 EnhancedCreateUserWizard.aspx 통해 페이지를 방문하여 홈타운, 홈페이지 및 서명에 대한 값을 지정하는 새 사용자 계정을 만듭니다. 새 계정을 만든 후에는 방금 입력한 AdditionalUserInfo.aspx 홈타운, 홈페이지 및 서명 정보가 표시되는 페이지로 리디렉션되어야 합니다.

참고

현재 웹 사이트에는 방문자가 새 계정을 만들 수 있는 두 페이지( 및 EnhancedCreateUserWizard.aspx)가 CreatingUserAccounts.aspx 있습니다. 웹 사이트의 사이트맵 및 로그인 페이지는 페이지를 가리키 CreatingUserAccounts.aspx 지만 CreatingUserAccounts.aspx 페이지는 사용자에게 홈페이지, 홈페이지 및 서명 정보를 묻는 메시지를 표시하지 않으며 에 해당 행 UserProfiles을 추가하지 않습니다. 따라서 이 기능을 제공하도록 페이지를 업데이트 CreatingUserAccounts.aspx 하거나 대신 참조하도록 EnhancedCreateUserWizard.aspxCreatingUserAccounts.aspxsitemap 및 로그인 페이지를 업데이트합니다. 후자 옵션을 선택하는 경우 익명 사용자가 페이지에 액세스할 수 있도록 폴더의 파일을 업데이트 Membership 해야 합니다EnhancedCreateUserWizard.aspx.Web.config

요약

이 자습서에서는 Membership 프레임워크 내의 사용자 계정과 관련된 데이터를 모델링하는 기술을 살펴보았습니다. 특히 일대다 관계를 공유하는 엔터티와 일 대 일 관계를 공유하는 데이터를 살펴보았습니다. 또한 SqlDataSource 컨트롤을 사용하는 몇 가지 예제와 ADO.NET 코드를 사용하는 다른 예제와 함께 이 관련 정보를 표시, 삽입 및 업데이트하는 방법을 알아보았습니다.

이 자습서에서는 사용자 계정 살펴보기 작업을 완료합니다. 다음 자습서부터 역할에 주의를 기울이겠습니다. 다음 몇 가지 자습서에서는 역할 프레임워크를 살펴보고, 새 역할을 만드는 방법, 사용자에게 역할을 할당하는 방법, 사용자가 속한 역할을 결정하는 방법 및 역할 기반 권한 부여를 적용하는 방법을 알아봅니다.

행복한 프로그래밍!

추가 정보

이 자습서에서 설명하는 topics 대한 자세한 내용은 다음 리소스를 참조하세요.

저자 정보

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

특별한 감사...

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 예정된 MSDN 문서를 검토하는 데 관심이 있으신가요? 그렇다면 에 줄을 놓습니다 mitchell@4GuysFromRolla.com.