(MVC) MVC (2017 год)

Cайтік з web-сервісом, спеціфічним membership-провайдером та даними Excel.

У минулому році я виконав безліч проєктів, двадцять з яких я описав тут Опис двадцяти моїх дрібних фрілансерских проєктів 2016-го року, у новому 2017-му року - не меньше, частину з яких я описав ось тут 2017, а ні цьей сторінці я опищу це один невеличкий сайтік, фактично зроблений за один день. Цей сайтік має три компонента, які могуть кого-небудь зацікавити:

1. Спеціфічний membership-провайдер, який працює без SQL-серверу, а самє по логинам у конфигу.

З точки зору авторізації у цьому конфигу задані три важливі речі:


   1:  <configuration>
   2:  .....
   3:    <system.web>
   4:      <customErrors mode="Off"/>
   5:      <compilation debug="true" strict="false" explicit="true" targetFramework="4.0">
   6:        <assemblies>
   7:          <add assembly="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
   8:        </assemblies>
   9:      </compilation>
  10:      <authentication mode="Forms">
  11:        <forms loginUrl="~/Account/Login.aspx" timeout="2880">
  12:          <credentials passwordFormat="Clear">
  13:            <user name="admin" password="N%nYhyEP~T{v6m" />
  14:          </credentials>
  15:        </forms>
  16:      </authentication>
  17:      <authorization>
  18:        <deny users="?" />
  19:      </authorization>
  20:       <membership defaultProvider="WebConfigMembershipProvider">
  21:        <providers >
  22:          <clear/>
  23:          <add name="WebConfigMembershipProvider" type="WebConfigMembershipProvider"/>
  24:         </providers>
  25:      </membership>
  26:      <profile>
  27:        <providers>
  28:          <clear/>
  29:          <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
  30:        </providers>
  31:      </profile>
  32:      <roleManager enabled="false">
  33:        <providers>
  34:          <clear/>
  35:          <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/"/>
  36:          <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/"/>
  37:        </providers>
  38:      </roleManager>
  39:    </system.web>
  40:    <system.webServer>
  41:      <modules runAllManagedModulesForAllRequests="true"/>
  42:    </system.webServer>
  43:  ....
  44:  </configuration>

Таким чином перша форма для незалогіненого юзера буде виглядати ось так:



Для новачків може бути питання, а звідки зьявилося щось взагалі у каталогі Account, зокрема форма Login? Справа в тому, що ця форма утворюється автоматично при утворенні ASP.NET проєкту:



Зверніть увагу, що папка Account має свій власний конфіг, акий дозволяе неаутентфікованому юзеру заходити до форми Register.


   1:  <?xml version="1.0"?>
   2:  <configuration>
   3:   
   4:    <location path="Register.aspx">
   5:      <system.web>
   6:        <authorization>
   7:          <allow users="*"/>
   8:        </authorization>
   9:      </system.web>
  10:    </location>
  11:   
  12:    <system.web>
  13:      <authorization>
  14:        <deny users="?"/>
  15:      </authorization>
  16:    </system.web>
  17:   
  18:  </configuration>

Але мій сайт (з точки зору безпеки) не має можливісті регістрації нових юзерів, він працює лише по тим самим логінам, які я сам задав йому у конфігі. Тому і сам клас провайдера, до якогу звертається вбудований у ASP.NET контрол на формі Login, виглядає дуже просто, я заповнив в ньому лише деякі методи.


   1:  Imports Microsoft.VisualBasic
   2:  Imports System.Configuration
   3:  Imports System.Web.Configuration
   4:  Imports System.Web.Security
   5:   
   6:  Public Class WebConfigMembershipProvider
   7:      Inherits MembershipProvider
   8:   
   9:      Private _users As FormsAuthenticationUserCollection = Nothing
  10:      Private _passwordFormat As FormsAuthPasswordFormat
  11:   
  12:      Public Overloads Overrides Sub Initialize(name As String, config As System.Collections.Specialized.NameValueCollection)
  13:          MyBase.Initialize(name, config)
  14:          _passwordFormat = getPasswordFormat()
  15:      End Sub
  16:   
  17:      Public Overloads Overrides Function ValidateUser(username As String, password As String) As Boolean
  18:          Dim user = getUsers()(username)
  19:          If user Is Nothing Then
  20:              Return False
  21:          End If
  22:   
  23:          If _passwordFormat = FormsAuthPasswordFormat.Clear Then
  24:              If user.Password = password Then
  25:                  Return True
  26:              End If
  27:          Else
  28:              If user.Password = FormsAuthentication.HashPasswordForStoringInConfigFile(password, _passwordFormat.ToString()) Then
  29:                  Return True
  30:              End If
  31:          End If
  32:   
  33:          Return False
  34:      End Function
  35:   
  36:      Protected Function getUsers() As FormsAuthenticationUserCollection
  37:          If _users Is Nothing Then
  38:              Dim section As AuthenticationSection = getAuthenticationSection()
  39:              Dim creds As FormsAuthenticationCredentials = section.Forms.Credentials
  40:              _users = section.Forms.Credentials.Users
  41:          End If
  42:          Return _users
  43:      End Function
  44:   
  45:      Protected Function getAuthenticationSection() As AuthenticationSection
  46:          Dim config As Configuration = WebConfigurationManager.OpenWebConfiguration("~")
  47:          Return DirectCast(config.GetSection("system.web/authentication"), AuthenticationSection)
  48:      End Function
  49:   
  50:      Protected Function getPasswordFormat() As FormsAuthPasswordFormat
  51:          Return getAuthenticationSection().Forms.Credentials.PasswordFormat
  52:      End Function
  53:   
  54:      Public Overrides Property ApplicationName As String
  55:          Get
  56:   
  57:          End Get
  58:          Set(value As String)
  59:   
  60:          End Set
  61:      End Property
  62:   
  63:      Public Overrides Function ChangePassword(username As String, oldPassword As String, newPassword As String) As Boolean
  64:   
  65:      End Function
  66:   
  67:      Public Overrides Function ChangePasswordQuestionAndAnswer(username As String, password As String, newPasswordQuestion As String, newPasswordAnswer As String) As Boolean
  68:   
  69:      End Function
  70:   
  71:      Public Overrides Function CreateUser(username As String, password As String, email As String, passwordQuestion As String, passwordAnswer As String, isApproved As Boolean, providerUserKey As Object, ByRef status As System.Web.Security.MembershipCreateStatus) As System.Web.Security.MembershipUser
  72:   
  73:      End Function
  74:   
  75:      Public Overrides Function DeleteUser(username As String, deleteAllRelatedData As Boolean) As Boolean
  76:   
  77:      End Function
  78:   
  79:      Public Overrides ReadOnly Property EnablePasswordReset As Boolean
  80:          Get
  81:   
  82:          End Get
  83:      End Property
  84:   
  85:      Public Overrides ReadOnly Property EnablePasswordRetrieval As Boolean
  86:          Get
  87:   
  88:          End Get
  89:      End Property
  90:   
  91:      Public Overrides Function FindUsersByEmail(emailToMatch As String, pageIndex As Integer, pageSize As Integer, ByRef totalRecords As Integer) As System.Web.Security.MembershipUserCollection
  92:   
  93:      End Function
  94:   
  95:      Public Overrides Function FindUsersByName(usernameToMatch As String, pageIndex As Integer, pageSize As Integer, ByRef totalRecords As Integer) As System.Web.Security.MembershipUserCollection
  96:   
  97:      End Function
  98:   
  99:      Public Overrides Function GetAllUsers(pageIndex As Integer, pageSize As Integer, ByRef totalRecords As Integer) As System.Web.Security.MembershipUserCollection
 100:   
 101:      End Function
 102:   
 103:      Public Overrides Function GetNumberOfUsersOnline() As Integer
 104:   
 105:      End Function
 106:   
 107:      Public Overrides Function GetPassword(username As String, answer As String) As String
 108:   
 109:      End Function
 110:   
 111:      Public Overloads Overrides Function GetUser(providerUserKey As Object, userIsOnline As Boolean) As System.Web.Security.MembershipUser
 112:   
 113:      End Function
 114:   
 115:      Public Overloads Overrides Function GetUser(username As String, userIsOnline As Boolean) As System.Web.Security.MembershipUser
 116:   
 117:      End Function
 118:   
 119:      Public Overrides Function GetUserNameByEmail(email As String) As String
 120:   
 121:      End Function
 122:   
 123:      Public Overrides ReadOnly Property MaxInvalidPasswordAttempts As Integer
 124:          Get
 125:   
 126:          End Get
 127:      End Property
 128:   
 129:      Public Overrides ReadOnly Property MinRequiredNonAlphanumericCharacters As Integer
 130:          Get
 131:   
 132:          End Get
 133:      End Property
 134:   
 135:      Public Overrides ReadOnly Property MinRequiredPasswordLength As Integer
 136:          Get
 137:   
 138:          End Get
 139:      End Property
 140:   
 141:      Public Overrides ReadOnly Property PasswordAttemptWindow As Integer
 142:          Get
 143:   
 144:          End Get
 145:      End Property
 146:   
 147:      Public Overrides ReadOnly Property PasswordFormat As System.Web.Security.MembershipPasswordFormat
 148:          Get
 149:   
 150:          End Get
 151:      End Property
 152:   
 153:      Public Overrides ReadOnly Property PasswordStrengthRegularExpression As String
 154:          Get
 155:   
 156:          End Get
 157:      End Property
 158:   
 159:      Public Overrides ReadOnly Property RequiresQuestionAndAnswer As Boolean
 160:          Get
 161:   
 162:          End Get
 163:      End Property
 164:   
 165:      Public Overrides ReadOnly Property RequiresUniqueEmail As Boolean
 166:          Get
 167:   
 168:          End Get
 169:      End Property
 170:   
 171:      Public Overrides Function ResetPassword(username As String, answer As String) As String
 172:   
 173:      End Function
 174:   
 175:      Public Overrides Function UnlockUser(userName As String) As Boolean
 176:   
 177:      End Function
 178:   
 179:      Public Overrides Sub UpdateUser(user As System.Web.Security.MembershipUser)
 180:   
 181:      End Sub
 182:  End Class

Методи пусті, бо утворюються вони самі, як тільки вводиш Public Overloads Overrides Sub Initialize і клацаєш Enter, всі необхідні методи студія утворить самостійно. А щоб написати ці декілька дуже важливих стрічок у цьому класі, я подивився у дебагері порядок виклику методів, та що до них приходить у переметрах, коли вони виклакаються з середовища ASP.NET.




2. Доступ до даних зі сторінки Excel.

Сайтік, який я зробив, потребує доступа до даних на сторінці Excel. Для того, щоб досягнути це у середовище ASP.NET потрібно зробити наступні кроки:


Я зробив цей сайт таким чином, на першій формі лише загружаеться всі дані з листа Excel та зберігаютья у Session. Тобто форма має лише три контрола.



Код форми набагато цікавіший, у ньому ви можете побачити весь механізм запросу до сторінок Excel за допомогою провайдерів Microsoft.Jet.OLEDB.4.0 та Microsoft.ACE.OLEDB.12.0.


   1:  Partial Class _Default
   2:      Inherits System.Web.UI.Page
   3:   
   4:      Public SessionName As String
   5:      Dim DT As Data.DataTable
   6:   
   7:      Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
   8:          If Not IsPostBack Then
   9:              If Session("SessionName") IsNot Nothing And Session("DT") IsNot Nothing Then
  10:                  Dim DT As Data.DataTable = DirectCast(Session("DT"), Data.DataTable)
  11:                  GridView1.DataSource = DT
  12:                  GridView1.DataBind()
  13:              End If
  14:          End If
  15:      End Sub
  16:   
  17:   
  18:      Protected Sub btnUpload_Click(sender As Object, e As System.EventArgs) Handles btnUpload.Click
  19:          If FileUpload1.HasFile Then
  20:              Try
  21:                  SessionName = Guid.NewGuid.ToString
  22:                  Dim FileName As String = SessionName
  23:                  Dim Extension As String = IO.Path.GetExtension(FileUpload1.PostedFile.FileName)
  24:                  Dim FolderPath As String = ConfigurationManager.AppSettings("FolderPath")
  25:                  Dim FilePath As String = Server.MapPath(FolderPath + FileName)
  26:                  FileUpload1.SaveAs(FilePath)
  27:                  Import_To_Grid(FilePath, Extension)
  28:              Catch ex As Exception
  29:                  lErr1.Text = ex.Message
  30:              End Try
  31:          End If
  32:      End Sub
  33:   
  34:      Private Sub Import_To_Grid(ByVal FilePath As String, ByVal Extension As String)
  35:          Dim conStr As String = ""
  36:          Select Case Extension
  37:              Case ".xls"
  38:                  'Excel 97-03
  39:                  conStr = ConfigurationManager.ConnectionStrings("Excel03ConString").ConnectionString()
  40:              Case ".xlsx"
  41:                  'Excel 07
  42:                  conStr = ConfigurationManager.ConnectionStrings("Excel07ConString").ConnectionString()
  43:          End Select
  44:          conStr = String.Format(conStr, FilePath)
  45:          Dim connExcel As New Data.OleDb.OleDbConnection(conStr)
  46:          Dim cmdExcel As New Data.OleDb.OleDbCommand()
  47:          cmdExcel.Connection = connExcel
  48:          'Get the name of First Sheet
  49:          connExcel.Open()
  50:          Dim dtExcelSchema As Data.DataTable
  51:          dtExcelSchema = connExcel.GetOleDbSchemaTable(Data.OleDb.OleDbSchemaGuid.Tables, Nothing)
  52:          Dim SheetName As String = dtExcelSchema.Rows(0)("TABLE_NAME").ToString()
  53:          connExcel.Close()
  54:          'Read Data from First Sheet
  55:          connExcel.Open()
  56:          cmdExcel.CommandText = "SELECT * From [" & SheetName & "]"
  57:          'fill data to DataAdapter
  58:          Dim DA As New Data.OleDb.OleDbDataAdapter
  59:          DT = New Data.DataTable
  60:          DA.SelectCommand = cmdExcel
  61:          DT.Columns.Add("Num")
  62:          DA.Fill(DT)
  63:          connExcel.Close()
  64:          DT.Columns.Add("Result")
  65:          DT.Columns.Add("ResultDate")
  66:          '
  67:          For i As Integer = 0 To DT.Rows.Count - 1
  68:              DT.Rows(i)(0) = i
  69:          Next
  70:          'Bind Data to GridView
  71:          'GridView1.Caption = IO.Path.GetFileName(FilePath)
  72:          GridView1.DataSource = DT
  73:          GridView1.DataBind()
  74:          '
  75:          Session("SessionName") = SessionName
  76:          Session("DT") = DT
  77:      End Sub
  78:   
  79:      Protected Sub PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs)
  80:          Dim FolderPath As String = ConfigurationManager.AppSettings("FolderPath")
  81:          Dim FileName As String = GridView1.Caption
  82:          Dim Extension As String = IO.Path.GetExtension(FileName)
  83:          Dim FilePath As String = Server.MapPath(FolderPath + FileName)
  84:          Import_To_Grid(FilePath, Extension)
  85:          GridView1.PageIndex = e.NewPageIndex
  86:          GridView1.DataBind()
  87:      End Sub
  88:   
  89:   
  90:  End Class

На чьому скрині DataTable можна побачити, що дані прочитались досить коректно, якщо не рахувати першу колонку, яку провайдер вважає за назву колонки.



А ось у зворотньому напрямку - зі свого сайта в Excel я роблю звичайно через CSV:



   1:   
   2:  Partial Class Result
   3:      Inherits System.Web.UI.Page
   4:   
   5:      Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
   6:          If Not IsPostBack Then
   7:              If Session("SessionName") IsNot Nothing And Session("DT") IsNot Nothing Then
   8:                  lId.Text = Session("SessionName")
   9:                  lRow.Text = DirectCast(Session("DT"), Data.DataTable).Rows.Count - 1
  10:              Else
  11:                  Response.Redirect("Default.aspx")
  12:              End If
  13:          End If
  14:      End Sub
  15:   
  16:      Protected Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
  17:          If Session("SessionName") IsNot Nothing And Session("DT") IsNot Nothing Then
  18:              Dim DT As Data.DataTable = DirectCast(Session("DT"), Data.DataTable)
  19:              Dim SessionName As String = Session("SessionName")
  20:              Dim Fname As String = "Report_" & Now.ToString("yyMMdd_HHmm", Globalization.CultureInfo.InvariantCulture)
  21:              '
  22:              Dim SB = New StringBuilder()
  23:              For Each OneRow As Data.DataRow In DT.Rows
  24:                  SB.AppendLine(OneLineFromRow(OneRow))
  25:              Next
  26:              '
  27:              HttpContext.Current.Response.Clear()
  28:              HttpContext.Current.Response.ClearHeaders()
  29:              HttpContext.Current.Response.ClearContent()
  30:              HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" & Fname & ".csv")
  31:              HttpContext.Current.Response.ContentType = "text/csv"
  32:              HttpContext.Current.Response.ContentEncoding = Encoding.GetEncoding("Windows-1251")
  33:              HttpContext.Current.Response.Write(SB.ToString())
  34:              HttpContext.Current.Response.Flush()
  35:              HttpContext.Current.Response.End()
  36:          End If
  37:      End Sub
  38:   
  39:      Function OneLineFromRow(OneRow As Data.DataRow) As String
  40:          Dim CsvRow As New StringBuilder()
  41:          For j As Integer = 0 To OneRow.Table.Columns.Count - 1
  42:              If j <> 0 Then
  43:                  CsvRow.Append(",")
  44:              End If
  45:              Dim ColumnValue As Object = OneRow(j)
  46:              If ColumnValue Is Nothing Then
  47:                  CsvRow.Append("")
  48:              Else
  49:                  Dim ColumnStringValue As String = ColumnValue.ToString()
  50:                  Dim CleanedColumnValue As String = CleanCSVString(ColumnStringValue)
  51:                  If ColumnValue.[GetType]() = GetType(String) AndAlso Not columnStringValue.Contains(",") Then
  52:                      ' Prevents a number stored in a string from being shown as 8888E+24 in Excel. Example use is the AccountNum field in CI that looks like a number but is really a string.
  53:                      CleanedColumnValue = CleanedColumnValue
  54:                  End If
  55:                  CsvRow.Append(cleanedColumnValue)
  56:              End If
  57:          Next
  58:          Return CsvRow.ToString
  59:      End Function
  60:   
  61:      Function CleanCSVString(input As String) As String
  62:          Return """" + input.Replace("""", """""").Replace(vbCr & vbLf, " ").Replace(vbCr, " ").Replace(vbLf, "") + """"
  63:      End Function
  64:  End Class

3. Трекінг почтових відправлень.

Ну і останне питання цього невеличкого сайтіку, яким чином приконенктись до сервісу трекінга почтових відправлень і як з ним працювати. Зверніть увагу, що це загальни засоби, точно таким чином можна працювати, наприклад, і з UPS World Wide.

Поперше, я поставив у своєї програмі лінк на зовнішни сервіс трекінга і отримав опис зовнішнього web-сервісу.



Подруге, я подивився на дані, яки мені видає сервіс.



А далі вже зробив ось таку форму, яка дозволяе оператору побачити корректність завантаження Excel-Файла та почати роботу з якогось місяця.



Самє код цієї форми звертається до почтового web-сервісу і робить трекінг почтових відправлень. Результат трекінгу код цієї форми вписує у заздалегідь підготувану колонку.


   1:   
   2:  Partial Class Result
   3:      Inherits System.Web.UI.Page
   4:   
   5:      Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
   6:          If Not IsPostBack Then
   7:              If Session("SessionName") IsNot Nothing And Session("DT") IsNot Nothing Then
   8:                  lId.Text = Session("SessionName")
   9:                  lRow.Text = DirectCast(Session("DT"), Data.DataTable).Rows.Count - 1
  10:              Else
  11:                  Response.Redirect("Default.aspx")
  12:              End If
  13:          End If
  14:      End Sub
  15:   
  16:      Protected Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
  17:          If Session("SessionName") IsNot Nothing And Session("DT") IsNot Nothing Then
  18:              Dim DT As Data.DataTable = DirectCast(Session("DT"), Data.DataTable)
  19:              Dim SessionName As String = Session("SessionName")
  20:              Dim Fname As String = "Report_" & Now.ToString("yyMMdd_HHmm", Globalization.CultureInfo.InvariantCulture)
  21:              '
  22:              Dim SB = New StringBuilder()
  23:              For Each OneRow As Data.DataRow In DT.Rows
  24:                  SB.AppendLine(OneLineFromRow(OneRow))
  25:              Next
  26:              '
  27:              HttpContext.Current.Response.Clear()
  28:              HttpContext.Current.Response.ClearHeaders()
  29:              HttpContext.Current.Response.ClearContent()
  30:              HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" & Fname & ".csv")
  31:              HttpContext.Current.Response.ContentType = "text/csv"
  32:              HttpContext.Current.Response.ContentEncoding = Encoding.GetEncoding("Windows-1251")
  33:              HttpContext.Current.Response.Write(SB.ToString())
  34:              HttpContext.Current.Response.Flush()
  35:              HttpContext.Current.Response.End()
  36:          End If
  37:      End Sub
  38:   
  39:      Function OneLineFromRow(OneRow As Data.DataRow) As String
  40:          Dim CsvRow As New StringBuilder()
  41:          For j As Integer = 0 To OneRow.Table.Columns.Count - 1
  42:              If j <> 0 Then
  43:                  CsvRow.Append(",")
  44:              End If
  45:              Dim ColumnValue As Object = OneRow(j)
  46:              If ColumnValue Is Nothing Then
  47:                  CsvRow.Append("")
  48:              Else
  49:                  Dim ColumnStringValue As String = ColumnValue.ToString()
  50:                  Dim CleanedColumnValue As String = CleanCSVString(ColumnStringValue)
  51:                  If ColumnValue.[GetType]() = GetType(String) AndAlso Not columnStringValue.Contains(",") Then
  52:                      ' Prevents a number stored in a string from being shown as 8888E+24 in Excel. Example use is the AccountNum field in CI that looks like a number but is really a string.
  53:                      CleanedColumnValue = CleanedColumnValue
  54:                  End If
  55:                  CsvRow.Append(cleanedColumnValue)
  56:              End If
  57:  Partial Class Process
  58:      Inherits System.Web.UI.Page
  59:   
  60:      Public SessionName As String
  61:      Dim DT As Data.DataTable
  62:   
  63:      Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
  64:          If Not IsPostBack Then
  65:              SrvLogin.Text = System.Configuration.ConfigurationManager.AppSettings("ServiceLogin").ToString
  66:              SrvPass.Text = System.Configuration.ConfigurationManager.AppSettings("ServicetPass").ToString
  67:              If Session("SessionName") IsNot Nothing And Session("DT") IsNot Nothing Then
  68:                  SessionName = Session("SessionName")
  69:                  lId.Text = SessionName
  70:                  DT = DirectCast(Session("DT"), Data.DataTable)
  71:                  lRow.Text = DT.Rows.Count - 1
  72:                  ToRow.Text = 10
  73:                  For j As Integer = 0 To DT.Columns.Count - 1
  74:                      Dim ColumnValue1 As Object = DT.Rows(1)(j)
  75:                      Dim ColumnValue2 As Object = DT.Rows(2)(j)
  76:                      Dim ColumnValue3 As Object = DT.Rows(3)(j)
  77:                      Dim ColumnStringValue1 As String = ColumnValue1.ToString()
  78:                      Dim ColumnStringValue2 As String = ColumnValue2.ToString()
  79:                      Dim ColumnStringValue3 As String = ColumnValue3.ToString()
  80:                      If ColumnStringValue1.Length = 14 And ColumnStringValue2.Length = 14 And ColumnStringValue3.Length = 14 Then
  81:                          ColumnNum.Text = j
  82:                          ColumnNum.Enabled = False
  83:                      End If
  84:                  Next
  85:              Else
  86:                  Response.Redirect("Default.aspx")
  87:              End If
  88:          End If
  89:      End Sub
  90:   
  91:      Protected Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
  92:          If Session("SessionName") IsNot Nothing And Session("DT") IsNot Nothing Then
  93:              DT = DirectCast(Session("DT"), Data.DataTable)
  94:              lErr1.Text = ""
  95:              Try
  96:                  '
  97:                  Dim X As New PostTrackingSingle.OperationHistory12Client
  98:                  Dim PostRequest As New PostTrackingSingle.OperationHistoryRequest
  99:                  Dim PostHeader As New PostTrackingSingle.AuthorizationHeader
 100:                  PostHeader.login = SrvLogin.Text
 101:                  PostHeader.password = SrvPass.Text
 102:                  For i As Integer = CInt(FromRow.Text) To Math.Min(DT.Rows.Count - 1, CInt(ToRow.Text))
 103:                      PostRequest.Barcode = DT.Rows(i)(CInt(ColumnNum.Text))
 104:                      Try
 105:                          Dim Y As PostTrackingSingle.OperationHistoryRecord() = X.getOperationHistory(PostRequest, PostHeader)
 106:                          If Y IsNot Nothing Then
 107:                              If Y.Count > 0 Then
 108:                                  Dim LastOper As PostTrackingSingle.OperationParameters = Y(Y.Count - 1).OperationParameters
 109:                                  If LastOper.OperType.Name = "Вручение" Then
 110:                                      DT.Rows(i)(DT.Columns.Count - 2) = "Вручение"
 111:                                      DT.Rows(i)(DT.Columns.Count - 1) = LastOper.OperDate.ToString(Globalization.CultureInfo.GetCultureInfo("RU-ru"))
 112:                                  Else
 113:                                      DT.Rows(i)(DT.Columns.Count - 2) = LastOper.OperType.Name
 114:                                      DT.Rows(i)(DT.Columns.Count - 1) = LastOper.OperDate.ToString(Globalization.CultureInfo.GetCultureInfo("RU-ru"))
 115:                                  End If
 116:                              End If
 117:                          End If
 118:                      Catch ex As System.ServiceModel.FaultException
 119:                          lErr1.Text = lErr1.Text & "<br>" & PostRequest.Barcode & ":" & ex.Message
 120:                      End Try
 121:                      'PostRequest.Barcode = "14001207332324"
 122:                      System.Threading.Thread.Sleep(CInt(Delay.Text) * 100)
 123:                  Next
 124:              Catch ex As Exception
 125:                  lErr1.Text = ex.Message
 126:              End Try
 127:              '
 128:              GridView1.DataSource = DT
 129:              GridView1.DataBind()
 130:          Else
 131:              lErr1.Text = lErr1.Text & "session experied"
 132:          End If
 133:   
 134:      End Sub
 135:   
 136:      Protected Sub PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs)
 137:          GridView1.DataSource = DirectCast(Session("DT"), Data.DataTable)
 138:          GridView1.PageIndex = e.NewPageIndex
 139:          GridView1.DataBind()
 140:      End Sub
 141:  End Class
 142:   
 143:          Next
 144:          Return CsvRow.ToString
 145:      End Function
 146:   
 147:      Function CleanCSVString(input As String) As String
 148:          Return """" + input.Replace("""", """""").Replace(vbCr & vbLf, " ").Replace(vbCr, " ").Replace(vbLf, "") + """"
 149:      End Function
 150:  End Class

Цей код потім декілька разів поліпшувався, але це не важливо, принципова основа (1) роботи з сервісами, (2) з провайдером, та (3) з Excel, яку ви бачите на цієї сторінці, була зроблена за один день і вже більше не змінувалася.





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