(ASP.NET) ASP.NET (2008 год)

Базовые странички ASP.NET

На этой страничке я хотел рассказать о способах построения базовых страничек в ASP.NET/MONO. Базовая страничка - это такая страничка, которая отрабатывает при каждом реквесте любой странички сайта и выполняет общие действия для любой странички сайта в пределах текущего проекта. Например, устанавливает контекст ображения пользователя к сайту (залогиненный контекст или анонимный, к своей ли страничке обращается пользователь или к чужой - в социальных сетях. Иными словами такая страничка готовит некоторые бызовые основания для работы всех остальных страничек сайта.

Предположим страничка сайта условно разрезена на две части левая/правая или верхняя/нижняя. Каждая часть странички представляет собой с точки зрения ASP.NET-кода - один контрол левый или правый, верхний или нижний. Не будете же вы в каждом контроле устанавливать отдельно - аутентифицированный ли юзер, активирован ли он, если ли у него права находится на этой страничке? Ведь это все обращения в базу - и сколько такая страничка будет готовится Web-сервером, если на ней разположены 10-15 контролов, и каждый автономно ходит в базу и проверяет там права пользователя? Поэтому такой функционал, повторяемый множество раз - как в пределах одной и той же странички, так и в пределах разных страничек одного и того же сайта - принято выносить в общую часть всего сайта, которая и называется базовая страничка.

В зависимости от обстоятельств я применяю четыре способа построения базовых страничек:


На этой страничке я хотел обсудить шаблоны кода для каждого из четырех случаев и обсудить обстоятельства, когда выгоден тот или иной вариант построения базовой странички.


На мой взгляд первый и второй варианты - выгодны для социальных сетей, где:


Первый вариант от второго отличается техникой программирования. Если надо управлять видимостью отдельных элементов странички, то надо делать второй (сокращенный) ContextChecker (для второго варианта) или делать базовую страничку для контролов.

Например базовую страничку социальной сети Votpusk.ru я построил по первому принципу:


   1:  Imports Microsoft.VisualBasic
   2:  Imports System.Web.Security
   3:  Imports System
   4:  Imports System.Web
   5:  Imports System.Web.Profile
   6:   
   7:  ''' <summary>
   8:  ''' Это базовый класс сайта, добавляюющий к стандартному классу странички пару свойств
   9:  ''' Иcпользуется на всех персональных страничках (при постбеках и нет) - где требуется эта проверка корректности номера юзера (к кому заходим), заданного в Request.QueryString("i")
  10:  ''' Просто определить тут WEB-контролы низзя - перестанут работать все диалоговые инструменты студии и привязки в SqlDataSource
  11:  ''' </summary>
  12:  ''' 
  13:  Public Class VotpuskBasePage
  14:      Inherits System.Web.UI.Page
  15:      ''' <summary>
  16:      ''' Это ссылка на шифровалку параметров
  17:      ''' </summary>
  18:      Public ReadOnly Property PP8() As vbnet2009.ParmProtector8
  19:          Get
  20:              Return CType(Application("ParmProtector8"), vbnet2009.ParmProtector8)
  21:          End Get
  22:      End Property
  23:   
  24:      Dim _TypeOfPageLoad As Votpusk.RequestType
  25:      ''' <summary>
  26:      ''' Это тип загрузки странички этого сайта
  27:      ''' </summary>
  28:      Public ReadOnly Property QueryString_TypeOfPageLoad() As Votpusk.RequestType
  29:          Get
  30:              Return _TypeOfPageLoad
  31:          End Get
  32:      End Property
  33:   
  34:      Dim _ToUser As MembershipUser
  35:      ''' <summary>
  36:      ''' К какому юзеру входим по QueryString (рассчитывается функцией CheckRequest)
  37:      ''' </summary>
  38:      Public ReadOnly Property QueryString_I_User() As MembershipUser
  39:          Get
  40:              Return _ToUser
  41:          End Get
  42:      End Property
  43:   
  44:      Dim _ToUserProfile As ProfileCommon
  45:      ''' <summary>
  46:      ''' Это профиль юзера к которому заходим по Querystring
  47:      ''' </summary>
  48:      Public ReadOnly Property QueryString_I_UserProfile() As ProfileCommon
  49:          Get
  50:              Return _ToUserProfile
  51:          End Get
  52:      End Property
  53:   
  54:      Dim _FromUserProfile As ProfileCommon
  55:      ''' <summary>
  56:      ''' Это профиль AU юзера, который заходит
  57:      ''' </summary>
  58:      Public ReadOnly Property QueryString_AU_From_UserProfile() As ProfileCommon
  59:          Get
  60:              Return _FromUserProfile
  61:          End Get
  62:      End Property
  63:   
  64:      Dim _QueryString_I_UserName As String
  65:      ''' <summary>
  66:      ''' Имя юзера к кому зашли по QueryString
  67:      ''' </summary>
  68:      Public ReadOnly Property QueryString_I_UserName() As String
  69:          Get
  70:              Return _QueryString_I_UserName
  71:          End Get
  72:      End Property
  73:   
  74:      Dim _QueryString_g As String
  75:      ''' <summary>
  76:      ''' QueryString("g") в расшифрованном виде
  77:      ''' </summary>
  78:      Public ReadOnly Property QueryString_g() As String
  79:          Get
  80:              Return _QueryString_g
  81:          End Get
  82:      End Property
  83:   
  84:      Dim _QueryString_t As String
  85:      ''' <summary>
  86:      ''' QueryString("t") в расшифрованном виде
  87:      ''' </summary>
  88:      Public ReadOnly Property QueryString_t() As String
  89:          Get
  90:              Return _QueryString_t
  91:          End Get
  92:      End Property
  93:   
  94:      Dim _QueryString_j As String
  95:      ''' <summary>
  96:      ''' QueryString("j") в расшифрованном виде
  97:      ''' </summary>
  98:      Public ReadOnly Property QueryString_j() As String
  99:          Get
 100:              Return _QueryString_j
 101:          End Get
 102:      End Property
 103:   
 104:      ''' <summary>
 105:      ''' Для определения нового контента
 106:      ''' </summary>
 107:      Public ReadOnly Property OldContentCounter() As Votpusk.SiteContentCount
 108:          Get
 109:              Return CType(Session("OldContentCounter"), Votpusk.SiteContentCount)
 110:          End Get
 111:      End Property
 112:   
 113:      Private Sub VotpuskBasePage_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 114:          'сначала заполнили базовые свойства странички _ToUser,TypeOfPageLoad
 115:          Session("CheckRequest") = CheckRequest(IsPostBack)
 116:          _TypeOfPageLoad = CType(Session("CheckRequest"), Votpusk.RequestType)
 117:          If _ToUser IsNot Nothing Then _QueryString_I_UserName = _ToUser.UserName
 118:          'теперь, если в Querystring заданы g, t, j - впишем их в hidentype-контролы странички в расшифрованном виде
 119:          If Request.QueryString("g") <> "" Then _QueryString_g = vbnet2009.PP8_Helper.Unmask_QueryString("g", "SQLServer_ConnectionStrings") 'номер в табле GroupName
 120:          If Request.QueryString("t") <> "" Then _QueryString_t = vbnet2009.PP8_Helper.Unmask_QueryString("t", "SQLServer_ConnectionStrings") 'номер в табле LoadType
 121:          If Request.QueryString("j") <> "" Then _QueryString_j = vbnet2009.PP8_Helper.Unmask_QueryString("j", "SQLServer_ConnectionStrings") 'номер в табле UserData
 122:      End Sub
 123:   
 124:      ''' <summary>
 125:      ''' Проверка типа входа - к себе/не к себе. 
 126:      ''' Отрезает совсем левые входы с подделанным или пустым номером юзера
 127:      ''' </summary>
 128:      Private Function CheckRequest(ByVal IsPostback As Boolean) As Votpusk.RequestType
 129:          If HttpContext.Current.Request.QueryString("i") = "" Then
 130:              If HttpContext.Current.User.Identity.IsAuthenticated Then
 131:                  'аутентифицированного юзера перенаправляем к себе же на страничку
 132:                  My.Log.WriteEntry("1. Error. Не задан QueryString('i'). Аутентифицированного юзера перенаправляем к себе же на страничку. IsPostback=" & IsPostback.ToString)
 133:                  HttpContext.Current.Response.Redirect(Votpusk.[GoTo].UserHomePage)
 134:              Else
 135:                  'левый вход непонятно кого и непонятно к кому
 136:                  My.Log.WriteEntry("2. Error. Не задан QueryString('i'). Левый вход неаутентифицированного непонятно к кому. Направляем на NotSupported. IsPostback=" & IsPostback.ToString)
 137:                  HttpContext.Current.Response.Redirect(Votpusk.[GoTo].NotSupported & "?ErrorMessage=""Не задан QueryString('i'). Левый вход неаутентифицированного непонятно к кому""&URL=""" & Request.RawUrl & """")
 138:              End If
 139:          Else
 140:              'вход к конкретно заданному юзеру
 141:              Try
 142:                  Dim ToGuid As New Guid(HttpContext.Current.Request.QueryString("i"))
 143:                  If Membership.GetUser(ToGuid) Is Nothing Then
 144:                      If HttpContext.Current.User.Identity.IsAuthenticated Then
 145:                          'аутентифицированного юзера перенаправляем к себе же на страничку
 146:                          My.Log.WriteEntry("3. Error. Не найден юзер по заданному GUID. Аутентифицированного юзера перенаправляем к себе же на страничку. IsPostback=" & IsPostback.ToString)
 147:                          HttpContext.Current.Response.Redirect(Votpusk.[GoTo].UserHomePage)
 148:                      Else
 149:                          'левый вход непонятно кого и непонятно к кому
 150:                          My.Log.WriteEntry("4. Error. Не получилось сделать GUID по заданному QueryString('i'). " & HttpContext.Current.Request.QueryString("i") & " Левый вход неаутентифицированного непонятно к кому. Направляем на NotSupported. IsPostback=" & IsPostback.ToString)
 151:                          HttpContext.Current.Response.Redirect(Votpusk.[GoTo].NotSupported & "?ErrorMessage=""Не получилось сделать GUID по заданному QueryString('i')""&URL=""" & Request.RawUrl & """")
 152:                      End If
 153:                  Else
 154:                      'запрошенный юзер СУЩЕСТВУЕТ - идем дальше
 155:                      _ToUser = Membership.GetUser(ToGuid)
 156:                  End If
 157:              Catch ex As Exception
 158:                  If HttpContext.Current.User.Identity.IsAuthenticated Then
 159:                      'аутентифицированного юзера перенаправляем к себе же на страничку
 160:                      My.Log.WriteEntry("5. Error. Не получилось сделать GUID по заданному QueryString('i') =" & HttpContext.Current.Request.QueryString("i") & " Аутентифицированного юзера перенаправляем к себе же на страничку. IsPostback=" & IsPostback.ToString)
 161:                      HttpContext.Current.Response.Redirect(Votpusk.[GoTo].UserHomePage)
 162:                  Else
 163:                      'левый вход непонятно кого и непонятно к кому
 164:                      My.Log.WriteEntry("6. Error. Не получилось сделать GUID по заданному QueryString('i'). " & HttpContext.Current.Request.QueryString("i") & " Левый вход неаутентифицированного непонятно к кому. Направляем на NotSupported. IsPostback=" & IsPostback.ToString)
 165:                      HttpContext.Current.Response.Redirect(Votpusk.[GoTo].NotSupported & "?ErrorMessage=""Не получилось сделать GUID по заданному QueryString('i')""&URL=""" & Request.RawUrl & """")
 166:                  End If
 167:              End Try
 168:              '
 169:              If _ToUser Is Nothing Then
 170:                  My.Log.WriteEntry("7. Error. Так и не получили имени юзера по QueryString('i') =" & HttpContext.Current.Request.QueryString("i") & " Аутентифицированного юзера перенаправляем к себе же на страничку. IsPostback=" & IsPostback.ToString)
 171:                  'аутентифицированного юзера перенаправляем к себе же на страничку
 172:                  HttpContext.Current.Response.Redirect(Votpusk.[GoTo].UserHomePage)
 173:              End If
 174:              '
 175:              Try
 176:                  _ToUserProfile = ProfileBase.Create(_ToUser.UserName)
 177:              Catch ex As Exception
 178:                  My.Log.WriteEntry("8. Error. Не прочитался профиль юзера " & HttpContext.Current.Request.QueryString("i"))
 179:                  HttpContext.Current.Response.Redirect(Votpusk.[GoTo].NotSupported & "?ErrorMessage=""Не прочитался профиль юзера  ""&URL=""" & Request.RawUrl & """")
 180:              End Try
 181:              '
 182:              If HttpContext.Current.User.Identity.IsAuthenticated Then
 183:                  _FromUserProfile = ProfileBase.Create(HttpContext.Current.User.Identity.Name)
 184:                  If _FromUserProfile IsNot Nothing Then
 185:                      If HttpContext.Current.Request.QueryString("i") = Membership.GetUser(HttpContext.Current.User.Identity.Name).ProviderUserKey.ToString Then
 186:                          My.Log.WriteEntry("AuUserToHimself. Аутентифицированный юзер '" & HttpContext.Current.User.Identity.Name & "' зашел к себе. IsPostback=" & IsPostback.ToString)
 187:                          If _FromUserProfile.LoginIsActivate Then
 188:                              Return Votpusk.RequestType.ActiveUserToHimself
 189:                          Else
 190:                              Return Votpusk.RequestType.InActiveUserToHimself
 191:                          End If
 192:                      Else
 193:                          If _ToUserProfile.LoginIsActivate Then
 194:                              My.Log.WriteEntry("AuUserToOtherActive. Аутентифицированный юзер '" & HttpContext.Current.User.Identity.Name & "' зашел на страничку другого юзера " & HttpContext.Current.Request.QueryString("i") & " c активированным логином. IsPostback=" & IsPostback.ToString)
 195:                              If _FromUserProfile.LoginIsActivate Then
 196:                                  Return Votpusk.RequestType.ActiveToOtherActive
 197:                              Else
 198:                                  Return Votpusk.RequestType.InActiveToOtherActive
 199:                              End If
 200:                          Else
 201:                              My.Log.WriteEntry("AuUserToOtherInActive. Аутентифицированный юзер '" & HttpContext.Current.User.Identity.Name & "' зашел на страничку другого юзера " & HttpContext.Current.Request.QueryString("i") & " c Неактивированным логином. IsPostback=" & IsPostback.ToString)
 202:                              If _FromUserProfile.LoginIsActivate Then
 203:                                  Return Votpusk.RequestType.ActiveToOtherInActive
 204:                              Else
 205:                                  Return Votpusk.RequestType.InActiveToOtherInActive
 206:                              End If
 207:                          End If
 208:                      End If
 209:                  Else
 210:                          My.Log.WriteEntry("8-1. Error. Не прочитался профиль юзера " & HttpContext.Current.User.Identity.Name)
 211:                          HttpContext.Current.Response.Redirect(Votpusk.[GoTo].NotSupported & "?ErrorMessage=""Не прочитался профиль юзера  ""&Login=""" & HttpContext.Current.User.Identity.Name & """")
 212:                      End If
 213:                  Else
 214:                      If _ToUserProfile.LoginIsActivate Then
 215:                          My.Log.WriteEntry("AnonUserToActive. Неаутифицированный юзер зашел посмотреть страничку конкретного юзера " & HttpContext.Current.Request.QueryString("i") & " c активированным логином. IsPostback=" & IsPostback.ToString)
 216:                          Return Votpusk.RequestType.AnonUserToActive
 217:                      Else
 218:                          My.Log.WriteEntry("AnonUserToInActive. Неаутифицированный юзер зашел посмотреть страничку конкретного юзера " & HttpContext.Current.Request.QueryString("i") & " c Неактивированным логином. IsPostback=" & IsPostback.ToString)
 219:                          Return Votpusk.RequestType.AnonUserToInActive
 220:                      End If
 221:                  End If
 222:              End If
 223:      End Function
 224:  End Class

Как видите, тут содержатся ссылки на важные классы (для шифрования параметров), параметры странички в расшифрованном виде, проверятся куда заходит юзер - к себе/не к себе. При заведомо поддельных параметрах - такой хитрый юзер отфутболивается на странички с ошибками. Странички с ошибками должны быть тупиковыми - на них нет ссылок. Таким образом паук, автоматически обходящий сайт - заводится в тупик.

В таком варианте построения базовых страничек каждая страничка содержит примерно вот такую гирлянду кода:


   1:      Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
   2:          If Not IsPostBack Then
   3:              Select Case QueryString_TypeOfPageLoad
   4:                  Case Votpusk.RequestType.AnonUserToActive
   5:                      Response.Redirect(Votpusk.[GoTo].WarningPage)
   6:                  Case Votpusk.RequestType.ActiveUserToHimself, Votpusk.RequestType.InActiveUserToHimself
   7:                      CurrPageState = CType(Session("PageState"), Votpusk.PageState)
   8:                      If CurrPageState.ContactAll_PageState = 0 Then
   9:                          CommentLabel1.Text = "Конструктор группировки моих контактов."
  10:                          MultiView1.ActiveViewIndex = 0
  11:                          GridView1.DataBind()
  12:                      Else
  13:                          CommentLabel1.Text = "Мои контакты."
  14:                          MultiView1.ActiveViewIndex = 2
  15:                          GridView2.DataBind()
  16:                      End If
  17:                  Case Votpusk.RequestType.ActiveToOtherActive, Votpusk.RequestType.InActiveToOtherActive
  18:                      Response.Redirect(Votpusk.[GoTo].NotSupported & "?ErrorMessage=""Левый вход не к себе.""&URL=""" & Request.RawUrl & """")
  19:                  Case Votpusk.RequestType.ActiveToOtherInActive, Votpusk.RequestType.InActiveToOtherInActive
  20:                      MultiView1.ActiveViewIndex = 1
  21:                  Case Votpusk.RequestType.AnonUserToInActive
  22:                      MultiView1.ActiveViewIndex = 1
  23:              End Select
  24:          End If

Те при загрузке каждой странички надо сделать ветвление в Page_Load в зависимости от контекста загрузки - который выставляется на базовой страничке - анонимный юзер, администратор, на своей страничке, на чужой и так далее. Кроме контекста базовая страничка дает основному рабочему коду уже расшифрованные параметры и другие важные ссылки, многократно используемые на страничке.


Второй способ - он немного отличается от первого способа, когда код разбора контекста реквеста выполняется до собственно создания конкретной странички MyPage.aspx. Во втором способе страничка создается нормально, наследуюя System.Web.UI.Page, однако в Page_Load каждой странички встраивается вызов проверки контекста вызова странички.

Эта техника тоже идальна для социальных сетей, однако я ее применяю когда странички сложные и легко запутаться какой именно элемент (например кнопка Удалить или кнопка Комментировать) - должен быть показан в том или ином контексте загрузки. Например, находясь на чужой страничке - можно только комментировать, на своей - можно только удалить, а админ сайта - может забанить/разбанить контент любой странички. Например, в моем сайте http://arenda.votpusk.ru/ на страничках очень много всяких кнопок, чекобоксов и прочих элементов, которые должны показываться (или не показываться) по-разному - в зависимости от шестнадцатразличных контекстов вызова странички. Чтобы не запутаться в 16-ти ветвлениях в огромном SELECT CASE в Page_Load я сделал в этом проекте вот такую базовую страничку (часть):


   1:  Imports Microsoft.VisualBasic
   2:   
   3:  Public Enum TypeOfPageLoad
   4:      AdminToHimself = 1
   5:      RightToHimself = 2
   6:      LeftToHimself = 3
   7:      AdminToLeftUser = 4
   8:      AdminToRightUser = 5
   9:      LeftToLeftUser = 6
  10:      RightToRightUser = 7
  11:      RightToLeftUser = 8
  12:      LeftToRightUser = 9
  13:      AnonToLeftUser = 10
  14:      AnonToRightUser = 11
  15:      LegalAnonContext = 12
  16:      ErrContext = 13
  17:      AdminContext = 14
  18:      RightUserContext = 15
  19:      LeftUserContext = 16
  20:      CurrUserNotFound = 17
  21:      ProfileNotFound = 18
  22:  End Enum
  23:   
  24:  ''' <summary>
  25:  ''' Проверка свой/чужой контекст, залогиненный/незалогиненный юзер - просто для контекста и для обьекта
  26:  ''' </summary>
  27:  Public Class CheckContext
  28:   
  29:      Public Delegate Sub AU_Callback(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon, ByVal ObjectOwner As MembershipUser, ByVal MyTypedProfile_Target As ProfileCommon)
  30:      Public Delegate Sub Himself_Callback(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile As ProfileCommon)
  31:      Public Delegate Sub Anon_Callback(ByVal ObjectOwner As MembershipUser, ByVal MyTypedProfile As ProfileCommon)
  32:      Public Delegate Sub ErrCalback()
  33:      Public Delegate Sub User_Callback(ByVal User As MembershipUser, ByVal MyTypedProfile As ProfileCommon)
  34:      Public Delegate Sub User_To_User_Callback(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon, ByVal TargetUser As MembershipUser, ByVal MyTypedProfile_Target As ProfileCommon)
  35:   
  36:   
  37:      ''' <summary>
  38:      ''' Запрос на чтение владельца обьекта
  39:      ''' </summary>
  40:      Public ReadOnly Property SelectObjectOwnerQuery() As String
  41:          Get
  42:              Return _SelectObjectOwnerQuery
  43:          End Get
  44:      End Property
  45:      Dim _SelectObjectOwnerQuery As String = "select ToUser from [Objects] with (nolock) where ID=@Object_ID"
  46:   
  47:   
  48:      ''' <summary>
  49:      '''  Определение контекста вызова странички
  50:      ''' </summary>
  51:      ''' <param name="AdminContext">вход администратора</param>
  52:      ''' <param name="RightUserContext"> вход зарегистрированного, активированного юзера</param>
  53:      ''' <param name="LeftUserContext">вход зарегистрированного, но неактивированного юзера</param>
  54:      ''' <param name="LegalAnonContext">анонимный вызов этой странички </param>
  55:      ''' <param name="CurrUserNotFound">не найден в Membership текущий залогиненный юзер</param>
  56:      ''' <param name="ProfileNotFound">отсутсвует профиль залогиненного пользователя</param>
  57:      ''' <remarks></remarks>
  58:      Public Sub CheckCurrentContext( _
  59:          ByVal AdminContext As Himself_Callback, _
  60:          ByVal RightUserContext As Himself_Callback, _
  61:          ByVal LeftUserContext As Himself_Callback, _
  62:          ByVal LegalAnonContext As ErrCalback, _
  63:          ByVal CurrUserNotFound As ErrCalback, _
  64:          ByVal ProfileNotFound As ErrCalback)
  65:          '
  66:          If HttpContext.Current.User.Identity.IsAuthenticated Then
  67:              'залогиненный контекст
  68:              Dim CurrentUser As MembershipUser = Membership.GetUser(HttpContext.Current.User.Identity.Name)
  69:              If CurrentUser IsNot Nothing Then
  70:                  '
  71:                  If Roles.IsUserInRole("UserAdmin") Then
  72:                      'контекст администратора
  73:                      Dim CurrentUserProfile As ProfileCommon = ReadMyTypedProfile(CurrentUser, ProfileNotFound)
  74:                      If CurrentUserProfile Is Nothing Then Exit Sub
  75:                      AdminContext.Invoke(CurrentUser, CurrentUserProfile)
  76:                  Else
  77:                      'залогиненный контекст простого юзера
  78:                      Dim CurrentUserProfile As ProfileCommon = ReadMyTypedProfile(CurrentUser, ProfileNotFound)
  79:                      If CurrentUserProfile Is Nothing Then Exit Sub
  80:                      '
  81:                      If CurrentUserProfile.LoginIsActivate Then
  82:                          'этот пользователь уже авторизован
  83:                          RightUserContext.Invoke(CurrentUser, CurrentUserProfile)
  84:                      Else
  85:                          'только что зарегистировавался
  86:                          LeftUserContext.Invoke(CurrentUser, CurrentUserProfile)
  87:                      End If
  88:                  End If
  89:              Else
  90:                  'не найден юзер
  91:                  CurrUserNotFound.Invoke()
  92:              End If
  93:          Else
  94:              'незалогиненный контекст
  95:              LegalAnonContext.Invoke()
  96:          End If
  97:      End Sub
  98:   
  99:   
 100:      ''' <summary>
 101:      '''  Определение контекста вызова странички при указании в QueryString номера пользователя
 102:      ''' </summary>
 103:      ''' <param name="ErrorParametersUser">Ошибка параметра Querystring("User")</param>
 104:      ''' <param name="TargetUserNotFound">Нет юзера к которому заходим</param>
 105:      ''' <param name="CurrUserNotFound">отсутвует в Membership текущий юзер</param>
 106:      ''' <param name="CurrProfileNotFound">нет профиля текущего юзера</param>
 107:      ''' <param name="TargetProfileNotFound">нет профиля юзера, чья страничка вызвана</param>
 108:      ''' <param name="RightToHimself">активированный залогиненный юзер зашел к себе на страничку</param>
 109:      ''' <param name="LeftToHimself">неактивированный залогиненный юзер зашел к себе на страничку</param>
 110:      ''' <param name="AdminToHimself">админ зашел на свою страничку</param>
 111:      ''' <param name="AdminToLeftUser">админ зашел к неактивированному юзеру</param>
 112:      ''' <param name="AdminToRightUser">админ зашел к активированному юзеру</param>
 113:      ''' <param name="LeftToLeftUser">неактивированный залогиненный юзер зашел на страничку к неактивированному</param>
 114:      ''' <param name="RightToRightUser">активированный залогиненный юзер зашел на страничку к активированному юзеру</param>
 115:      ''' <param name="RightToLeftUser">активированный залогиненный юзер зашел на страничку к неактивированному юзеру</param>
 116:      ''' <param name="LeftToRightUser">активированный залогиненный юзер зашел на страничку к неактивированному</param>
 117:      ''' <param name="AnonToLeftUser">аноним зашел к неактивированному юзеру</param>
 118:      ''' <param name="AnonToRightUser">аноним зашел к активированному юзеру</param>
 119:      ''' <remarks></remarks>
 120:      Public Sub CheckUserContext(ByVal ErrorParametersUser As ErrCalback, _
 121:      ByVal TargetUserNotFound As ErrCalback, _
 122:      ByVal CurrUserNotFound As ErrCalback, _
 123:      ByVal CurrProfileNotFound As ErrCalback, _
 124:      ByVal TargetProfileNotFound As ErrCalback, _
 125:      ByVal RightToHimself As User_Callback, _
 126:      ByVal LeftToHimself As User_Callback, _
 127:      ByVal AdminToHimself As User_Callback, _
 128:      ByVal AdminToLeftUser As User_To_User_Callback, _
 129:      ByVal AdminToRightUser As User_To_User_Callback, _
 130:      ByVal LeftToLeftUser As User_To_User_Callback, _
 131:      ByVal RightToRightUser As User_To_User_Callback, _
 132:      ByVal RightToLeftUser As User_To_User_Callback, _
 133:      ByVal LeftToRightUser As User_To_User_Callback, _
 134:      ByVal AnonToLeftUser As User_Callback, _
 135:      ByVal AnonToRightUser As User_Callback)
 136:   
 137:          If HttpContext.Current.Request.QueryString("User") Is Nothing Then
 138:              ErrorParametersUser.Invoke()
 139:              Exit Sub
 140:          End If
 141:          If HttpContext.Current.Request.QueryString("User") = "" Then
 142:              ErrorParametersUser.Invoke()
 143:              Exit Sub
 144:          End If
 145:          Dim UserID As String = HttpContext.Current.Request.QueryString("User")
 146:          Try
 147:              'это просто проверка того, что сюда суют именно GUID
 148:              Dim Guid1 As Guid = New Guid(UserID)
 149:          Catch ex As Exception
 150:              ErrorParametersUser.Invoke()
 151:              Exit Sub
 152:          End Try
 153:          '
 154:          Dim TargetUser As MembershipUser
 155:          TargetUser = Membership.GetUser(New Guid(UserID))
 156:          If TargetUser Is Nothing Then
 157:              TargetUserNotFound.Invoke()
 158:              Exit Sub
 159:          End If
 160:          Dim MyTypedProfile_Target As ProfileCommon = ReadMyTypedProfile(TargetUser, TargetProfileNotFound)
 161:          '
 162:          Dim CurrentUser As MembershipUser
 163:          If HttpContext.Current.User.Identity.IsAuthenticated Then
 164:              CurrentUser = Membership.GetUser(HttpContext.Current.User.Identity.Name)
 165:              If CurrentUser Is Nothing Then
 166:                  CurrUserNotFound.Invoke()
 167:                  Exit Sub
 168:              End If
 169:              Dim MyTypedProfile_Current As ProfileCommon = ReadMyTypedProfile(CurrentUser, CurrProfileNotFound)
 170:              Dim IsAdmin As Boolean = Roles.IsUserInRole(CurrentUser.UserName, "UserAdmin")
 171:              If CurrentUser.UserName = TargetUser.UserName Then
 172:                  'зашел к себе на страничку
 173:                  If IsAdmin Then
 174:                      AdminToHimself.Invoke(CurrentUser, MyTypedProfile_Current)
 175:                  Else
 176:                      If MyTypedProfile_Current.LoginIsActivate Then
 177:                          RightToHimself.Invoke(CurrentUser, MyTypedProfile_Current)
 178:                      Else
 179:                          LeftToHimself.Invoke(CurrentUser, MyTypedProfile_Current)
 180:                      End If
 181:                  End If
 182:              Else
 183:                  'зашел на чужую страничку
 184:                  If IsAdmin Then
 185:                      If MyTypedProfile_Target.LoginIsActivate Then
 186:                          AdminToRightUser.Invoke(CurrentUser, MyTypedProfile_Current, TargetUser, MyTypedProfile_Target)
 187:                      Else
 188:                          AdminToLeftUser.Invoke(CurrentUser, MyTypedProfile_Current, TargetUser, MyTypedProfile_Target)
 189:                      End If
 190:                  Else
 191:                      If MyTypedProfile_Current.LoginIsActivate Then
 192:                          If MyTypedProfile_Target.LoginIsActivate Then
 193:                              RightToRightUser(CurrentUser, MyTypedProfile_Current, TargetUser, MyTypedProfile_Target)
 194:                          Else
 195:                              RightToLeftUser(CurrentUser, MyTypedProfile_Current, TargetUser, MyTypedProfile_Target)
 196:                          End If
 197:                      Else
 198:                          If MyTypedProfile_Target.LoginIsActivate Then
 199:                              LeftToRightUser(CurrentUser, MyTypedProfile_Current, TargetUser, MyTypedProfile_Target)
 200:                          Else
 201:                              LeftToLeftUser(CurrentUser, MyTypedProfile_Current, TargetUser, MyTypedProfile_Target)
 202:                          End If
 203:                      End If
 204:                  End If
 205:              End If
 206:          Else
 207:              'аноним зашел к кому-то
 208:              If MyTypedProfile_Target.LoginIsActivate Then
 209:                  AnonToRightUser.Invoke(TargetUser, MyTypedProfile_Target)
 210:              Else
 211:                  AnonToLeftUser.Invoke(TargetUser, MyTypedProfile_Target)
 212:              End If
 213:          End If
 214:      End Sub
 215:   
 216:   
 217:   
 218:      ''' <summary>
 219:      ''' Определение контекста вызова странички при указании в Querystring номера Обьекта недвижимости 
 220:      ''' </summary>
 221:      ''' <param name="ErrorParametersObject_ID">В параметрах передан не GUID</param>
 222:      ''' <param name="ObjectNotFound">Объект не найден</param>
 223:      ''' <param name="UserOwnerNotFound">не найден юзер - владелец обьекта</param>
 224:      ''' <param name="CurrUserNotFound">не найден в Membership текущий залогиненный юзер</param>
 225:      ''' <param name="ProfileNotFound">нету профиля залогиненного юзера</param>
 226:      ''' <param name="RightToHimself">зарегистрированный активированный юзер зашел к себе</param>
 227:      ''' <param name="LeftToHimself">зарегистрированный неактивированный юзер зашел к себе<</param>
 228:      ''' <param name="AdminToHimself">администратор зашел к себе</param>
 229:      ''' <param name="AdminToLeftUser">администратор зашел к неавторизованному юзеру</param>
 230:      ''' <param name="AdminToRightUser">администратор зашел к авторизованному юзеру</param>
 231:      ''' <param name="LeftToLeftUser">неактивированный залогиненный юзер зашел к другому неактивированному</param>
 232:      ''' <param name="RightToRightUser">зарегистрированный активированный юзер зашел к другому активированному зарегистрированному юзеру</param>
 233:      ''' <param name="RightToLeftUser">зарегистрированный активированный юзер зашел к другому зарегистрированному неактивированному юзеру</param>
 234:      ''' <param name="LeftToRightUser">зарегистрированный неактивированный юзер зашел к другому зарегистрированному активированному юзеру</param>
 235:      ''' <param name="AnonToLeftUser">аноним зашел к зарегистрированный неактивированному юзеру</param>
 236:      ''' <param name="AnonToRightUser">аноним зашел к зарегистрированный активированному юзеру</param>
 237:      ''' <remarks></remarks>
 238:      Public Sub CheckObjectContext(ByVal ErrorParametersObject_ID As ErrCalback, _
 239:      ByVal ObjectNotFound As ErrCalback, _
 240:      ByVal UserOwnerNotFound As ErrCalback, _
 241:      ByVal CurrUserNotFound As ErrCalback, _
 242:      ByVal ProfileNotFound As ErrCalback, _
 243:      ByVal RightToHimself As Himself_Callback, _
 244:      ByVal LeftToHimself As Himself_Callback, _
 245:      ByVal AdminToHimself As Himself_Callback, _
 246:      ByVal AdminToLeftUser As AU_Callback, _
 247:      ByVal AdminToRightUser As AU_Callback, _
 248:      ByVal LeftToLeftUser As AU_Callback, _
 249:      ByVal RightToRightUser As AU_Callback, _
 250:      ByVal RightToLeftUser As AU_Callback, _
 251:      ByVal LeftToRightUser As AU_Callback, _
 252:      ByVal AnonToLeftUser As Anon_Callback, _
 253:      ByVal AnonToRightUser As Anon_Callback)
 254:   
 255:   
 256:          If HttpContext.Current.Request.QueryString("Object") Is Nothing Then
 257:              ErrorParametersObject_ID.Invoke()
 258:              Exit Sub
 259:          End If
 260:          If HttpContext.Current.Request.QueryString("Object") = "" Then
 261:              ErrorParametersObject_ID.Invoke()
 262:              Exit Sub
 263:          End If
 264:          Dim Object_ID As String = HttpContext.Current.Request.QueryString("Object")
 265:          Try
 266:              'это просто проверка того, что сюда суют именно GUID
 267:              Dim Guid1 As Guid = New Guid(Object_ID)
 268:          Catch ex As Exception
 269:              ErrorParametersObject_ID.Invoke()
 270:              Exit Sub
 271:          End Try
 272:          '
 273:          Dim ObjectOwnerUser As MembershipUser = GetObjectOwner(Object_ID, ObjectNotFound, UserOwnerNotFound)
 274:          If ObjectOwnerUser Is Nothing Then Exit Sub
 275:          '
 276:          Dim OwnerUserProfile As ProfileCommon = ReadMyTypedProfile(ObjectOwnerUser, ProfileNotFound)
 277:          If OwnerUserProfile Is Nothing Then Exit Sub
 278:          '
 279:          If HttpContext.Current.User.Identity.IsAuthenticated Then
 280:              'залогиненный контекст
 281:              Dim CurrentUser As MembershipUser = Membership.GetUser(HttpContext.Current.User.Identity.Name)
 282:              If CurrentUser IsNot Nothing Then
 283:                  '
 284:                  Dim CurrentUserProfile As ProfileCommon = ReadMyTypedProfile(CurrentUser, ProfileNotFound)
 285:                  If CurrentUserProfile Is Nothing Then Exit Sub
 286:                  '
 287:                  If Roles.IsUserInRole("UserAdmin") Then
 288:                      'контекст администратора
 289:                      If ObjectOwnerUser.ProviderUserKey = CurrentUser.ProviderUserKey Then
 290:                          'у себя
 291:                          AdminToHimself.Invoke(CurrentUser, OwnerUserProfile)
 292:                      Else
 293:                          'у другого юзера
 294:                          If OwnerUserProfile.LoginIsActivate Then
 295:                              'у авторизовавшегося
 296:                              AdminToRightUser.Invoke(CurrentUser, CurrentUserProfile, ObjectOwnerUser, OwnerUserProfile)
 297:                          Else
 298:                              'у только что зарегистировавшегося
 299:                              AdminToLeftUser.Invoke(CurrentUser, CurrentUserProfile, ObjectOwnerUser, OwnerUserProfile)
 300:                          End If
 301:                      End If
 302:                  Else
 303:                      'залогиненный контекст простого юзера
 304:                      If ObjectOwnerUser.ProviderUserKey = CurrentUser.ProviderUserKey Then
 305:                          'у себя
 306:                          '
 307:                          If CurrentUserProfile.LoginIsActivate Then
 308:                              'этот пользователь уже авторизован
 309:                              RightToHimself.Invoke(CurrentUser, CurrentUserProfile)
 310:                          Else
 311:                              'только что зарегистировавался
 312:                              LeftToHimself.Invoke(CurrentUser, CurrentUserProfile)
 313:                          End If
 314:                      Else
 315:                          'у другого юзера
 316:                          '
 317:                          If OwnerUserProfile.LoginIsActivate Then
 318:                              'у авторизовавшегося
 319:                              If CurrentUserProfile.LoginIsActivate Then
 320:                                  RightToRightUser.Invoke(CurrentUser, CurrentUserProfile, ObjectOwnerUser, OwnerUserProfile)
 321:                              Else
 322:                                  LeftToRightUser.Invoke(CurrentUser, CurrentUserProfile, ObjectOwnerUser, OwnerUserProfile)
 323:                              End If
 324:                          Else
 325:                              'у только что зарегистировавшегося
 326:                              If CurrentUserProfile.LoginIsActivate Then
 327:                                  RightToLeftUser.Invoke(CurrentUser, CurrentUserProfile, ObjectOwnerUser, OwnerUserProfile)
 328:                              Else
 329:                                  LeftToLeftUser.Invoke(CurrentUser, CurrentUserProfile, ObjectOwnerUser, OwnerUserProfile)
 330:                              End If
 331:                          End If
 332:                      End If
 333:                  End If
 334:              Else
 335:                  'не найден юзер
 336:                  CurrUserNotFound.Invoke()
 337:              End If
 338:          Else
 339:              'незалогиненный контекст
 340:              If OwnerUserProfile.LoginIsActivate Then
 341:                  AnonToRightUser(ObjectOwnerUser, OwnerUserProfile)
 342:              Else
 343:                  AnonToLeftUser.Invoke(ObjectOwnerUser, OwnerUserProfile)
 344:              End If
 345:          End If
 346:      End Sub
 347:   
 348:  ...

В такой архитектуре вначале каждой странички просто делается проверка контекста юзера (CheckUserContext) или проверка контекста просмотра обьекта (CheckObjectContext) - в ВСЯ страничка просто состоит из делегатов, в которых выполняется управление элементами странички:


   1:  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
   2:          Dim ObjectChecker As New CheckContext
   3:          ObjectChecker.CheckUserContext( _
   4:          AddressOf ErrorParametersUser, _
   5:          AddressOf TargetUserNotFound, _
   6:          AddressOf CurrUserNotFound, _
   7:          AddressOf CurrProfileNotFound, _
   8:          AddressOf TargetProfileNotFound, _
   9:          AddressOf RightToHimself, _
  10:          AddressOf LeftToHimself, _
  11:          AddressOf AdminToHimself, _
  12:          AddressOf AdminToLeftUser, _
  13:          AddressOf AdminToRightUser, _
  14:          AddressOf LeftToLeftUser, _
  15:          AddressOf RightToRightUser, _
  16:          AddressOf RightToLeftUser, _
  17:          AddressOf LeftToRightUser, _
  18:          AddressOf AnonToLeftUser, _
  19:          AddressOf AnonToRightUser)
  20:   
  21:  ....
  22:   
  23:      End Sub
  24:   
  25:  #Region "Доступность элементов странички в зависимости от контекста вызова странички"
  26:   
  27:      'активированный залогиненный юзер зашел к себе на страничку
  28:      Sub RightToHimself(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon)
  29:          UserMenu1.MenuUser = CurrentUser
  30:          UserMenu1.ThisTypePageLoad = TypeOfPageLoad.RightToHimself
  31:          ThisTypePageLoad = TypeOfPageLoad.RightToHimself
  32:   
  33:      End Sub
  34:   
  35:      Sub LeftToHimself(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon)
  36:          UserMenu1.MenuUser = CurrentUser
  37:          UserMenu1.ThisTypePageLoad = TypeOfPageLoad.LeftToHimself
  38:          ThisTypePageLoad = TypeOfPageLoad.LeftToHimself
  39:          lErr1.Text = "Вы не можете добавлять новые объекты пока не прошли активацию"
  40:      End Sub
  41:   
  42:      'ошибка параметра Querystring("User")
  43:      Sub ErrorParametersUser()
  44:          UserMenu1.Visible = False
  45:          lErr1.Text = "Ошибка. Пользователь не найден."
  46:          'AddLink1.Visible = False
  47:      End Sub
  48:   
  49:      'админ зашел на свою страничку
  50:      Sub AdminToHimself(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon)
  51:          UserMenu1.MenuUser = CurrentUser
  52:          UserMenu1.ThisTypePageLoad = TypeOfPageLoad.AdminToHimself
  53:          ThisTypePageLoad = TypeOfPageLoad.AdminToHimself
  54:      End Sub
  55:   
  56:      'админ зашел к неактивированному юзеру
  57:      Sub AdminToLeftUser(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon, ByVal TargetUser As MembershipUser, ByVal MyTypedProfile_Target As ProfileCommon)
  58:          UserMenu1.MenuUser = TargetUser
  59:          UserMenu1.ThisTypePageLoad = TypeOfPageLoad.AdminToLeftUser
  60:          ThisTypePageLoad = TypeOfPageLoad.AdminToLeftUser
  61:          lErr1.Text = "Этот пользователь еще не прошел активацию и не может добавлять свои объекты"
  62:      End Sub
  63:   
  64:      'админ зашел к активированному юзеру
  65:      Sub AdminToRightUser(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon, ByVal TargetUser As MembershipUser, ByVal MyTypedProfile_Target As ProfileCommon)
  66:          UserMenu1.MenuUser = TargetUser
  67:          UserMenu1.ThisTypePageLoad = TypeOfPageLoad.AdminToRightUser
  68:          ThisTypePageLoad = TypeOfPageLoad.AdminToRightUser
  69:      End Sub
  70:   
  71:      'неактивированный залогиненный юзер зашел на страничку к неактивированному
  72:      Sub LeftToLeftUser(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon, ByVal TargetUser As MembershipUser, ByVal MyTypedProfile_Target As ProfileCommon)
  73:          UserMenu1.MenuUser = TargetUser
  74:          UserMenu1.ThisTypePageLoad = TypeOfPageLoad.LeftToLeftUser
  75:          ThisTypePageLoad = TypeOfPageLoad.LeftToLeftUser
  76:          lErr1.Text = "Этот пользователь еще не прошел активацию и не может добавлять свои объекты"
  77:      End Sub
  78:   
  79:      'активированный залогиненный юзер зашел на страничку к активированному юзеру
  80:      Sub RightToRightUser(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon, ByVal TargetUser As MembershipUser, ByVal MyTypedProfile_Target As ProfileCommon)
  81:          UserMenu1.MenuUser = TargetUser
  82:          UserMenu1.ThisTypePageLoad = TypeOfPageLoad.RightToRightUser
  83:          ThisTypePageLoad = TypeOfPageLoad.RightToRightUser
  84:      End Sub
  85:   
  86:      'активированный залогиненный юзер зашел на страничку к неактивированному юзеру
  87:      Sub RightToLeftUser(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon, ByVal TargetUser As MembershipUser, ByVal MyTypedProfile_Target As ProfileCommon)
  88:          UserMenu1.MenuUser = TargetUser
  89:          UserMenu1.ThisTypePageLoad = TypeOfPageLoad.RightToLeftUser
  90:          ThisTypePageLoad = TypeOfPageLoad.RightToLeftUser
  91:          lErr1.Text = "Этот пользователь еще не прошел активацию и не может добавлять свои объекты"
  92:      End Sub
  93:   
  94:      'неактивированный залогиненный юзер зашел на страничку к активированному
  95:      Sub LeftToRightUser(ByVal CurrentUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon, ByVal TargetUser As MembershipUser, ByVal MyTypedProfile_Target As ProfileCommon)
  96:          UserMenu1.MenuUser = TargetUser
  97:          UserMenu1.ThisTypePageLoad = TypeOfPageLoad.LeftToRightUser
  98:          ThisTypePageLoad = TypeOfPageLoad.LeftToRightUser
  99:      End Sub
 100:   
 101:      Sub CurrUserNotFound()
 102:          UserMenu1.Visible = False
 103:          'AddLink1.Visible = False
 104:          lErr1.Text = "Ошибка. Пользователь не найден."
 105:      End Sub
 106:   
 107:      Sub CurrProfileNotFound()
 108:          UserMenu1.Visible = False
 109:          '  AddLink1.Visible = False
 110:          lErr1.Text = "Ошибка. Пользователь не найден."
 111:      End Sub
 112:   
 113:      'аноним зашел к неактивированному юзеру
 114:      Sub AnonToLeftUser(ByVal TargetUser As MembershipUser, ByVal MyTypedProfile_Current As ProfileCommon)
 115:          '  AddLink1.Visible = False
 116:          ThisTypePageLoad = TypeOfPageLoad.AnonToLeftUser
 117:          UserMenu1.ThisTypePageLoad = TypeOfPageLoad.AnonToLeftUser
 118:          lErr1.Text = "Этот пользователь еще не прошел активацию и не может добавлять свои объекты"
 119:      End Sub
 120:   
 121:      'аноним зашел к активированному юзеру
 122:      Sub AnonToRightUser(ByVal TargetUser As MembershipUser, ByVal MyTypedProfile_Target As ProfileCommon)
 123:          ' AddLink1.Visible = False
 124:          ThisTypePageLoad = TypeOfPageLoad.AnonToRightUser
 125:          UserMenu1.ThisTypePageLoad = TypeOfPageLoad.AnonToRightUser
 126:      End Sub
 127:   
 128:      'Нет юзера к которому заходим
 129:      Sub TargetUserNotFound()
 130:          UserMenu1.Visible = False
 131:          ' AddLink1.Visible = False
 132:          lErr1.Text = "Ошибка. Пользователь не найден."
 133:      End Sub
 134:   
 135:      'нет профиля юзера, чья страничка вызвана
 136:      Sub TargetProfileNotFound()
 137:          UserMenu1.Visible = False
 138:          ' AddLink1.Visible = False
 139:          lErr1.Text = "Ошибка. Пользователь не найден."
 140:      End Sub
 141:   
 142:  #End Region

Как видите - так код получился гораздо нагляднее, чем если бы Page_Load была построена на 16-ти ветках Select Case. Этот код является превосходным дополнением моей странички Практическое применение наследования, полиморфизма, интерфейсов, дженериков и делегатов на примерах в Visual Basic .NET в части делегатов.




Теперь рассмотрим третий вариант вынесения общего кода в контрол. Я обычно пользуюсь таким вариантом для аутентификации. Возьмем для примера админку того же проекта вотпуск.




Вся левая часть с крупными линками - это отдельный контрол в который утоплен код проверки прав юзера на вход в админку.


   1:  <%@ Master Language="VB" CodeFile="M2.master.vb" Inherits="M2" %>
   2:  <%@ Register Src="AdminLink.ascx" TagName="AdminLink" TagPrefix="uc1" %>
   3:   
   4:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   5:   
   6:  <html xmlns="http://www.w3.org/1999/xhtml" >
   7:  <head runat="server">
   8:      <title>CMS <asp:Literal runat="server" Text="<%$ appSettings:RealURL%>"/></title>
   9:  </head> 
  10:  <body >
  11:      <form id="form1" runat="server">
  12:          <uc1:AdminLink ID="AdminLink1" runat="server" />
  13:      <div>
  14:          <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
  15:          </asp:contentplaceholder>
  16:          
  17:      </div>
  18:      </form>
  19:  </body>
  20:  </html>

   1:  <%@ Control Language="VB" AutoEventWireup="false" CodeFile="AdminLink.ascx.vb" Inherits="AdminLink" %>
   2:  <table cellpadding="0" cellspacing="0">
   3:  ...
   4:  </table>

   1:  ''' <summary>
   2:  ''' Контрол защищает от левых входов
   3:  ''' </summary>
   4:  Partial Class AdminLink
   5:      Inherits System.Web.UI.UserControl
   6:   
   7:      Protected Sub AdminLink_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
   8:          '
   9:          HyperLink29.NavigateUrl = "http://foto." & System.Configuration.ConfigurationManager.AppSettings("RealURL")
  10:          HyperLink30.NavigateUrl = "http://video." & System.Configuration.ConfigurationManager.AppSettings("RealURL")
  11:          HyperLink31.NavigateUrl = "http://story." & System.Configuration.ConfigurationManager.AppSettings("RealURL")
  12:          HyperLink32.NavigateUrl = "http://poputi." & System.Configuration.ConfigurationManager.AppSettings("RealURL")
  13:          HyperLink37.NavigateUrl = "http://search." & System.Configuration.ConfigurationManager.AppSettings("RealURL")
  14:          HyperLink39.NavigateUrl = "http://" & System.Configuration.ConfigurationManager.AppSettings("RealURL")
  15:          '
  16:          If Not IsPostBack Then
  17:              If Not Me.Page.User.Identity.IsAuthenticated Then
  18:                  Response.Redirect("Login.aspx")
  19:                  Exit Sub
  20:              End If
  21:              If Not Roles.IsUserInRole(Me.Page.User.Identity.Name, "UserAdmin") Then
  22:                  Response.Redirect(Votpusk.[GoTo].NotSupported & "?ErrorMessage=""Эта функция доступна только администраторам.""&URL=""" & Request.RawUrl & """")
  23:              End If
  24:          End If
  25:   
  26:      End Sub
  27:  End Class



Наконец четвертый вариант утапливанивая общего кода в код Master_Page. Это наиболее сложный вариант - когда не удается утопить общий код иначе. Ведь контролы (а Master-Page это тоже контрол) - выполняются от внутреннего вложенного к внешнему окаймляющему. Те код код master-page будет выполняться посдедним - и страничкb проекта будут готовитья, когда этот обший код в master-page еще не вызывался.

Но есть несколько вариантов, когда имеет смысл утапливать код в master page:


В качестве примера общего кода на мастер-педж проекта я приведу мой баг-трекер, который в принципе является одинм из моих комерческих продуктов - Bug_Tracker (инструмент разработки и эксплуатации программ) ( в упрощенном варианте является OpenSource Простейший баг-трекер). В виде продукта его только вот отсюда сгрузили сотни человек. А для моих собственных целей (для сопровождения багов в прогах, которые я выкладываю на http://freeware.vb-net.com/ и http://products.vb-net.com/ этот мой баг-трекер лежит вот тут - http://bug.vb-net.com/Default.aspx.


В этом проекте есть некий общий код, вынесенный на master-page. В данном случае этот общий код выполняет две функции:


   1:  <%@ Master Language="VB" CodeFile="M1.master.vb" Inherits="M1" %>
   2:   
   3:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   4:   
   5:  <html xmlns="http://www.w3.org/1999/xhtml">
   6:  <head runat="server">
   7:      <title>Bug Tracker</title>
   8:  </head>
   9:  <body>
  10:      <form id="form1" runat="server">
  11:          <div style="text-align:left; display:inline;float:left">
  12:      <asp:ImageButton ID="ImageButton1" ImageUrl="~/BugImage/Top.gif" PostBackUrl="~/Default.aspx" runat="server" ValidationGroup="Always" />
  13:      </div>
  14:      <div style="text-align:right; display:inline;float:right">
  15:          <asp:Login ID="Login1" runat="server" LoginButtonText="Войти" 
  16:              PasswordLabelText="Пароль" RememberMeText="Помнить" TitleText="" 
  17:              UserNameLabelText="Email">
  18:          </asp:Login>
  19:          <asp:LinkButton ID="LinkButton1" runat="server"  ValidationGroup="Always">Выйти</asp:LinkButton>
  20:          <asp:Label ID="LoginName1" runat="server"  />
  21:          <asp:HyperLink ID="RegisterLink" runat="server" >Регистрация</asp:HyperLink><br />
  22:          <asp:HyperLink ID="RememberLink" runat="server" >Напомнить пароль</asp:HyperLink>
  23:      </div>
  24:      <div style="height:80px"></div>
  25:      <div>
  26:          <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
  27:          
  28:          </asp:ContentPlaceHolder>
  29:      </div>
  30:      </form>
  31:  </body>
  32:  </html>

   1:  Partial Class M1
   2:      Inherits System.Web.UI.MasterPage
   3:   
   4:      Protected Sub M1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
   5:   
   6:          'защита/активация
   7:          If Not IsPostBack Then
   8:              Dim PointerToActivationCode As IntPtr
   9:              'код активации, полученный от сервера
  10:              Dim RuntimeActivationCode As String
  11:              'RuntimeActivationCode = Runtime.InteropServices.Marshal.PtrToStringBSTR(PointerToActivationCode)
  12:              Try
  13:                  'код проверки ключа активации
  14:                  '....
  15:                  '
  16:                  Me.Page.ClientScript.RegisterOnSubmitStatement(Me.GetType, "DemoAlert", "alert('Demo version');")
  17:              Catch ex As Exception
  18:                  Me.Page.ClientScript.RegisterOnSubmitStatement(Me.GetType, "DemoAlert", "alert('Demo version');")
  19:              End Try
  20:  Run:
  21:          End If
  22:          '
  23:          RegisterLink.NavigateUrl = System.Configuration.ConfigurationManager.AppSettings("UserRegisterURL")
  24:          RememberLink.NavigateUrl = System.Configuration.ConfigurationManager.AppSettings("UserRestorePassURL")
  25:          '
  26:          If HttpContext.Current.User.Identity.IsAuthenticated Then
  27:              Dim MyTypedProfile As ProfileCommon = Profile.GetProfile(HttpContext.Current.User.Identity.Name)
  28:              If MyTypedProfile IsNot Nothing Then
  29:                  LoginName1.Text = MyTypedProfile.usNik
  30:              Else
  31:                  LoginName1.Text = HttpContext.Current.User.Identity.Name
  32:              End If
  33:              LinkButton1.Visible = True
  34:              Login1.Visible = False
  35:              RegisterLink.Visible = False
  36:              RememberLink.Visible = False
  37:          Else
  38:              LoginName1.Visible = False
  39:              LinkButton1.Visible = False
  40:              Login1.Visible = True
  41:              RegisterLink.Visible = True
  42:              RememberLink.Visible = True
  43:          End If
  44:      End Sub
  45:   
  46:      Protected Sub Login1_LoggingIn(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.LoginCancelEventArgs) Handles Login1.LoggingIn
  47:          Dim MyTypedProfile As ProfileCommon = Profile.GetProfile(HttpContext.Current.User.Identity.Name)
  48:          If MyTypedProfile IsNot Nothing Then
  49:              LoginName1.Text = MyTypedProfile.usNik
  50:          Else
  51:              LoginName1.Text = HttpContext.Current.User.Identity.Name
  52:          End If
  53:          LinkButton1.Visible = True
  54:          Login1.Visible = False
  55:          RegisterLink.Visible = False
  56:          RememberLink.Visible = False
  57:      End Sub
  58:   
  59:      Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click
  60:          FormsAuthentication.SignOut()
  61:          LoginName1.Visible = False
  62:          LinkButton1.Visible = False
  63:          Login1.Visible = True
  64:          RegisterLink.Visible = True
  65:          RememberLink.Visible = True
  66:          Response.Redirect(Request.RawUrl)
  67:      End Sub
  68:   
  69:      Protected Sub Login1_LoginError(ByVal sender As Object, ByVal e As System.EventArgs) Handles Login1.LoginError
  70:          LoginName1.Visible = False
  71:          LinkButton1.Visible = False
  72:          Login1.Visible = True
  73:          RegisterLink.Visible = True
  74:          RememberLink.Visible = True
  75:      End Sub
  76:  End Class

Обратите внимание, что если вы будете пользоваться таким же точно способом залогинивания - когда микрософтовские контролы для залогинивания сами находят стандартную базу ASP.NET юзеров и обрабатывают логины/пароли в этой базе, то вы должны точно в конфиге своего приложения сконфигурировать membership-провайдер:


   1:  ...
   2:      <connectionStrings>
   3:          <remove name="LocalSqlServer"/>
   4:          <add name="LocalSqlServer" connectionString="server=Dev;Initial Catalog=Bug;User ID=Bug;Password=123456" providerName="System.Data.SqlClient"/>
   5:          <add name="SQLServer_ConnectionStrings" connectionString="server=Dev;Initial Catalog=Bug;User ID=Bug;Password=123456" providerName="System.Data.SqlClient"/>
   6:      </connectionStrings>
   7:  ...
   8:      <appSettings>
   9:  ...
  10:      </appSettings>
  11:      <system.web>
  12:          <globalization culture="ru-RU"/>
  13:          <roleManager enabled="true" defaultProvider="AspNetSqlProvider">
  14:              <providers>
  15:                  <remove name="AspNetSqlRoleProvider"/>
  16:                  <remove name="AspNetWindowsTokenRoleProvider"/>
  17:                  <add applicationName="/" name="AspNetSqlProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="LocalSqlServer"/>
  18:              </providers>
  19:          </roleManager>
  20:          <membership>
  21:              <providers>
  22:                  <remove name="AspNetSqlMembershipProvider"/>
  23:                  <add applicationName="/" name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider,System.Web, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="LocalSqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="False" requiresUniqueEmail="True" minRequiredPasswordLength="1" minRequiredNonalphanumericCharacters="0" passwordFormat="Hashed" maxInvalidPasswordAttempts="6" passwordAttemptWindow="10" passwordStrengthRegularExpression=""/>
  24:              </providers>
  25:          </membership>
  26:          <compilation debug="true">
  27:              <assemblies>
  28:  ...
  29:                  </compilation>
  30:          <authentication mode="Forms"/>
  31:          <profile defaultProvider="SqlProvider">
  32:              <providers>
  33:                  <clear/>
  34:                  <add applicationName="/" name="SqlProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="LocalSqlServer"/>
  35:              </providers>
  36:              <properties>
  37:  ...
  38:              </properties>
  39:          </profile>



В заключение я покажу расширение первого варианта, когда строится некая иерархия классов, некоторые методы в которых обьвляются Overridable, а потом в вышестоящих классах переопределяются (с ключевым словом Overrides). Соотвественно - каждая форма проекта может наследовать тот или иной похожий класс.


   1:  Imports Microsoft.VisualBasic
   2:   
   3:  ''' <summary>
   4:  ''' Есть свойство для запоминания текущего рабочего XML - и оно всегда непустое
   5:  ''' </summary>
   6:  Public Class ProfileBasePage2
   7:      Inherits ProfileBasePage1
   8:   
   9:      Property WorkingXML As XElement
  10:          Get
  11:              Return Session("WorkingXML" & "_" & Request.QueryString("Type") & "_" & Request.QueryString("id"))
  12:          End Get
  13:          Set(ByVal value As XElement)
  14:              Session("WorkingXML" & "_" & Request.QueryString("Type") & "_" & Request.QueryString("id")) = value
  15:          End Set
  16:      End Property
  17:   
  18:      Private Sub ProfileBasePage_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  19:          ReadCurrentUser()
  20:          ReadTargetProfile()
  21:          INI_NULL_Working_XML()
  22:      End Sub
  23:   
  24:      Overrides Sub INI_NULL_Working_XML()
  25:          Select Case Request.QueryString("Type")
  26:              Case "BankingCards"
  27:                  If BankingCards_xml(0) Is Nothing Then
  28:                      WorkingXML = New XElement("{http://Airts.vb-net.com/}" & "BankingCards")
  29:                  Else
  30:                      WorkingXML = BankingCards_xml(0)
  31:                  End If
  32:              Case "InetMoney"
  33:                  If InetMoney_xml(0) Is Nothing Then
  34:                      WorkingXML = New XElement("{http://Airts.vb-net.com/}" & "InetMoney")
  35:                  Else
  36:                      WorkingXML = InetMoney_xml(0)
  37:                  End If
  38:              Case "HardMoney"
  39:                  If HardMoney_xml(0) Is Nothing Then
  40:                      WorkingXML = New XElement("{http://Airts.vb-net.com/}" & "HardMoney")
  41:                  Else
  42:                      WorkingXML = HardMoney_xml(0)
  43:                  End If
  44:              Case "Invoice"
  45:                  If Invoice_xml(0) Is Nothing Then
  46:                      WorkingXML = New XElement("{http://Airts.vb-net.com/}" & "Invoice")
  47:                  Else
  48:                      WorkingXML = Invoice_xml(0)
  49:                  End If
  50:              Case "BankTransfer"
  51:                  If BankTransfer_xml(0) Is Nothing Then
  52:                      WorkingXML = New XElement("{http://Airts.vb-net.com/}" & "BankTransfer")
  53:                  Else
  54:                      WorkingXML = BankTransfer_xml(0)
  55:                  End If
  56:              Case "Bonus"
  57:                  If Bonus_xml(0) Is Nothing Then
  58:                      WorkingXML = New XElement("{http://Airts.vb-net.com/}" & "Bonus")
  59:                  Else
  60:                      WorkingXML = Bonus_xml(0)
  61:                  End If
  62:              Case "Reserved"
  63:                  If Reserved_xml Is Nothing Then
  64:                      WorkingXML = New XElement("{http://Airts.vb-net.com/}" & "Reserved")
  65:                  Else
  66:                      WorkingXML = Reserved_xml(0)
  67:                  End If
  68:              Case "Common"
  69:                  If Common_xml(0) Is Nothing Then
  70:                      WorkingXML = New XElement("{http://Airts.vb-net.com/}" & "Common")
  71:                  Else
  72:                      WorkingXML = Common_xml(0)
  73:                  End If
  74:          End Select
  75:      End Sub
  76:   
  77:      Sub SaveProfile()
  78:          Dim AirtsDB1 As New UserPaymentProfileDataContext()
  79:          Select Case Request.QueryString("Type")
  80:              Case "BankingCards"
  81:                  Me.TargetUserPaymentProfile(0).BankingCardsProfile = WorkingXML
  82:                  AirtsDB1.SaveBankingCardsUserProfile(New Guid(Me.TargetUser.id), WorkingXML)
  83:                  DebugLog.TraceTXT(Me.AppRelativeVirtualPath, "BankingCardsSchema Save " & Me.TargetUser.id)
  84:              Case "InetMoney"
  85:                  Me.TargetUserPaymentProfile(0).InetMoneyProfile = WorkingXML
  86:                  AirtsDB1.SaveInetMoneyUserProfile(New Guid(Me.TargetUser.id), WorkingXML)
  87:                  DebugLog.TraceTXT(Me.AppRelativeVirtualPath, "InetMoneySchema Save " & Me.TargetUser.id)
  88:              Case "HardMoney"
  89:                  Me.TargetUserPaymentProfile(0).HardMoneyProfile = WorkingXML
  90:                  AirtsDB1.SaveHardMoneyUserProfile(New Guid(Me.TargetUser.id), WorkingXML)
  91:                  DebugLog.TraceTXT(Me.AppRelativeVirtualPath, "HardMoneySchema Save " & Me.TargetUser.id)
  92:              Case "Invoice"
  93:                  Me.TargetUserPaymentProfile(0).InvoiceProfile = WorkingXML
  94:                  AirtsDB1.SaveInvoiceUserProfile(New Guid(Me.TargetUser.id), WorkingXML)
  95:                  DebugLog.TraceTXT(Me.AppRelativeVirtualPath, "InvoiceSchema Save " & Me.TargetUser.id)
  96:              Case "BankTransfer"
  97:                  Me.TargetUserPaymentProfile(0).BankTransferProfile = WorkingXML
  98:                  AirtsDB1.SaveBankTransferUserProfile(New Guid(Me.TargetUser.id), WorkingXML)
  99:                  DebugLog.TraceTXT(Me.AppRelativeVirtualPath, "BankTransferSchema Save " & Me.TargetUser.id)
 100:              Case "Bonus"
 101:                  Me.TargetUserPaymentProfile(0).BonusProfile = WorkingXML
 102:                  AirtsDB1.SaveBonusUserProfile(New Guid(Me.TargetUser.id), WorkingXML)
 103:                  DebugLog.TraceTXT(Me.AppRelativeVirtualPath, "BonusSchema Save " & Me.TargetUser.id)
 104:              Case "Reserved"
 105:                  Me.TargetUserPaymentProfile(0).ReservedProfile = WorkingXML
 106:                  AirtsDB1.SaveReservedUserProfile(New Guid(Me.TargetUser.id), WorkingXML)
 107:                  DebugLog.TraceTXT(Me.AppRelativeVirtualPath, "ReservedSchema Save " & Me.TargetUser.id)
 108:              Case "Common"
 109:                  Me.TargetUserPaymentProfile(0).CommonProfile = WorkingXML
 110:                  AirtsDB1.SaveCommonUserProfile(New Guid(Me.TargetUser.id), Me.TargetUserPaymentProfile(0).ProfileName, Me.TargetUserPaymentProfile(0).CommonProfile)
 111:                  DebugLog.TraceTXT(Me.AppRelativeVirtualPath, "InetMoneySchema Save " & Me.TargetUser.id)
 112:          End Select
 113:      End Sub
 114:   
 115:  End Class
 116:   
 117:  ''' <summary>
 118:  ''' Для работы с профилями
 119:  ''' админ видит любого юзера, чей id указан в параметрах
 120:  ''' информация в контролах доступна для изменению только админу, неадмин видит только свой профиль
 121:  ''' </summary>
 122:  Public Class ProfileBasePage1
 123:      Inherits ProfileBasePage
 124:   
 125:      Property TargetUser As CheckUser
 126:   
 127:      Property TargetUserPaymentProfile As System.Collections.Generic.List(Of GetOneUserPaymentProfileResult)
 128:      Property BankingCards_xml As Collections.Generic.IEnumerable(Of XElement)
 129:      Property InetMoney_xml As Collections.Generic.IEnumerable(Of XElement)
 130:      Property HardMoney_xml As Collections.Generic.IEnumerable(Of XElement)
 131:      Property Invoice_xml As Collections.Generic.IEnumerable(Of XElement)
 132:      Property BankTransfer_xml As Collections.Generic.IEnumerable(Of XElement)
 133:      Property Bonus_xml As Collections.Generic.IEnumerable(Of XElement)
 134:      Property Reserved_xml As Collections.Generic.IEnumerable(Of XElement)
 135:      Property Common_xml As Collections.Generic.IEnumerable(Of XElement)
 136:   
 137:      Private Sub ProfileBasePage_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 138:          ReadCurrentUser()
 139:          ReadTargetProfile()
 140:          INI_NULL_Working_XML()
 141:      End Sub
 142:   
 143:      Overrides Sub ReadTargetProfile()
 144:          TargetUser = New CheckUser
 145:          'информация в контролах доступна для изменению только админу, неадмин видит только свой профиль
 146:          If Not CurrentUser.IsAdmin Then
 147:              DisableControls(Me.Controls(0))
 148:              TargetUser = CurrentUser
 149:          Else
 150:              'админ видит любого юзера, чей id указан в параметрах
 151:              If Request.QueryString("id") IsNot Nothing Then
 152:                  If Request.QueryString("id") <> "" Then
 153:                      TargetUser.GetUserByID(Request.QueryString("id"))
 154:                  Else
 155:                      TargetUser = CurrentUser
 156:                  End If
 157:              Else
 158:                  TargetUser = CurrentUser
 159:              End If
 160:          End If
 161:          '
 162:          ReadTargetUserPaymentProfile()
 163:          '
 164:          If Request.QueryString("Type") IsNot Nothing Then
 165:              Select Case Request.QueryString("Type")
 166:                  Case "BankingCards"
 167:                      BankingCards_xml = From AllColumn In Me.TargetUserPaymentProfile Select AllColumn.BankingCardsProfile
 168:                  Case "InetMoney"
 169:                      InetMoney_xml = From AllColumn In Me.TargetUserPaymentProfile Select AllColumn.InetMoneyProfile
 170:                  Case "HardMoney"
 171:                      HardMoney_xml = From AllColumn In Me.TargetUserPaymentProfile Select AllColumn.HardMoneyProfile
 172:                  Case "Invoice"
 173:                      Invoice_xml = From AllColumn In Me.TargetUserPaymentProfile Select AllColumn.InvoiceProfile
 174:                  Case "BankTransfer"
 175:                      BankTransfer_xml = From AllColumn In Me.TargetUserPaymentProfile Select AllColumn.BankTransferProfile
 176:                  Case "Bonus"
 177:                      Bonus_xml = From AllColumn In Me.TargetUserPaymentProfile Select AllColumn.BonusProfile
 178:                  Case "Reserved"
 179:                      Reserved_xml = From AllColumn In Me.TargetUserPaymentProfile Select AllColumn.ReservedProfile
 180:                  Case "Common"
 181:                      Common_xml = From AllColumn In Me.TargetUserPaymentProfile Select AllColumn.CommonProfile
 182:              End Select
 183:          End If
 184:      End Sub
 185:   
 186:      Sub ReadTargetUserPaymentProfile()
 187:          'кеширование чтения профиля из базы с помощью LINQ
 188:          If Session("UserPaymentProfile_" & Me.TargetUser.id) Is Nothing Then
 189:              Dim AirtsDB As New UserPaymentProfileDataContext()
 190:              Dim AirtsDB_MemoryBuf As System.Collections.Generic.List(Of GetOneUserPaymentProfileResult) = AirtsDB.GetOneUserPaymentProfile(New Guid(Me.TargetUser.id)).ToList
 191:              Session("UserPaymentProfile_" & Me.TargetUser.id) = AirtsDB_MemoryBuf
 192:          End If
 193:          _TargetUserPaymentProfile = Session("UserPaymentProfile_" & Me.TargetUser.id)
 194:      End Sub
 195:   
 196:      Sub DisableControls(ByVal TopControl As System.Web.UI.Control)
 197:          Try
 198:              If TopControl.GetType.Name.Contains("TextBox") Then
 199:                  Dim TextBox As Web.UI.WebControls.TextBox = CType(TopControl, Web.UI.WebControls.TextBox)
 200:                  TextBox.Enabled = False
 201:              ElseIf TopControl.GetType.Name.Contains("CheckBox") Then
 202:                  Dim CheckBox As Web.UI.WebControls.CheckBox = CType(TopControl, Web.UI.WebControls.CheckBox)
 203:                  CheckBox.Enabled = False
 204:              ElseIf TopControl.GetType.Name.Contains("DropDownList") Then
 205:                  Dim DropDownList As Web.UI.WebControls.DropDownList = CType(TopControl, Web.UI.WebControls.DropDownList)
 206:                  DropDownList.Enabled = False
 207:              Else
 208:                  If TopControl.Controls.Count > 0 Then
 209:                      For Each OneControls As System.Web.UI.Control In TopControl.Controls
 210:                          DisableControls(OneControls)
 211:                      Next
 212:                  End If
 213:              End If
 214:          Catch ex As Exception
 215:              Throw New Exception("Base page Error" & ex.Message)
 216:          End Try
 217:   
 218:      End Sub
 219:   
 220:  End Class
 221:   
 222:  ''' <summary>
 223:  ''' Только аутентификация и чтение профиля залогиненного юзера из базы
 224:  ''' </summary>
 225:  Public Class ProfileBasePage
 226:      Inherits System.Web.UI.Page
 227:   
 228:      Property CurrentUser As CheckUser
 229:   
 230:      Private Sub ProfileBasePage_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 231:          ReadCurrentUser()
 232:          ReadTargetProfile()
 233:          INI_NULL_Working_XML()
 234:      End Sub
 235:   
 236:   
 237:      Sub ReadCurrentUser()
 238:          CurrentUser = New CheckUser
 239:          If HttpContext.Current.User.Identity.IsAuthenticated Then
 240:              'прочитали профиль юзера из базы
 241:              CurrentUser.GetUserByMail(HttpContext.Current.User.Identity.Name)
 242:          Else
 243:              Response.Redirect("Login.aspx")
 244:          End If
 245:      End Sub
 246:   
 247:      Overridable Sub ReadTargetProfile()
 248:          'в этом классе не делаем ничего
 249:      End Sub
 250:   
 251:      Overridable Sub INI_NULL_Working_XML()
 252:          'в этом классе пусто
 253:      End Sub
 254:   
 255:  End Class

Итак, подведем итоги - на этой страничке я описал ЧЕТЫРЕ способа встраивания общего кода ASP-NET проекта в общую структуру проекта:

Самый последний вариант - это многоярусная пирамида классов в базовой страничке проекта - расширение первого варианта размещения общего кода ASP.NET сайта.



Comments ( )
<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17>  <18>  <19>  <20>  <21>  <22>  <23
Link to this page: //www.vb-net.com/BasePage/index.htm
<SITEMAP>  <MVC>  <ASP>  <NET>  <DATA>  <KIOSK>  <FLEX>  <SQL>  <NOTES>  <LINUX>  <MONO>  <FREEWARE>  <DOCS>  <ENG>  <CHAT ME>  <ABOUT ME>  < THANKS ME>