Przechowywanie dodatkowych informacji dotyczących użytkowników (VB)

Autor: Scott Mitchell

Uwaga

Ponieważ ten artykuł został napisany, dostawcy ASP.NET członkostwa zostały zastąpione przez usługę ASP.NET Identity. Zdecydowanie zalecamy aktualizowanie aplikacji w celu korzystania z platformy ASP.NET Identity , a nie dostawców członkostwa opisanych w tym artykule. ASP.NET Identity ma wiele zalet w systemie członkostwa ASP.NET, w tym :

  • Lepsza wydajność
  • Ulepszona rozszerzalność i możliwość testowania
  • Obsługa uwierzytelniania OAuth, OpenID Connect i uwierzytelniania dwuskładnikowego
  • Obsługa tożsamości opartej na oświadczeniach
  • Lepsza współdziałanie z platformą ASP.Net Core

Pobierz kod lub pobierz plik PDF

W tym samouczku odpowiemy na to pytanie, tworząc bardzo podstawową aplikację elementu gościa. W tym celu przyjrzymy się różnym opcjom modelowania informacji o użytkowniku w bazie danych, a następnie zobaczymy, jak skojarzyć te dane z kontami użytkowników utworzonymi przez platformę członkostwa.

Wprowadzenie

ASP. Platforma członkostwa platformy NET oferuje elastyczny interfejs do zarządzania użytkownikami. Interfejs API członkostwa zawiera metody sprawdzania poprawności poświadczeń, pobierania informacji o aktualnie zalogowanym użytkowniku, tworzeniu nowego konta użytkownika i usuwaniu między innymi konta użytkownika. Każde konto użytkownika w strukturze członkostwa zawiera tylko właściwości wymagane do weryfikacji poświadczeń i wykonywania podstawowych zadań związanych z kontem użytkownika. Jest to dowodem metod i właściwości MembershipUser klasy, które modeluje konto użytkownika w strukturze członkostwa. Ta klasa ma właściwości, takie jak , i , i UnlockUserGetPassword .IsLockedOutEmailUserName

Często aplikacje muszą przechowywać dodatkowe informacje o użytkowniku, które nie są uwzględnione w strukturze członkostwa. Na przykład sprzedawca internetowy może wymagać, aby każdy użytkownik przechowywał swoje adresy wysyłkowe i rozliczeniowe, informacje o płatności, preferencje dostawy i numer telefonu kontaktowego. Ponadto każda kolejność w systemie jest skojarzona z określonym kontem użytkownika.

Klasa MembershipUser nie zawiera właściwości takich jak PhoneNumber lub DeliveryPreferences lub PastOrders. Jak więc śledzić informacje o użytkowniku potrzebne przez aplikację i zintegrować je ze strukturą członkostwa? W tym samouczku odpowiemy na to pytanie, tworząc bardzo podstawową aplikację elementu gościa. W tym celu przyjrzymy się różnym opcjom modelowania informacji o użytkowniku w bazie danych, a następnie zobaczymy, jak skojarzyć te dane z kontami użytkowników utworzonymi przez platformę członkostwa. Zaczynamy!

Krok 1. Tworzenie modelu danych aplikacji elementu gościa

Istnieje wiele technik, które można stosować do przechwytywania informacji o użytkowniku w bazie danych i kojarzenie ich z kontami użytkowników utworzonymi przez platformę członkostwa. Aby zilustrować te techniki, musimy rozszerzyć aplikację internetową samouczka, aby przechwytywać dane związane z użytkownikiem. (Obecnie model danych aplikacji zawiera tylko tabele usług aplikacji wymagane przez SqlMembershipProviderprogram ).

Utwórzmy bardzo prostą aplikację guestbook, w której uwierzytelniony użytkownik może pozostawić komentarz. Oprócz przechowywania komentarzy gościa pozwólmy każdemu użytkownikowi na przechowywanie swojego rodzinnego miasta, strony głównej i podpisu. Jeśli zostanie podana, miasto główne użytkownika, strona główna i podpis pojawią się na każdej wiadomości pozostawionej w podręczniku gościa.

GuestbookCommentsDodawanie tabeli

Aby przechwycić komentarze elementu gościa, musimy utworzyć tabelę bazy danych o nazwie GuestbookComments zawierającą kolumny takie jak CommentId, , Subjecti BodyCommentDate. Musimy również mieć każdy rekord w GuestbookComments tabeli odwołujący się do użytkownika, który opuścił komentarz.

Aby dodać tę tabelę do bazy danych, przejdź do Eksploratora baz danych w programie Visual Studio i przejdź do SecurityTutorials szczegółów bazy danych. Kliknij prawym przyciskiem myszy folder Tabele i wybierz polecenie Dodaj nową tabelę. Spowoduje to wyświetlenie interfejsu, który umożliwia zdefiniowanie kolumn dla nowej tabeli.

Dodawanie nowej tabeli do bazy danych SecurityTutorials

Rysunek 1. Dodawanie nowej tabeli do SecurityTutorials bazy danych (kliknij, aby wyświetlić obraz pełnowymiarowy)

Następnie zdefiniuj GuestbookCommentskolumny .s. Zacznij od dodania kolumny o nazwie CommentId typu uniqueidentifier. Ta kolumna będzie unikatowo identyfikować każdy komentarz w podręczniku gościa, więc nie zezwala NULL i oznacza go jako klucz podstawowy tabeli. Zamiast podać wartość pola dla CommentId każdego INSERTelementu , możemy wskazać, że nowa uniqueidentifier wartość powinna być automatycznie generowana dla tego pola INSERT , ustawiając wartość domyślną kolumny na NEWID(). Po dodaniu tego pierwszego pola, oznaczeniu go jako klucza podstawowego i ustawieniu jego wartości domyślnej ekran powinien wyglądać podobnie do zrzutu ekranu pokazanego na rysunku 2.

Dodawanie kolumny podstawowej o nazwie CommentId

Rysunek 2. Dodawanie kolumny podstawowej o nazwie CommentId (kliknij, aby wyświetlić obraz pełnowymiarowy)

Następnie dodaj kolumnę o nazwie type nvarchar(50) i kolumnę o nazwie BodySubject typu nvarchar(MAX), która nie zezwala NULL na korzystanie z obu kolumn. Następnie dodaj kolumnę o nazwie CommentDate typu datetime. Nie zezwalaj NULL i ustaw wartość domyślną CommentDate kolumny na getdate().

Pozostaje tylko dodać kolumnę, która kojarzy konto użytkownika z każdym komentarzem elementu gościa. Jedną z opcji jest dodanie kolumny o nazwie UserName typu nvarchar(256). Jest to odpowiedni wybór w przypadku korzystania z dostawcy członkostwa innego SqlMembershipProviderniż . Jednak w przypadku korzystania z SqlMembershipProviderelementu , ponieważ znajdujemy się w tej serii samouczków, UserName kolumna w aspnet_Users tabeli nie ma gwarancji unikatowości. Klucz aspnet_Users podstawowy tabeli to UserId i ma typ uniqueidentifier. W związku z tym GuestbookComments tabela potrzebuje kolumny o nazwie UserId typu uniqueidentifier (niedozwolone NULL wartości). Przejdź dalej i dodaj tę kolumnę.

Uwaga

Jak omówiono w samouczku Tworzenie schematu członkostwa w SQL Server, struktura członkostwa została zaprojektowana tak, aby umożliwić wielu aplikacjom internetowym z różnymi kontami użytkowników współużytkowanie tego samego magazynu użytkowników. Robi to przez partycjonowanie kont użytkowników w różnych aplikacjach. I chociaż każda nazwa użytkownika ma gwarancję unikatowości w aplikacji, ta sama nazwa użytkownika może być używana w różnych aplikacjach przy użyciu tego samego magazynu użytkowników. W tabeli i ApplicationIdUserName znajduje się ograniczenie aspnet_Users złożoneUNIQUE, ale nie jedno w poluUserName. W związku z tym istnieje możliwość, aby tabela aspnet_Users miała dwa (lub więcej) rekordy o tej samej UserName wartości. Istnieje jednak UNIQUE ograniczenie w aspnet_Users polu tabeli UserId (ponieważ jest to klucz podstawowy). Ograniczenie UNIQUE jest ważne, ponieważ bez niego nie możemy ustanowić ograniczenia klucza obcego między tabelami GuestbookComments i .aspnet_Users

Po dodaniu kolumny UserId zapisz tabelę, klikając ikonę Zapisz na pasku narzędzi. Nadaj nowej tabeli GuestbookCommentsnazwę .

Mamy ostatni problem, aby uczestniczyć w GuestbookComments tabeli: musimy utworzyć ograniczenie klucza obcego między GuestbookComments.UserId kolumną a kolumną aspnet_Users.UserId . Aby to osiągnąć, kliknij ikonę Relacja na pasku narzędzi, aby uruchomić okno dialogowe Relacje klucza obcego. (Alternatywnie możesz uruchomić to okno dialogowe, przechodząc do menu Tabela Projektant i wybierając pozycję Relacje).

Kliknij przycisk Dodaj w lewym dolnym rogu okna dialogowego Relacje klucza obcego. Spowoduje to dodanie nowego ograniczenia klucza obcego, chociaż nadal musimy zdefiniować tabele, które uczestniczą w relacji.

Zarządzanie ograniczeniami klucza obcego za pomocą okna dialogowego Relacje kluczy obcych tabeli

Rysunek 3. Okno dialogowe Relacje kluczy obcych umożliwia zarządzanie ograniczeniami klucza obcego tabeli (kliknij, aby wyświetlić obraz pełnowymiarowy)

Następnie kliknij ikonę wielokropka w wierszu "Specyfikacje tabel i kolumn" po prawej stronie. Spowoduje to uruchomienie okna dialogowego Tabele i kolumny, z którego możemy określić tabelę klucza podstawowego i kolumnę klucza obcego GuestbookComments z tabeli. W szczególności wybierz aspnet_Users tabelę UserId i kolumnę klucza podstawowego oraz UserId z GuestbookComments tabeli jako kolumnę klucza obcego (zobacz Rysunek 4). Po zdefiniowaniu tabel i kolumn klucza podstawowego i obcego kliknij przycisk OK, aby powrócić do okna dialogowego Relacje kluczy obcych.

Ustanawianie ograniczenia klucza obcego między tabelami aspnet_Users i GuesbookComments

Rysunek 4. Ustanowienie ograniczenia klucza obcego między aspnet_Users tabelami i GuesbookComments (kliknij, aby wyświetlić obraz pełnowymiarowy)

W tym momencie ustanowiono ograniczenie klucza obcego. Obecność tego ograniczenia zapewnia integralność relacyjną między dwiema tabelami, gwarantując, że nigdy nie będzie wpisu elementu gościa odwołującego się do nieistniejącego konta użytkownika. Domyślnie ograniczenie klucza obcego nie zezwala na usunięcie rekordu nadrzędnego, jeśli istnieją odpowiednie rekordy podrzędne. Oznacza to, że jeśli użytkownik tworzy co najmniej jeden komentarz do elementu gościa, a następnie próbujemy usunąć to konto użytkownika, usunięcie zakończy się niepowodzeniem, chyba że jego komentarze do książki gościa zostaną najpierw usunięte.

Ograniczenia klucza obcego można skonfigurować tak, aby automatycznie usuwać skojarzone rekordy podrzędne po usunięciu rekordu nadrzędnego. Innymi słowy, możemy skonfigurować to ograniczenie klucza obcego, aby wpisy elementu gościa użytkownika zostały automatycznie usunięte po usunięciu konta użytkownika. Aby to osiągnąć, rozwiń sekcję "INSERT And UPDATE Specification" (Wstaw i aktualizuj specyfikację) i ustaw właściwość "Usuń regułę" na Kaskadę.

Konfigurowanie ograniczenia klucza obcego do usuwania kaskadowego

Rysunek 5. Konfigurowanie ograniczenia klucza obcego do usuwania kaskadowego (kliknij, aby wyświetlić obraz pełnowymiarowy)

Aby zapisać ograniczenie klucza obcego, kliknij przycisk Zamknij, aby wyjść z relacji klucza obcego. Następnie kliknij ikonę Zapisz na pasku narzędzi, aby zapisać tabelę i tę relację.

Przechowywanie głównego miasta użytkownika, strony głównej i podpisu użytkownika

W GuestbookComments tabeli przedstawiono sposób przechowywania informacji, które współudzielą relację jeden do wielu z kontami użytkowników. Ponieważ każde konto użytkownika może mieć dowolną liczbę skojarzonych komentarzy, ta relacja jest modelowana przez utworzenie tabeli do przechowywania zestawu komentarzy zawierających kolumnę, która łączy każdy komentarz z powrotem do określonego użytkownika. W przypadku korzystania z SqlMembershipProviderelementu ten link najlepiej ustanowić, tworząc kolumnę o nazwie UserId typu uniqueidentifier i ograniczenie klucza obcego między tą kolumną a aspnet_Users.UserId.

Teraz musimy skojarzyć trzy kolumny z każdym kontem użytkownika, aby przechowywać miasto główne, stronę główną i podpis użytkownika, które będą wyświetlane w komentarzach do jego książki gościa. Istnieje wiele różnych sposobów, aby to osiągnąć:

  • Dodawanie nowych kolumn do elementuaspnet_UsersLubaspnet_MembershipTabel. Nie polecam tego podejścia, ponieważ modyfikuje schemat używany przez program SqlMembershipProvider. Ta decyzja może wrócić do nawiedzić cię w dół drogi. Na przykład co zrobić, jeśli przyszła wersja ASP.NET używa innego SqlMembershipProvider schematu. Firma Microsoft może zawierać narzędzie do migrowania danych ASP.NET 2.0 SqlMembershipProvider do nowego schematu, ale jeśli zmodyfikowano schemat ASP.NET 2.0 SqlMembershipProvider , taka konwersja może nie być możliwa.

  • Użyj platformy ASP. Struktura profilu platformy NET, definiująca właściwość profilu dla rodzinnego miasta, strony głównej i podpisu. ASP.NET zawiera strukturę profilów przeznaczoną do przechowywania dodatkowych danych specyficznych dla użytkownika. Podobnie jak w przypadku struktury członkostwa, platforma Profilu jest zbudowana na szczycie modelu dostawcy. .NET Framework jest dostarczany z elementem SqlProfileProvider , który przechowuje dane profilów w bazie danych SQL Server. W rzeczywistości nasza baza danych zawiera już tabelę używaną przez SqlProfileProvider element (aspnet_Profile), ponieważ została dodana podczas dodawania usług aplikacji z powrotem w samouczku Tworzenie schematu członkostwa w SQL Server.
    Główną zaletą struktury profilów jest umożliwienie deweloperom definiowania właściwości profilu w Web.config programie — nie trzeba zapisywać kodu w celu serializacji danych profilu do i z bazowego magazynu danych. Krótko mówiąc, bardzo łatwo jest zdefiniować zestaw właściwości profilu i pracować z nimi w kodzie. Jednak system profilów pozostawia wiele do życzenia, jeśli chodzi o przechowywanie wersji, więc jeśli masz aplikację, w której oczekujesz, że nowe właściwości specyficzne dla użytkownika zostaną dodane w późniejszym czasie lub istniejące do usunięcia lub zmodyfikowania, wówczas struktura profilu może nie być najlepszą opcją. Ponadto SqlProfileProvider obiekt przechowuje właściwości profilu w sposób wysoce zdenormalizowany, dzięki czemu nie można uruchamiać zapytań bezpośrednio względem danych profilu (takich jak liczba użytkowników, którzy mają miasto domowe w Nowym Jorku).
    Aby uzyskać więcej informacji na temat struktury profilów, zapoznaj się z sekcją "Dalsze informacje" na końcu tego samouczka.

  • Dodaj te trzy kolumny do nowej tabeli w bazie danych i ustanów relację jeden do jednego między tą tabelą aaspnet_Users. Takie podejście wymaga nieco większej pracy niż w przypadku struktury profilów, ale zapewnia maksymalną elastyczność w sposobie modelowania dodatkowych właściwości użytkownika w bazie danych. Jest to opcja, która zostanie użyta w tym samouczku.

Utworzymy nową tabelę o nazwie UserProfiles , aby zapisać miasto domowe, stronę główną i podpis dla każdego użytkownika. Kliknij prawym przyciskiem myszy folder Tables w oknie Eksplorator bazy danych i wybierz opcję utworzenia nowej tabeli. Nazwij pierwszą kolumnę UserId i ustaw jej typ na uniqueidentifier. Nie zezwalaj NULL na wartości i oznaczaj kolumnę jako klucz podstawowy. Następnie dodaj kolumny o nazwie: HomeTown typu ; HomepageUrl typu nvarchar(50)nvarchar(100); i Podpis typu nvarchar(500). Każda z tych trzech kolumn może akceptować NULL wartość.

Tworzenie tabeli UserProfiles

Rysunek 6. Tworzenie UserProfiles tabeli (kliknij, aby wyświetlić obraz pełnowymiarowy)

Zapisz tabelę i nadaj jej UserProfilesnazwę . Na koniec ustanów ograniczenie klucza obcego między UserProfiles polem tabeli UserId a polem aspnet_Users.UserId . Podobnie jak w przypadku ograniczenia klucza obcego między GuestbookComments tabelami i aspnet_Users , należy usunąć to ograniczenie kaskadowe. UserId Ponieważ pole w UserProfiles pliku jest kluczem podstawowym, gwarantuje to, że w tabeli nie będzie więcej niż jeden rekord UserProfiles dla każdego konta użytkownika. Ten typ relacji jest określany jako jeden do jednego.

Teraz, gdy mamy utworzony model danych, możemy go używać. W krokach 2 i 3 przyjrzymy się, jak aktualnie zalogowany użytkownik może wyświetlać i edytować swoje miasto domowe, stronę główną i informacje o podpisie. W kroku 4 utworzymy interfejs dla uwierzytelnionych użytkowników w celu przesyłania nowych komentarzy do elementu guestbook i wyświetlania istniejących.

Krok 2. Wyświetlanie głównego miasta użytkownika, strony głównej i podpisu

Istnieje wiele sposobów, aby umożliwić aktualnie zalogowanym użytkownikowi wyświetlanie i edytowanie jego rodzinnego miasta, strony głównej i informacji o podpisie. Możemy ręcznie utworzyć interfejs użytkownika za pomocą kontrolek TextBox i Label lub użyć jednej z kontrolek sieci Web danych, takich jak kontrolka DetailsView. Aby wykonać bazę danych SELECT i UPDATE instrukcje, możemy napisać ADO.NET kod w klasie za pomocą kodu naszej strony lub, alternatywnie, zastosować podejście deklaratywne w usłudze SqlDataSource. Najlepiej, aby nasza aplikacja zawierała architekturę warstwową, którą można wywołać programowo z klasy za pomocą kodu strony lub deklaratywnie za pośrednictwem kontrolki ObjectDataSource.

Ponieważ ta seria samouczków koncentruje się na uwierzytelnianiu formularzy, autoryzacji, kontach użytkowników i rolach, nie będzie szczegółowej dyskusji na temat tych różnych opcji dostępu do danych ani dlaczego architektura warstwowa jest preferowana w przypadku wykonywania instrukcji SQL bezpośrednio ze strony ASP.NET. Przejdę przez proces korzystania z elementów DetailsView i SqlDataSource — najszybszej i najłatwiejszej opcji — ale omówione koncepcje z pewnością można zastosować do alternatywnych mechanizmów kontroli sieci Web i logiki dostępu do danych. Aby uzyskać więcej informacji na temat pracy z danymi w ASP.NET, zapoznaj się z serią samouczków Praca z danymi w ASP.NET 2.0 .

AdditionalUserInfo.aspx Otwórz stronę w folderze Membership i dodaj kontrolkę DetailsView do strony, ustawiając jej właściwość ID na UserProfile i usuwając jej Width właściwości i Height . Rozwiń tag inteligentny kontrolki DetailsView i wybierz powiązanie go z nową kontrolką źródła danych. Spowoduje to uruchomienie Kreatora konfiguracji źródła danych (zobacz Rysunek 7). Pierwszy krok wymaga określenia typu źródła danych. Ponieważ połączymy się bezpośrednio z bazą SecurityTutorials danych, wybierz ikonę Baza danych, określając parametr ID jako UserProfileDataSource.

Dodawanie nowej kontrolki SqlDataSource o nazwie UserProfileDataSource

Rysunek 7. Dodawanie nowej kontrolki SqlDataSource o nazwie UserProfileDataSource (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Następny ekran wyświetla monit o użycie bazy danych. Zdefiniowaliśmy już parametry połączenia dla Web.configSecurityTutorials bazy danych. Ta parametry połączenia nazwa — SecurityTutorialsConnectionString powinna znajdować się na liście rozwijanej. Wybierz tę opcję i kliknij przycisk Dalej.

Wybierz pozycję SecurityTutorialsConnectionString z listy Drop-Down

Rysunek 8. Wybieranie SecurityTutorialsConnectionString z listy Drop-Down (kliknij, aby wyświetlić obraz pełnowymiarowy)

Na kolejnym ekranie zostanie wyświetlony monit o określenie tabeli i kolumn do zapytania. Wybierz tabelę UserProfiles z listy rozwijanej i sprawdź wszystkie kolumny.

Przywrócenie wszystkich kolumn z tabeli UserProfiles

Rysunek 9. Przywrócenie wszystkich kolumn z UserProfiles tabeli (kliknij, aby wyświetlić obraz pełnowymiarowy)

Bieżące zapytanie na rysunku 9 zwraca wszystkie rekordy w UserProfileselemencie , ale interesuje nas tylko rekord aktualnie zalogowanego użytkownika. Aby dodać klauzulę WHERE , kliknij WHERE przycisk, aby wyświetlić okno dialogowe Dodawanie WHERE klauzuli (zobacz Rysunek 10). W tym miejscu możesz wybrać kolumnę do filtrowania, operator i źródło parametru filtru. Wybierz UserId jako kolumnę i "=" jako operator.

Niestety nie ma wbudowanego źródła parametrów, aby zwrócić wartość aktualnie zalogowanego użytkownika UserId . Będziemy musieli chwycić tę wartość programowo. W związku z tym ustaw listę rozwijaną Źródło na wartość "Brak", kliknij przycisk Dodaj, aby dodać parametr, a następnie kliknij przycisk OK.

Dodawanie parametru filtru w kolumnie UserId

Rysunek 10. Dodawanie parametru filtru w kolumnie UserId (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Po kliknięciu przycisku OK nastąpi powrót do ekranu pokazanego na rysunku 9. Tym razem jednak zapytanie SQL w dolnej części ekranu powinno zawierać klauzulę WHERE . Kliknij przycisk Dalej, aby przejść do ekranu "Zapytanie testowe". W tym miejscu możesz uruchomić zapytanie i wyświetlić wyniki. Kliknij przycisk Zakończ, aby zakończyć kreatora.

Po ukończeniu pracy Kreatora konfiguracji źródła danych program Visual Studio tworzy kontrolkę SqlDataSource na podstawie ustawień określonych w kreatorze. Ponadto ręcznie dodaje element BoundFields do kontrolki DetailsView dla każdej kolumny zwróconej SelectCommandprzez element SqlDataSource. Nie ma potrzeby wyświetlania UserId pola w widoku DetailsView, ponieważ użytkownik nie musi znać tej wartości. To pole można usunąć bezpośrednio z tagu deklaratywnego kontrolki DetailsView lub klikając link "Edytuj pola" z tagu inteligentnego.

Na tym etapie znaczniki deklaratywne strony powinny wyglądać podobnie do następujących:

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

Przed wybraniem danych należy programowo ustawić parametr kontrolki UserId SqlDataSource na aktualnie zalogowanego użytkownika UserId . Można to zrobić, tworząc procedurę obsługi zdarzeń dla zdarzenia sqlDataSource Selecting i dodając w nim następujący kod:

Protected Sub UserProfileDataSource_Selecting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceSelectingEventArgs) Handles UserProfileDataSource.Selecting
     ' Get a reference to the currently logged on user
     Dim currentUser As MembershipUser = Membership.GetUser()

     ' Determine the currently logged on user's UserId value
     Dim currentUserId As Guid = CType(currentUser.ProviderUserKey, Guid)

     ' Assign the currently logged on user's UserId to the @UserId parameter
     e.Command.Parameters("@UserId").Value = currentUserId
End Sub

Powyższy kod rozpoczyna się od uzyskania odwołania do aktualnie zalogowanego użytkownika przez wywołanie Membership metody klasy GetUser . Spowoduje to zwrócenie MembershipUser obiektu, którego ProviderUserKey właściwość zawiera UserIdobiekt . Wartość UserId jest następnie przypisywana do parametru @UserId sqlDataSource.

Uwaga

Metoda Membership.GetUser() zwraca informacje o aktualnie zalogowanym użytkowniku. Jeśli anonimowy użytkownik odwiedza stronę, zwróci wartość Nothing. W takim przypadku spowoduje to wywołanie NullReferenceException obiektu w następującym wierszu kodu podczas próby odczytania ProviderUserKey właściwości. Oczywiście nie musimy martwić się o Membership.GetUser() zwracanie wartości Nothing na AdditionalUserInfo.aspx stronie, ponieważ skonfigurowaliśmy autoryzację adresu URL w poprzednim samouczku, aby tylko uwierzytelnieni użytkownicy mogli uzyskiwać dostęp do zasobów ASP.NET w tym folderze. Jeśli musisz uzyskać dostęp do informacji o aktualnie zalogowanym użytkowniku na stronie, na której dozwolony jest dostęp anonimowy, upewnij się, że MembershipUser obiekt zwrócony z GetUser() metody nie ma wartości Nic przed odwoływaniem się do jego właściwości.

Jeśli odwiedzisz AdditionalUserInfo.aspx stronę za pośrednictwem przeglądarki, zobaczysz pustą stronę, ponieważ nie dodaliśmy jeszcze żadnych wierszy do UserProfiles tabeli. W kroku 6 przyjrzymy się, jak dostosować kontrolkę CreateUserWizard, aby automatycznie dodać nowy wiersz do tabeli po utworzeniu UserProfiles nowego konta użytkownika. Na razie jednak musimy ręcznie utworzyć rekord w tabeli.

Przejdź do Eksploratora baz danych w programie Visual Studio i rozwiń folder Tables. Kliknij prawym przyciskiem myszy tabelę aspnet_Users i wybierz polecenie "Pokaż dane tabeli", aby wyświetlić rekordy w tabeli. Wykonaj te same czynności dla UserProfiles tabeli. Rysunek 11 przedstawia te wyniki w przypadku kafelków w pionie. W mojej bazie danych istnieją obecnie aspnet_Users rekordy dla Bruce'a, Freda i Tito, ale w tabeli nie ma żadnych rekordów UserProfiles .

Zawartość tabel aspnet_Users i UserProfiles jest wyświetlana

Rysunek 11. Zawartość aspnet_Users tabel i UserProfiles tabel jest wyświetlana (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Dodaj nowy rekord do UserProfiles tabeli, ręcznie wpisując wartości dla HomeTownpól , HomepageUrli Signature . Najprostszym sposobem uzyskania prawidłowej UserId wartości w nowym UserProfiles rekordzie jest wybranie UserId pola z określonego konta użytkownika w aspnet_Users tabeli i skopiowanie i wklejenie go do UserId pola w UserProfilespliku . Rysunek 12 przedstawia tabelę UserProfiles po dodaniu nowego rekordu dla Bruce'a.

Rekord został dodany do elementu UserProfiles dla Bruce'a

Rysunek 12. Dodano rekord dla UserProfiles Bruce'a (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Wróć do elementu AdditionalUserInfo.aspx page, zalogowanego jako Bruce. Jak pokazano na rysunku 13, ustawienia Bruce'a są wyświetlane.

Aktualnie odwiedzający użytkownik jest wyświetlany jego ustawienia

Rysunek 13. Aktualnie odwiedzający użytkownik jest wyświetlany jego ustawienia (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Uwaga

Przejdź dalej i ręcznie dodaj rekordy w UserProfiles tabeli dla każdego użytkownika członkostwa. W kroku 6 przyjrzymy się, jak dostosować kontrolkę CreateUserWizard, aby automatycznie dodać nowy wiersz do tabeli po utworzeniu UserProfiles nowego konta użytkownika.

Krok 3. Zezwolenie użytkownikowi na edytowanie swojego rodzinnego miasta, strony głównej i podpisu

W tym momencie zalogowany użytkownik może wyświetlać swoje miasto domowe, stronę główną i ustawienie podpisu, ale nie może jeszcze ich modyfikować. Zaktualizujmy kontrolkę DetailsView, aby można było edytować dane.

Pierwszą rzeczą, którą musimy zrobić, jest dodanie UpdateCommand elementu dla elementu SqlDataSource, określając instrukcję UPDATE do wykonania i odpowiadające jej parametry. Wybierz pozycję SqlDataSource i w okno Właściwości kliknij wielokropek obok właściwości UpdateQuery, aby wyświetlić okno dialogowe Redaktor polecenia i parametru. Wprowadź następującą UPDATE instrukcję w polu tekstowym:

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

Następnie kliknij przycisk "Odśwież parametry", który utworzy parametr w kolekcji kontrolki UpdateParameters SqlDataSource dla każdego z parametrów w instrukcji UPDATE . Pozostaw źródło dla wszystkich parametrów ustawionych na Wartość Brak, a następnie kliknij przycisk OK, aby ukończyć okno dialogowe.

Określanie parametrów UpdateCommand i UpdateParameters elementu SqlDataSource

Rysunek 14. Określanie elementów SqlDataSource UpdateCommand i UpdateParameters (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Ze względu na dodatki wprowadzone do kontrolki SqlDataSource kontrolka DetailsView może teraz obsługiwać edycję. W tagu inteligentnym kontrolki DetailsView zaznacz pole wyboru "Włącz edytowanie". Spowoduje to dodanie pola commandfield do kolekcji kontrolki Fields z jej ShowEditButton właściwością ustawioną na true. Spowoduje to renderowanie przycisku Edytuj, gdy kontrolka DetailsView jest wyświetlana w trybie tylko do odczytu, a przyciski Aktualizuj i Anuluj są wyświetlane w trybie edycji. Zamiast wymagać od użytkownika kliknięcia przycisku Edytuj, możemy jednak wyrenderować element DetailsView w stanie "zawsze edytowalny", ustawiając właściwość kontrolki DefaultMode DetailsView na Editwartość .

Po wprowadzeniu tych zmian znacznik deklaratywny kontrolki DetailsView powinien wyglądać podobnie do następującego:

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

Zwróć uwagę na dodanie pola CommandField i DefaultMode właściwości .

Przejdź dalej i przetestuj tę stronę za pośrednictwem przeglądarki. Podczas odwiedzania użytkownika, który ma odpowiedni rekord w UserProfilesprogramie , ustawienia użytkownika są wyświetlane w edytowalnym interfejsie.

Kontrolka DetailsView renderuje interfejs edytowalny

Rysunek 15. Widok Szczegółów renderuje interfejs edytowalny (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Spróbuj zmienić wartości i kliknąć przycisk Aktualizuj. Wygląda na to, że nic się nie dzieje. Istnieje ogłaszanie zwrotne i wartości są zapisywane w bazie danych, ale nie ma żadnych wizualnych opinii, że zapis wystąpił.

Aby rozwiązać ten problem, wróć do programu Visual Studio i dodaj kontrolkę Etykieta nad kontrolką DetailsView. Ustaw jej ID właściwość na SettingsUpdatedMessage, Text na wartość "Ustawienia zostały zaktualizowane", a jej Visible właściwości i EnableViewState na Falsewartość .

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

Musimy wyświetlić etykietę SettingsUpdatedMessage za każdym razem, gdy element DetailsView zostanie zaktualizowany. Aby to osiągnąć, utwórz procedurę obsługi zdarzeń dla zdarzenia kontrolki ItemUpdated DetailsView i dodaj następujący kod:

Protected Sub UserProfile_ItemUpdated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewUpdatedEventArgs) Handles UserProfile.ItemUpdated
     SettingsUpdatedMessage.Visible = True
End Sub

Wróć do AdditionalUserInfo.aspx strony za pośrednictwem przeglądarki i zaktualizuj dane. Tym razem zostanie wyświetlony pomocny komunikat o stanie.

Po zaktualizowaniu ustawień zostanie wyświetlony krótki komunikat

Rysunek 16. Po zaktualizowaniu ustawień jest wyświetlany krótki komunikat (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Uwaga

Interfejs edycji kontrolki DetailsView pozostawia wiele do życzenia. Używa ona standardowych pól tekstowych, ale pole Signature powinno być prawdopodobnie polem tekstowym wielowierszowym. Należy użyć elementu RegularExpressionValidator, aby upewnić się, że wprowadzony adres URL strony głównej zaczyna się od "http://" lub "https://". Ponadto, ponieważ kontrolka DetailsView ma jej DefaultMode właściwość ustawioną na Edit, przycisk Anuluj nie wykonuje żadnych czynności. Należy go usunąć lub, po kliknięciu, przekierować użytkownika do innej strony (na przykład ~/Default.aspx). Zostawię te ulepszenia jako ćwiczenie dla czytelnika.

Obecnie witryna internetowa nie udostępnia żadnych linków do AdditionalUserInfo.aspx strony. Jedynym sposobem na dotarcie do niego jest wprowadzenie adresu URL strony bezpośrednio na pasku adresu przeglądarki. Dodajmy link do tej strony na stronie wzorcowej Site.master .

Pamiętaj, że strona wzorcowa zawiera kontrolkę internetową Kontrolka LoginView w elemecie LoginContent ContentPlaceHolder, która wyświetla różne znaczniki dla uwierzytelnionych i anonimowych osób odwiedzających. Zaktualizuj kontrolkę LoggedInTemplate LoginView, aby zawierała link do AdditionalUserInfo.aspx strony. Po wprowadzeniu tych zmian znacznik deklaratywny kontrolki LoginView powinien wyglądać podobnie do następującego:

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

Zwróć uwagę na dodanie kontrolki lnkUpdateSettings HyperLink do .LoggedInTemplate Dzięki temu linkowi uwierzytelnieni użytkownicy mogą szybko przejść do strony, aby wyświetlić i zmodyfikować ustawienia swojego rodzinnego miasta, strony głównej i podpisu.

Krok 4. Dodawanie nowych komentarzy do elementu guestbook

Strona to miejsce, na Guestbook.aspx którym uwierzytelnieni użytkownicy mogą wyświetlać książkę gościa i pozostawiać komentarz. Zacznijmy od utworzenia interfejsu w celu dodania nowych komentarzy do podręcznika gościa.

Guestbook.aspx Otwórz stronę w programie Visual Studio i skonstruuj interfejs użytkownika składający się z dwóch kontrolek TextBox: jeden dla tematu nowego komentarza i jeden dla jego treści. Ustaw właściwość pierwszego kontrolki TextBox na Subject wartość i jej Columns właściwość na 40; ustaw dla sekundy BodyID wartość , jej TextModeMultiLinewłaściwość na , a jej Width właściwości na Rows wartość "95%" i 8.ID Aby ukończyć interfejs użytkownika, dodaj kontrolkę Sieć Web przycisku o nazwie PostCommentButton i ustaw jej Text właściwość na "Opublikuj komentarz".

Ponieważ każdy komentarz elementu gościa wymaga tematu i treści, dodaj element RequiredFieldValidator dla każdego elementu TextBoxes. ValidationGroup Ustaw właściwość tych kontrolek na "EnterComment", podobnie ustaw PostCommentButton właściwość kontrolki ValidationGroup na "EnterComment". Aby uzyskać więcej informacji na temat platformy ASP. Kontrolki walidacji platformy NET można sprawdzić w ASP.NET sprawdzania poprawności formularza.

Po zakończeniu tworzenia interfejsu użytkownika znacznik deklaratywny strony powinien wyglądać podobnie do następującego:

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

Po zakończeniu pracy interfejsu użytkownika następnym zadaniem jest wstawienie nowego rekordu GuestbookComments do tabeli po kliknięciu PostCommentButton . Można to osiągnąć na wiele sposobów: możemy napisać kod ADO.NET w procedurze obsługi zdarzeń przyciskuClick. Możemy dodać kontrolkę SqlDataSource do strony, skonfigurować jej InsertCommandmetodę , a następnie wywołać jej Insert metodę z Click programu obsługi zdarzeń. Możemy też utworzyć warstwę środkową, która była odpowiedzialna za wstawianie komentarzy nowego elementu gościa i wywołać tę funkcję z Click programu obsługi zdarzeń. Ponieważ przyjrzeliśmy się używaniu elementu SqlDataSource w kroku 3, użyjmy tutaj kodu ADO.NET.

Uwaga

Klasy ADO.NET używane do programowego uzyskiwania dostępu do danych z bazy danych microsoft SQL Server znajdują się w System.Data.SqlClient przestrzeni nazw. Może być konieczne zaimportowanie tej przestrzeni nazw do klasy kodowej strony (tj. Imports System.Data.SqlClient).

Utwórz procedurę obsługi zdarzeń dla PostCommentButtonzdarzenia i Click dodaj następujący kod:

Protected Sub PostCommentButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles PostCommentButton.Click
     If Not Page.IsValid Then Exit Sub

     ' Determine the currently logged on user's UserId
     Dim currentUser As MembershipUser = Membership.GetUser()
     Dim currentUserId As Guid = CType(currentUser.ProviderUserKey, Guid)

     ' Insert a new record into GuestbookComments
     Dim connectionString As String = 
          ConfigurationManager.ConnectionStrings("SecurityTutorialsConnectionString").ConnectionString
     Dim insertSql As String = "INSERT INTO GuestbookComments(Subject, Body, UserId)
          VALUES(@Subject, @Body, @UserId)"

     Using myConnection As New SqlConnection(connectionString)

          myConnection.Open()
          Dim myCommand As 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()
     End Using

     ' "Reset" the Subject and Body TextBoxes

     Subject.Text = String.Empty
     Body.Text = String.Empty
End Sub

Procedura Click obsługi zdarzeń rozpoczyna się od sprawdzenia, czy dane dostarczone przez użytkownika są prawidłowe. Jeśli tak nie jest, program obsługi zdarzeń kończy działanie przed wstawieniem rekordu. Przy założeniu, że podane dane są prawidłowe, wartość aktualnie zalogowanego użytkownika UserId jest pobierana i przechowywana w zmiennej currentUserId lokalnej. Ta wartość jest potrzebna, ponieważ musimy podać UserId wartość podczas wstawiania rekordu do GuestbookCommentselementu .

Następnie jest pobierana parametry połączenia dla SecurityTutorials bazy danych, a instrukcja SQL jest określonaINSERT.Web.config Następnie SqlConnection tworzony i otwierany jest obiekt. SqlCommand Następnie jest tworzony obiekt, a wartości parametrów używanych w INSERT zapytaniu są przypisywane. Instrukcja INSERT jest następnie wykonywana, a połączenie zostało zamknięte. Na końcu procedury obsługi zdarzeń właściwości i Body TextBoxes Text są czyszczone, Subject aby wartości użytkownika nie zostały utrwalone po zakończeniu ogłaszania zwrotnego.

Przejdź dalej i przetestuj tę stronę w przeglądarce. Ponieważ ta strona znajduje się w folderze Membership , nie jest dostępna dla anonimowych osób odwiedzających. W związku z tym należy najpierw zalogować się (jeśli jeszcze tego nie zrobiono). Wprowadź wartość w polach Subject TextBoxes i Body kliknij PostCommentButton przycisk . Spowoduje to dodanie nowego rekordu do elementu GuestbookComments. W przypadku ogłaszania zwrotnego podany temat i treść są czyszczone z textBoxes.

Po kliknięciu PostCommentButton przycisku nie ma żadnych wizualnych opinii, że komentarz został dodany do elementu guestbook. Nadal musimy zaktualizować tę stronę, aby wyświetlić istniejące komentarze do podręcznika gościa, które wykonamy w kroku 5. Po osiągnięciu tego celu na liście komentarzy zostanie wyświetlony właśnie dodany komentarz, zapewniając odpowiednią opinię wizualną. Na razie upewnij się, że komentarz do elementu guestbook został zapisany, sprawdzając zawartość GuestbookComments tabeli.

Rysunek 17 przedstawia zawartość tabeli po pozostawieniu GuestbookComments dwóch komentarzy.

Komentarze do elementów guestbook są widoczne w tabeli GuestbookComments

Rysunek 17. Komentarze elementów gościa można zobaczyć w GuestbookComments tabeli (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Jeśli użytkownik spróbuje wstawić komentarz do elementu guestbook, który zawiera potencjalnie niebezpieczne znaczniki — takie jak HTML — ASP.NET zgłosi błąd HttpRequestValidationException. Aby dowiedzieć się więcej na temat tego wyjątku, dlaczego jest on zgłaszany i jak zezwolić użytkownikom na przesyłanie potencjalnie niebezpiecznych wartości, zapoznaj się z oficjalnym dokumentem dotyczącym weryfikacji żądań.

Krok 5. Wyświetlanie listy istniejących komentarzy do podręcznika gościa

Oprócz pozostawiania komentarzy użytkownik odwiedzający Guestbook.aspx stronę powinien również mieć możliwość wyświetlania istniejących komentarzy elementu gościa. Aby to osiągnąć, dodaj kontrolkę ListView o nazwie CommentList na dole strony.

Uwaga

Kontrolka ListView jest nowym elementem ASP.NET w wersji 3.5. Jest ona przeznaczona do wyświetlania listy elementów w bardzo dostosowywalnym i elastycznym układzie, ale nadal oferuje wbudowane funkcje edytowania, wstawiania, usuwania, stronicowania i sortowania, takich jak GridView. Jeśli używasz ASP.NET 2.0, musisz zamiast tego użyć kontrolki DataList lub Repeater. Aby uzyskać więcej informacji na temat korzystania z kontrolki ListView, zobacz wpis w blogu Scotta Guthrie, kontrolka asp:ListView i artykuł Wyświetlanie danych za pomocą kontrolki ListView.

Otwórz tag inteligentny elementu ListView i z listy rozwijanej Wybierz źródło danych powiąż kontrolkę z nowym źródłem danych. Jak pokazano w kroku 2, spowoduje to uruchomienie Kreatora konfiguracji źródła danych. Wybierz ikonę Baza danych, nadaj wynikowej nazwie sqlDataSource CommentsDataSource, a następnie kliknij przycisk OK. Następnie wybierz SecurityTutorialsConnectionString parametry połączenia z listy rozwijanej i kliknij przycisk Dalej.

W tym momencie w kroku 2 określiliśmy dane do zapytania, wybierając UserProfiles tabelę z listy rozwijanej i wybierając kolumny do zwrócenia (wróć do rysunku 9). Tym razem jednak chcemy utworzyć instrukcję SQL, która ściąga nie tylko rekordy z GuestbookComments, ale także do rodzinnego miasta komentatora, strony głównej, podpisu i nazwy użytkownika. W związku z tym wybierz przycisk radiowy "Określ niestandardową instrukcję SQL lub procedurę składowaną", a następnie kliknij przycisk Dalej.

Spowoduje to wyświetlenie ekranu "Definiowanie instrukcji niestandardowych lub procedur składowanych". Kliknij przycisk Konstruktor zapytań, aby graficznie skompilować zapytanie. Konstruktor zapytań rozpoczyna się od monitowania o określenie tabel, z których chcemy wykonać zapytanie. Wybierz tabele GuestbookComments, UserProfilesi aspnet_Users i kliknij przycisk OK. Spowoduje to dodanie wszystkich trzech tabel do powierzchni projektowej. Ponieważ istnieją ograniczenia klucza obcego GuestbookCommentsmiędzy tabelami , UserProfilesi aspnet_Users , konstruktor zapytań automatycznie JOIN podsyła te tabele.

Pozostaje tylko określić kolumny, które mają być zwracane. GuestbookComments W tabeli wybierz Subjectkolumny , Bodyi , a CommentDate następnie zwróć HomeTownkolumny , HomepageUrli Signature z UserProfilesaspnet_Userstabeli .UserName Dodaj również element "ORDER BY CommentDate DESC" na końcu SELECT zapytania, tak aby najnowsze wpisy zostały zwrócone jako pierwsze. Po wybraniu tych opcji interfejs konstruktora zapytań powinien wyglądać podobnie do zrzutu ekranu na rysunku 18.

Skonstruowane elementy JOIN zapytania są tworzone przez elementy guestbookComments, UserProfiles i tabele aspnet_Users

Rysunek 18. Skonstruowane zapytanie JOIN zawiera GuestbookCommentstabele , UserProfilesi aspnet_Users (kliknij, aby wyświetlić obraz pełnowymiarowy)

Kliknij przycisk OK, aby zamknąć okno Konstruktora zapytań i wrócić do ekranu "Definiowanie instrukcji niestandardowych lub procedur składowanych". Kliknij przycisk Dalej, aby przejść do ekranu "Zapytanie testowe", na którym można wyświetlić wyniki zapytania, klikając przycisk Testuj zapytanie. Gdy wszystko będzie gotowe, kliknij przycisk Zakończ, aby ukończyć pracę kreatora Konfigurowanie źródła danych.

Po zakończeniu pracy Kreatora konfigurowania źródła danych w kroku 2 skojarzona kolekcja kontrolki Fields DetailsView została zaktualizowana w celu uwzględnienia pola BoundField dla każdej kolumny zwróconej przez SelectCommandelement . Jednak widok ListView pozostaje niezmieniony; Nadal musimy zdefiniować jego układ. Układ obiektu ListView można utworzyć ręcznie za pomocą narzutu deklaratywnego lub z opcji "Konfiguruj widok ListView" w tagu inteligentnym. Zwykle preferuję definiowanie znaczników ręcznie, ale używaj dowolnej metody, która jest dla Ciebie najbardziej naturalna.

Skończyło się na użyciu następujących LayoutTemplateelementów , ItemTemplatei ItemSeparatorTemplate dla mojej kontrolki ListView:

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

Element LayoutTemplate definiuje znaczniki emitowane przez kontrolkę, podczas gdy ItemTemplate renderuje każdy element zwrócony przez element SqlDataSource. Wynikowy ItemTemplateadiustacja jest umieszczana w kontrolce LayoutTemplate. itemPlaceholder . Oprócz elementu itemPlaceholderLayoutTemplate element zawiera kontrolkę DataPager, która ogranicza widok ListView do wyświetlania tylko 10 komentarzy elementów gości na stronę (ustawienie domyślne) i renderuje interfejs stronicowania.

Mój ItemTemplate wyświetla temat każdego komentarza elementu gościa w elemecie <h4> z treścią znajdującą się poniżej tematu. Zwróć uwagę, że składnia używana do wyświetlania treści pobiera dane zwracane przez Eval("Body") instrukcję powiązania danych, konwertuje je na ciąg i zastępuje podziały wierszy elementem <br /> . Ta konwersja jest wymagana w celu pokazania podziałów wierszy wprowadzonych podczas przesyłania komentarza, ponieważ biały znak jest ignorowany przez kod HTML. Podpis użytkownika jest wyświetlany pod treścią kursywy, a następnie miasto domowe użytkownika, link do jego strony głównej, data i godzina komentarza oraz nazwa użytkownika osoby, która opuściła komentarz.

Poświęć chwilę, aby wyświetlić stronę za pośrednictwem przeglądarki. Komentarze dodane do elementu guestbook powinny zostać wyświetlone w kroku 5.

Guestbook.aspx teraz wyświetla komentarze elementu gościa

Rysunek 19. Guestbook.aspx Teraz wyświetla komentarze elementu gościa (kliknij, aby wyświetlić obraz pełnowymiarowy)

Spróbuj dodać nowy komentarz do elementu guestbook. Po kliknięciu PostCommentButton przycisku strona publikuje z powrotem i komentarz jest dodawany do bazy danych, ale kontrolka ListView nie jest aktualizowana w celu wyświetlenia nowego komentarza. Można to naprawić za pomocą jednego z następujących:

  • PostCommentButton Aktualizowanie programu obsługi zdarzeń przycisku Click w celu wywołania metody kontrolki DataBind() ListView po wstawieniu nowego komentarza do bazy danych lub
  • Ustawienie właściwości kontrolki EnableViewState ListView na False. Takie podejście działa, ponieważ wyłączenie stanu widoku kontrolki wymaga ponownego powiązania danych bazowych na każdym ogłaszaniu zwrotnym.

Witryna internetowa samouczka, która można pobrać z tego samouczka, ilustruje obie techniki. Właściwość kontrolki EnableViewState ListView do False i kod potrzebny do programowego powiązania danych z listview jest obecny w procedurze Click obsługi zdarzeń, ale jest komentowany.

Uwaga

Obecnie strona umożliwia użytkownikowi AdditionalUserInfo.aspx wyświetlanie i edytowanie ustawień swojego rodzinnego miasta, strony głównej i podpisu. Może być miło zaktualizować AdditionalUserInfo.aspx w celu wyświetlenia zalogowanych komentarzy do podręcznika użytkownika. Oznacza to, że oprócz badania i modyfikowania jej informacji użytkownik może odwiedzić AdditionalUserInfo.aspx stronę, aby zobaczyć, jakie komentarze książki gościa zrobiła w przeszłości. Zostawię to jako ćwiczenie dla zainteresowanego czytelnika.

Krok 6. Dostosowywanie kontrolki CreateUserWizard w celu uwzględnienia interfejsu dla miasta głównego, strony głównej i podpisu

Zapytanie SELECT używane przez Guestbook.aspx stronę używa elementu , INNER JOIN aby połączyć powiązane rekordy między GuestbookCommentstabelami , UserProfilesi aspnet_Users . Jeśli użytkownik bez rekordu w elemecie UserProfiles tworzy komentarz do elementu guestbook, komentarz nie będzie wyświetlany w widoku ListView, ponieważ INNER JOIN zwraca tylko GuestbookComments rekordy, gdy w elementach i aspnet_Userssą zgodne rekordy.UserProfiles Jak pokazano w kroku 3, jeśli użytkownik nie ma w UserProfiles niej rekordu, nie może wyświetlić ani edytować jej ustawień na AdditionalUserInfo.aspx stronie.

Nie trzeba powiedzieć, ze względu na nasze decyzje projektowe ważne jest, aby każde konto użytkownika w systemie członkostwa miało pasujący rekord w UserProfiles tabeli. Chcemy, aby odpowiedni rekord był dodawany do UserProfiles każdego utworzenia nowego konta użytkownika członkostwa za pomocą polecenia CreateUserWizard.

Zgodnie z opisem w samouczku Tworzenie kont użytkowników po utworzeniu nowego konta użytkownika członkostwo kontrolka CreateUserWizard zgłasza zdarzenieCreatedUser. Możemy utworzyć procedurę obsługi zdarzeń dla tego zdarzenia, pobrać identyfikator UserId dla właśnie utworzonego użytkownika, a następnie wstawić rekord do UserProfiles tabeli z wartościami domyślnymi dla HomeTownkolumn , HomepageUrli Signature . Co więcej, można monitować użytkownika o te wartości, dostosowując interfejs kontrolki CreateUserWizard w celu uwzględnienia dodatkowych pól TextBoxes.

Najpierw przyjrzyjmy się, jak dodać nowy wiersz do UserProfiles tabeli w CreatedUser procedurze obsługi zdarzeń z wartościami domyślnymi. W tym celu zobaczymy, jak dostosować interfejs użytkownika kontrolki CreateUserWizard w celu uwzględnienia dodatkowych pól formularza w celu zbierania nowego miasta, strony głównej i podpisu nowego użytkownika.

Dodawanie domyślnego wiersza doUserProfiles

W samouczku Tworzenie kont użytkowników dodaliśmy kontrolkę CreateUserWizard do CreatingUserAccounts.aspx strony w folderze Membership . Aby kontrolka CreateUserWizard dodała rekord do UserProfiles tabeli podczas tworzenia konta użytkownika, musimy zaktualizować funkcjonalność kontrolki CreateUserWizard. Zamiast wprowadzać te zmiany na CreatingUserAccounts.aspx stronie, zamiast tego dodajmy nową kontrolkę CreateUserWizard do EnhancedCreateUserWizard.aspx strony i wprowadźmy tam modyfikacje tego samouczka.

EnhancedCreateUserWizard.aspx Otwórz stronę w programie Visual Studio i przeciągnij kontrolkę CreateUserWizard z przybornika na stronę. Ustaw właściwość kontrolki ID CreateUserWizard na NewUserWizardwartość . Jak omówiono w samouczku Tworzenie kont użytkowników , domyślny interfejs użytkownika createUserWizard monituje użytkownika o podanie niezbędnych informacji. Po podaniu tych informacji kontrolka wewnętrznie tworzy nowe konto użytkownika w strukturze członkostwa bez konieczności pisania pojedynczego wiersza kodu.

Kontrolka CreateUserWizard zgłasza wiele zdarzeń podczas przepływu pracy. Gdy gość dostarczy informacje o żądaniu i prześle formularz, kontrolka CreateUserWizard początkowo uruchamia zdarzenieCreatingUser. Jeśli podczas procesu tworzenia wystąpi problem, CreateUserError zdarzenie zostanie wyzwolone. Jeśli jednak użytkownik zostanie pomyślnie utworzony, CreatedUser zdarzenie zostanie zgłoszone . W samouczku Tworzenie kont użytkowników utworzyliśmy procedurę obsługi zdarzeń dla CreatingUser zdarzenia, aby upewnić się, że podana nazwa użytkownika nie zawiera żadnych spacji wiodących ani końcowych oraz że nazwa użytkownika nie pojawiła się nigdzie w haśle.

Aby dodać wiersz w UserProfiles tabeli dla właśnie utworzonego użytkownika, musimy utworzyć procedurę obsługi zdarzeń dla CreatedUser zdarzenia. CreatedUser Gdy zdarzenie zostało wyzwolone, konto użytkownika zostało już utworzone w strukturze członkostwa, co umożliwi nam pobranie wartości UserId konta.

Utwórz procedurę obsługi zdarzeń dla NewUserWizardzdarzenia i CreatedUser dodaj następujący kod:

Protected Sub NewUserWizard_CreatedUser(ByVal sender As Object, ByVal e As System.EventArgs) Handles NewUserWizard.CreatedUser
     ' Get the UserId of the just-added user
     Dim newUser As MembershipUser = Membership.GetUser(NewUserWizard.UserName)
     Dim newUserId As Guid = CType(newUser.ProviderUserKey, Guid)

     ' Insert a new record into UserProfiles
     Dim connectionString As String = 

          ConfigurationManager.ConnectionStrings("SecurityTutorialsConnectionString").ConnectionString
     Dim insertSql As String = "INSERT INTO UserProfiles(UserId, HomeTown, HomepageUrl,
          Signature) VALUES(@UserId, @HomeTown, @HomepageUrl, @Signature)"

     Using myConnection As New SqlConnection(connectionString)
          myConnection.Open()
          Dim myCommand As 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()
     End Using
End Sub

Powyższe istoty kodu przez pobranie identyfikatora UserId właśnie dodanego konta użytkownika. Jest to realizowane przy użyciu Membership.GetUser(username) metody w celu zwrócenia informacji o określonym użytkowniku, a następnie przy użyciu ProviderUserKey właściwości w celu pobrania identyfikatora UserId. Nazwa użytkownika wprowadzona przez użytkownika w kontrolce CreateUserWizard jest dostępna za pośrednictwem jego UserName właściwości.

Następnie zostanie pobrany parametry połączenia z Web.config instrukcji , a instrukcja zostanie określonaINSERT. Niezbędne obiekty ADO.NET są tworzone i wykonywane polecenie. Kod przypisuje DBNull wystąpienie do @HomeTownparametrów , @HomepageUrli @Signature , które mają wpływ na wstawianie wartości bazy danych NULL dla HomeTownpól , HomepageUrli Signature .

EnhancedCreateUserWizard.aspx Odwiedź stronę za pośrednictwem przeglądarki i utwórz nowe konto użytkownika. Po wykonaniu tej czynności wróć do programu Visual Studio i sprawdź zawartość aspnet_Users tabel i UserProfiles (tak jak na rysunku 12). Powinno zostać wyświetlone nowe konto użytkownika w aspnet_Users i odpowiadający mu UserProfiles wiersz (z wartościami NULL , HomeTownHomepageUrli Signature).

Dodano nowe konto użytkownika i rekord UserProfiles

Rysunek 20. Dodano nowe konto użytkownika i UserProfiles rekord (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Po podaniu przez użytkownika informacji o nowym koncie i kliknięciu przycisku "Utwórz użytkownika" konto użytkownika zostanie utworzone i zostanie dodany wiersz do UserProfiles tabeli. Następnie w obszarze CreateUserWizard zostanie wyświetlony komunikat CompleteWizardStepo powodzeniu i przycisk Kontynuuj. Kliknięcie przycisku Kontynuuj powoduje powrót, ale nie podjęto żadnej akcji, pozostawiając użytkownika zablokowanego EnhancedCreateUserWizard.aspx na stronie.

Możemy określić adres URL, który ma zostać wysłany do użytkownika po kliknięciu przycisku Kontynuuj za pośrednictwem właściwości kontrolki ContinueDestinationPageUrlCreateUserWizard. ContinueDestinationPageUrl Ustaw właściwość na "~/Członkostwo/AdditionalUserInfo.aspx". Spowoduje to przejście nowego użytkownika do AdditionalUserInfo.aspxlokalizacji , w której może wyświetlać i aktualizować ustawienia.

Dostosowywanie interfejsu CreateUserWizard w celu monitowania o podanie głównego miasta, strony głównej i podpisu nowego użytkownika

Domyślny interfejs kontrolki CreateUserWizard jest wystarczający dla prostych scenariuszy tworzenia konta, w których zbierane są tylko podstawowe informacje o koncie użytkownika, takie jak nazwa użytkownika, hasło i wiadomość e-mail. Ale co zrobić, jeśli chcemy skłonić gościa do wejścia do swojego rodzinnego miasta, strony głównej i podpisu podczas tworzenia konta? Istnieje możliwość dostosowania interfejsu kontrolki CreateUserWizard w celu zbierania dodatkowych informacji podczas rejestracji, a te informacje mogą być używane w CreatedUser procedurze obsługi zdarzeń w celu wstawiania dodatkowych rekordów do bazowej bazy danych.

Kontrolka CreateUserWizard rozszerza kontrolkę Kreatora ASP.NET, która umożliwia deweloperowi strony zdefiniowanie serii uporządkowanych WizardStepselementów . Kontrolka Kreator renderuje aktywny krok i udostępnia interfejs nawigacyjny, który umożliwia odwiedzającym przejście przez te kroki. Kontrolka Kreator jest idealna do podziału długiego zadania na kilka krótkich kroków. Aby uzyskać więcej informacji na temat kontrolki Kreatora, zobacz Tworzenie interfejsu użytkownika krok po kroku za pomocą kontrolki kreatora ASP.NET 2.0.

Domyślny znacznik kontrolki CreateUserWizard definiuje dwa WizardStepselementy : CreateUserWizardStep i CompleteWizardStep.

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

Pierwszy WizardStepelement , CreateUserWizardSteprenderuje interfejs, który wyświetla monit o podanie nazwy użytkownika, hasła, poczty e-mail itd. Gdy odwiedzający dostarczy te informacje i kliknie pozycję "Utwórz użytkownika", zostanie wyświetlona wartość , która pokazuje komunikat o powodzeniu CompleteWizardStepi przycisk Kontynuuj.

Aby dostosować interfejs kontrolki CreateUserWizard w celu uwzględnienia dodatkowych pól formularza, możemy:

  • Utwórz co najmniej jeden nowyWizardSteps, aby zawierać dodatkowe elementy interfejsu użytkownika. Aby dodać nowy WizardStep element do elementu CreateUserWizard, kliknij link "Dodaj/Usuń WizardStep s" z jego tagu inteligentnegoWizardStep, aby uruchomić Redaktor Kolekcji. W tym miejscu możesz dodawać, usuwać lub zmieniać kolejność kroków w kreatorze. Jest to podejście, które będziemy używać w tym samouczku.

  • KonwertowanieCreateUserWizardStepdo edycjiWizardStep. Spowoduje to zamianę CreateUserWizardStep elementu na odpowiednik WizardStep , którego znacznik definiuje interfejs użytkownika zgodny z parametrami CreateUserWizardStep.s. Konwertując CreateUserWizardStep element na WizardStep element , możemy zmienić położenie kontrolek lub dodać dodatkowe elementy interfejsu użytkownika do tego kroku. Aby przekonwertować element CreateUserWizardStep lub CompleteWizardStep na edytowalny WizardStep, kliknij link "Dostosuj krok użytkownika" lub "Dostosuj pełny krok" z tagu inteligentnego kontrolki.

  • Użyj kombinacji powyższych dwóch opcji.

Należy pamiętać, że kontrolka CreateUserWizard wykonuje proces tworzenia konta użytkownika po kliknięciu przycisku "Utwórz użytkownika" z poziomu elementu CreateUserWizardStep. Nie ma znaczenia, czy są dodatkowe WizardStep po CreateUserWizardStep lub nie.

Podczas dodawania niestandardowego WizardStep do kontrolki CreateUserWizard w celu zbierania dodatkowych danych wejściowych użytkownika można umieścić niestandardowe WizardStep przed lub po CreateUserWizardStep. Jeśli nastąpi to przed CreateUserWizardStep wprowadzeniem dodatkowych danych wejściowych użytkownika zebranych z niestandardowego CreatedUser obiektu WizardStep obsługi zdarzeń. Jeśli jednak niestandardowe WizardStep nastąpi po CreateUserWizardStep upływie tego czasu, po wyświetleniu niestandardowego WizardStep zostanie już utworzone nowe konto użytkownika i CreatedUser zdarzenie zostało już wyzwolone.

Rysunek 21 przedstawia przepływ pracy po dodaniu WizardStep poprzedzającym CreateUserWizardStepelement . Ponieważ dodatkowe informacje o użytkowniku zostały zebrane przez czas CreatedUser uruchomienia zdarzenia, wystarczy zaktualizować CreatedUser procedurę obsługi zdarzeń, aby pobrać te dane wejściowe i użyć tych wartości INSERT parametrów instrukcji (a DBNull.Valuenie ).

Przepływ pracy CreateUserWizard, gdy dodatkowy kreatorKrok poprzedza element CreateUserWizardStep

Rysunek 21. Przepływ pracy CreateUserWizard po WizardStep dodatkowym poprzedza CreateUserWizardStep (kliknij, aby wyświetlić obraz pełnowymiarowy)

Jeśli jednak po ustawieniu parametruCreateUserWizardStepzostanie umieszczony niestandardowy WizardStep proces tworzenia konta użytkownika, zanim użytkownik miał szansę wejść do swojego rodzinnego miasta, strony głównej lub podpisu. W takim przypadku te dodatkowe informacje należy wstawić do bazy danych po utworzeniu konta użytkownika, jak pokazano na rysunku 22.

Przepływ pracy CreateUserWizard, gdy dodatkowy kreatorKrok pojawia się po kroku CreateUserWizardStep

Rysunek 22. Przepływ pracy CreateUserWizard po wprowadzeniu dodatkowych WizardStepCreateUserWizardStep informacji (kliknij, aby wyświetlić obraz pełnowymiarowy)

Przepływ pracy przedstawiony na rysunku 22 czeka na wstawienie rekordu UserProfiles do tabeli do momentu ukończenia kroku 2. Jeśli odwiedzający zamknie przeglądarkę po kroku 1, jednak osiągniemy stan, w którym zostało utworzone konto użytkownika, ale nie dodano rekordu do UserProfilesusługi . Jednym z obejść jest posiadanie rekordu z wartościami domyślnymi NULL wstawionym do UserProfilesCreatedUser programu obsługi zdarzeń (który jest uruchamiany po kroku 1), a następnie zaktualizować ten rekord po ukończeniu kroku 2. Dzięki UserProfiles temu rekord zostanie dodany dla konta użytkownika, nawet jeśli użytkownik zakończy proces rejestracji w połowie.

W tym samouczku utworzymy nową, WizardStep która występuje po CreateUserWizardStep obiekcie , ale przed .CompleteWizardStep Najpierw pobierzemy polecenie WizardStep i skonfigurujemy go, a następnie przyjrzymy się kodowi.

Na karcie Smart Tag kontrolki CreateUserWizard wybierz pozycję "Dodaj/UsuńWizardStep", która powoduje wyświetlenie okna dialogowego WizardStep Kolekcja Redaktor. Dodaj nowy WizardStepelement , ustawiając element ID na UserSettings, Title na "Ustawienia" i na StepTypeStep. Następnie umieść go tak, aby był dostępny po CreateUserWizardStep ("Zarejestruj się na nowe konto") i przed ("Complete"), jak pokazano na rysunku CompleteWizardStep 23.

Dodawanie nowego kreatoraKrok do kontrolki CreateUserWizard

Rysunek 23. Dodawanie nowego WizardStep do kontrolki CreateUserWizard (kliknij, aby wyświetlić obraz pełnowymiarowy)

Kliknij przycisk OK, WizardStep aby zamknąć okno dialogowe Zbieranie Redaktor. Nowy WizardStep jest dowodem na zaktualizowane znaczniki deklaratywne kontrolki 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>

Zanotuj nowy <asp:WizardStep> element. Musimy dodać interfejs użytkownika, aby zebrać miasto macierzyste nowego użytkownika, stronę główną i podpis tutaj. Tę zawartość można wprowadzić w składni deklaratywnej lub za pomocą Projektant. Aby użyć Projektant, wybierz krok "Ustawienia" z listy rozwijanej w tagu inteligentnym, aby wyświetlić krok w Projektant.

Uwaga

Wybranie kroku na liście rozwijanej tagu inteligentnego spowoduje zaktualizowanie właściwości kontrolki ActiveStepIndexCreateUserWizard, która określa indeks kroku początkowego. W związku z tym, jeśli używasz tej listy rozwijanej do edytowania kroku "Ustawienia" w Projektant, pamiętaj, aby ustawić go z powrotem na "Zarejestruj się na nowe konto", aby ten krok był wyświetlany podczas pierwszej wizyty użytkowników na EnhancedCreateUserWizard.aspx stronie.

Utwórz interfejs użytkownika w kroku "Ustawienia", który zawiera trzy kontrolki TextBox o nazwie HomeTown, HomepageUrli Signature. Po utworzeniu tego interfejsu znacznik deklaratywny CreateUserWizard powinien wyglądać podobnie do następującego:

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

Przejdź dalej i odwiedź tę stronę za pośrednictwem przeglądarki i utwórz nowe konto użytkownika, określając wartości dla rodzinnego miasta, strony głównej i podpisu. Po ukończeniu CreateUserWizardStep konta użytkownika zostanie utworzone w strukturze członkostwa i CreatedUser zostanie uruchomiona procedura obsługi zdarzeń, która dodaje nowy wiersz do UserProfileselementu , ale z wartością bazy danych NULL dla HomeTown, HomepageUrli Signature. Wartości wprowadzone dla rodzinnego miasta, strony głównej i podpisu nigdy nie są używane. Wynik netto to nowe konto użytkownika z rekordem UserProfiles , którego HomeTownpola , HomepageUrli Signature nie zostały jeszcze określone.

Musimy wykonać kod po kroku "Twoje ustawienia", który przyjmuje miasto macierzyste, honepage i wartości podpisu wprowadzone przez użytkownika i aktualizuje odpowiedni UserProfiles rekord. Za każdym razem, gdy użytkownik przechodzi między krokami w kontrolce Kreatora, zdarzenie Kreatora ActiveStepChanged jest uruchamiane. Możemy utworzyć procedurę obsługi zdarzeń dla tego zdarzenia i zaktualizować UserProfiles tabelę po zakończeniu kroku "Ustawienia".

Dodaj procedurę obsługi zdarzeń dla zdarzenia CreateUserWizard ActiveStepChanged i dodaj następujący kod:

Protected Sub NewUserWizard_ActiveStepChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles NewUserWizard.ActiveStepChanged
     ' Have we JUST reached the Complete step?
     If NewUserWizard.ActiveStep.Title = "Complete" Then
          Dim UserSettings As WizardStep = CType(NewUserWizard.FindControl("UserSettings"),WizardStep)

          ' Programmatically reference the TextBox controls
          Dim HomeTown As TextBox = CType(UserSettings.FindControl("HomeTown"), TextBox)
          Dim HomepageUrl As TextBox = CType(UserSettings.FindControl("HomepageUrl"), TextBox)
          Dim Signature As TextBox = CType(UserSettings.FindControl("Signature"), TextBox)

          ' Update the UserProfiles record for this user
          ' Get the UserId of the just-added user
          Dim newUser As MembershipUser = Membership.GetUser(NewUserWizard.UserName)
          Dim newUserId As Guid = CType(newUser.ProviderUserKey, Guid)

          ' Insert a new record into UserProfiles
          Dim connectionString As String = ConfigurationManager.ConnectionStrings("SecurityTutorialsConnectionString").ConnectionString

          Dim updateSql As String = "UPDATE UserProfiles SET HomeTown = @HomeTown, HomepageUrl
               = @HomepageUrl, Signature = @Signature WHERE UserId = @UserId"

          Using myConnection As New SqlConnection(connectionString)
               myConnection.Open()
               Dim myCommand As 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()
          End Using
     End If
End Sub

Powyższy kod rozpoczyna się od określenia, czy właśnie osiągnięto krok "Ukończono". Ponieważ krok "Ukończ" występuje natychmiast po kroku "Ustawienia", gdy gość osiągnie krok "Ukończono", oznacza to, że właśnie zakończyła krok "Twoje ustawienia".

W takim przypadku musimy programowo odwołać się do kontrolek TextBox w obiekcie UserSettings WizardStep. Jest to realizowane przy użyciu FindControl metody , aby programowo odwoływać UserSettings WizardStepsię do elementu , a następnie ponownie odwołać się do pola TextBoxes z poziomu elementu WizardStep. Po odwołaniu się do pola TextBoxes możemy wykonać instrukcję UPDATE . Instrukcja UPDATE ma taką samą liczbę parametrów jak INSERT instrukcja w CreatedUser procedurze obsługi zdarzeń, ale w tym miejscu używamy wartości miasta macierzystego, strony głównej i podpisu dostarczone przez użytkownika.

Korzystając z tej procedury obsługi zdarzeń, odwiedź EnhancedCreateUserWizard.aspx stronę za pośrednictwem przeglądarki i utwórz nowe konto użytkownika określające wartości dla rodzinnego miasta, strony głównej i podpisu. Po utworzeniu nowego konta należy przekierować na AdditionalUserInfo.aspx stronę, na której są wyświetlane informacje o właśnie wprowadzonej miejscowości głównej, stronie głównej i podpisie.

Uwaga

Nasza witryna internetowa ma obecnie dwie strony, na których odwiedzający może utworzyć nowe konto: CreatingUserAccounts.aspx i EnhancedCreateUserWizard.aspx. Mapa witryny i strona logowania witryny internetowej wskazują CreatingUserAccounts.aspx stronę, ale CreatingUserAccounts.aspx strona nie monituje użytkownika o podanie informacji o swoim rodzinnym mieście, stronie głównej i podpisie i nie dodaje odpowiedniego wiersza do UserProfiles. W związku z tym zaktualizuj CreatingUserAccounts.aspx stronę tak, aby oferuje ona tę funkcję lub zaktualizowała mapę witryny i stronę logowania, aby odwoływać EnhancedCreateUserWizard.aspx się zamiast CreatingUserAccounts.aspx. Jeśli wybierzesz tę drugą opcję, pamiętaj, aby zaktualizować Membership plik folderu Web.config tak, aby zezwolić anonimowym użytkownikom na dostęp do EnhancedCreateUserWizard.aspx strony.

Podsumowanie

W tym samouczku przyjrzeliśmy się technikom modelowania danych związanych z kontami użytkowników w ramach struktury członkostwa. W szczególności przyjrzeliśmy się modelowaniu jednostek, które współdzielą relację jeden do wielu z kontami użytkowników, a także dane, które współużytkuje relację jeden do jednego. Ponadto zobaczyliśmy, jak te powiązane informacje można wyświetlać, wstawiać i aktualizować, przy użyciu niektórych przykładów przy użyciu kontrolki SqlDataSource i innych przy użyciu kodu ADO.NET.

W tym samouczku przedstawiono konta użytkowników. Począwszy od następnego samouczka zwrócimy uwagę na role. W kolejnych kilku samouczkach przyjrzymy się strukturze Role, zobaczymy, jak tworzyć nowe role, jak przypisywać role do użytkowników, jak określić, do jakich ról należy użytkownik, oraz jak zastosować autoryzację opartą na rolach.

Szczęśliwe programowanie!

Dalsze informacje

Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:

Informacje o autorze

Scott Mitchell, autor wielu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Scott można dotrzeć pod mitchell@4guysfromrolla.com adresem lub za pośrednictwem swojego bloga pod adresem http://ScottOnWriting.NET.

Specjalne podziękowania...

Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.