Я пытаюсь использовать службу Windows для запуска в полночь каждый день, а затем проверяет таблицу SQL, чтобы увидеть, соответствуют ли даты будущих транзакций сегодняшней дате. Затем предполагается получить эти записи как объекты и отправляет их в другую службу для обработки. Однако, прежде чем я даже дошел до этого шага, я получаю некоторые странные ошибки из службы Windows в своем журнале ошибок, что я не уверен, как правильно отлаживать или сузить то, что происходит.Свойства службы Windows ConnectionString не были инициализированы?
Сначала я просто получил типичную ошибку инициализатора типа с классами, которые я вызывал в службе Windows, до тех пор, пока я не изменил свой журнал ошибок, чтобы включить внутреннее исключение, и теперь это выглядит как проблема, инициализирующая connectionString, хотя Я сейчас вызывал строку подключения непосредственно в моей службе Windows.
Я не уверен, почему у него возникнут проблемы с строкой соединения, когда я создаю новый SQLConnection со строкой открытого текста, существует ли какая-то ошибка перевода между моей службой Windows и остальной частью моего решения ?
Вот мой Windows Service Code:
Imports System.IO
Imports System.Threading
Imports System.Configuration
Imports Afi.BusinessObjects.Billing
Imports System.Data.SqlClient
Public Class Service1
Protected Overrides Sub OnStart(ByVal args() As String)
' Add code here to start your service. This method should set things
' in motion so your service can do its work.
Dim PaymentsToBeProcessed As New FuturePaymentsCollection
Me.WriteToFile("Future Transaction Processor started at " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt"))
Try
PaymentsToBeProcessed = GetFutureTransactionsByDate(DateTime.Now.Date)
Dim ProcessedPaymentsString As String = String.Format("{0} payments were processed during this session.", PaymentsToBeProcessed.Count)
Me.WriteToFile(ProcessedPaymentsString)
Catch ex As Exception
If Not ex.InnerException Is Nothing Then
WriteToFile("Future Transaction Processing Error on: {0} " + ex.Message + ex.StackTrace + ex.InnerException.ToString())
Else
'Log any errors we get.
WriteToFile("Future Transaction Processing Error on: {0} " + ex.Message + ex.StackTrace)
End If
End Try
Me.ScheduleService()
End Sub
Protected Overrides Sub OnStop()
' Add code here to perform any tear-down necessary to stop your service.
Me.WriteToFile("Future Transaction Processor stopped at " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt"))
Me.Schedular.Dispose()
End Sub
Protected mFuturePayment As AFI.BusinessObjects.Billing.FuturePayment
Public Property Payment() As AFI.BusinessObjects.Billing.FuturePayment
Get
Return mFuturePayment
End Get
Set(ByVal value As AFI.BusinessObjects.Billing.FuturePayment)
mFuturePayment = value
End Set
End Property
Private Schedular As Timer
Public Sub ScheduleService()
Try
'Initialize a new Timer called Schedular and give it the callback of SchedularCallback
Schedular = New Timer(New TimerCallback(AddressOf SchedularCallback))
'Set our run mode as daily, so the service will run itself every day.
Dim runMode As String = "DAILY"
'Sets scheduledTime to a DateTime value
Dim scheduledTime As DateTime = DateTime.MinValue
If runMode = "DAILY" Then
'Gets our scheduled time from the app settings if the mode is equal to Daily and sets it equal to ScheduledTime
scheduledTime = DateTime.Parse("09:20")
'If the time has already been passed then we'll schedule our service to run for tomorrow at the same time previously set.
If DateTime.Now > scheduledTime Then
scheduledTime = scheduledTime.AddDays(1)
End If
End If
'Gets the difference in time between now and the scheduled time for the service to run.
Dim timeSpan As TimeSpan = scheduledTime.Subtract(DateTime.Now)
'Creates a string of our timeSpan to the next time the service should run.
Dim schedule As String = String.Format("{0} day(s) {1} hour(s) {2} minute(s) {3} seconds", timeSpan.Days, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds)
'Prints our next scheduled run to our log file.
Me.WriteToFile((Convert.ToString("Future Transaction Processor scheduled to run after: ") & schedule) + " {0}")
'Get the difference in milliseconds between the Scheduled and Current Time.
Dim dueTime As Integer = Convert.ToInt32(timeSpan.TotalMilliseconds)
'Change the Timer's Due Time
Schedular.Change(dueTime, Timeout.Infinite)
'If there are any errors write them to the log.
Catch ex As Exception
WriteToFile("Future Transaction Error on: {0} " + ex.Message + ex.StackTrace)
'Stop the Windows Service
Using serviceController As New System.ServiceProcess.ServiceController("FutureTransactionProcessor")
serviceController.[Stop]()
End Using
End Try
End Sub
Public Shared Function GetFutureTransactionsByDate(ByVal dateToday As DateTime) As FuturePaymentsCollection
Dim FuturePaymentsToBeProcessed As FuturePaymentsCollection = New FuturePaymentsCollection
Using cnSQL As SqlConnection = New SqlConnection("Server=rdbashq01;Database=AFI_SYSTEM;User ID=*****;Password=****;Trusted_Connection=False;")
Using cmdSP As New SqlCommand("PROC_FUTURE_TRANSACTIONS_SEL_BY_TODAY", cnSQL)
cmdSP.CommandType = System.Data.CommandType.StoredProcedure
cmdSP.Parameters.AddWithValue("DATETODAY", dateToday)
cmdSP.Connection.Open()
Dim sqlReader As SqlDataReader = cmdSP.ExecuteReader()
If sqlReader.HasRows Then
While (sqlReader.Read())
Dim futurePayment As New FuturePayment
futurePayment.FutureTransactionID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_TRANSACTION_ID"))
futurePayment.GroupID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_CNTC_GROUP_ID"))
futurePayment.PayorAccountID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_PAYOR_ACCOUNT_ID"))
futurePayment.PolicyID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_POLICY_ID"))
futurePayment.AccountTypeID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_ACCOUNT_TYPE_ID"))
futurePayment.TransationTypeID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_TRANSACTION_TYPE_ID"))
futurePayment.TransactionDate = sqlReader.GetDateTime(sqlReader.GetOrdinal("BMW_TRANSACTION_DATE")).ToString("MM/dd/yyyy")
futurePayment.TransactionSubmitter = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_TRANSACTION_SUBMITTER"))
futurePayment.TransactionAmount = sqlReader.GetDecimal(sqlReader.GetOrdinal("BMW_TRANSACTION_AMOUNT"))
futurePayment.TransactionLast4 = sqlReader.GetString(sqlReader.GetOrdinal("BMW_TRANSACTION_LAST4"))
futurePayment.TransactionEmail = sqlReader.GetString(sqlReader.GetOrdinal("BMW_TRANSACTION_EMAIL"))
futurePayment.PaymentInfo1 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo1"))
futurePayment.PaymentInfo2 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo2"))
futurePayment.PaymentInfo3 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo3"))
futurePayment.PaymentInfo4 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo4"))
futurePayment.PaymentInfo5 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo5"))
futurePayment.PaymentInfo6 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo6"))
futurePayment.TransactionUpdateDate = sqlReader.GetDateTime(sqlReader.GetOrdinal("BMW_TRANSACTION_UPDATE_DATE"))
FuturePaymentsToBeProcessed.Add(futurePayment)
End While
End If
cmdSP.Connection.Close()
End Using
End Using
For Each Payment As FuturePayment In FuturePaymentsToBeProcessed
Dim PaymentToBeProcessed As OneTimePayment
PaymentToBeProcessed.PayorAccountId = Payment.PayorAccountID
PaymentToBeProcessed.PolicyID = Payment.PolicyID
PaymentToBeProcessed.AccountTypeID = Payment.AccountTypeID
PaymentToBeProcessed.PayTypeID = 1
PaymentToBeProcessed.BankInfoName = Payment.PaymentInfo1
PaymentToBeProcessed.BankInfoRoutingNum = Payment.PaymentInfo2
PaymentToBeProcessed.BankInfoAccountNum = Payment.PaymentInfo3
If PaymentToBeProcessed.BankInfoAccountNum >= 4 Then
PaymentToBeProcessed.Last4 = PaymentToBeProcessed.BankInfoAccountNum.Substring(PaymentToBeProcessed.BankInfoAccountNum.Length - 4, 4)
Else
PaymentToBeProcessed.Last4 = "XXXX"
End If
PaymentToBeProcessed.TransactionTypeID = 1
PaymentToBeProcessed.Email = Payment.TransactionEmail
PaymentToBeProcessed.TransactionAmount = Payment.TransactionAmount
PaymentToBeProcessed.Save()
PaymentToBeProcessed.SendPaymentToGateway()
'Run our method to remove the future payment from the Future_Transactions table and enter it into the Future_transactions_History table as processed
Payment.ProcessFuturePayment(Payment.FutureTransactionID)
Next
Return FuturePaymentsToBeProcessed
End Function
Private Sub SchedularCallback(e As Object)
Me.WriteToFile("Future Transaction Log: " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt"))
Me.ScheduleService()
End Sub
Private Sub WriteToFile(text As String)
Dim path As String = "C:\FutureTransactionLog.txt"
Using writer As New StreamWriter(path, True)
writer.WriteLine(String.Format(text, DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt")))
writer.Close()
End Using
End Sub
End Class
Следующая ниже мой стек след ... Я считаю, что моя проблема заключается в csla.DataPortalException: DataPortal.Fetc не удалось (System.InvalidOperationException: ConnectionString свойство не инициализирован.)
Future Transaction Processor stopped at 12/10/2015 10:49:23 AM
Future Transaction Processor started at 12/10/2015 10:49:46 AM
Future Transaction Processing Error on: 12/10/2015 10:49:46 AM The type initializer for 'AFI.BusinessObjects.Billing.FuturePayment' threw an exception. at AFI.BusinessObjects.Billing.FuturePayment..ctor()
at FutureTransactionProcessor.Service1.GetFutureTransactionsByDate(DateTime dateToday) in C:\TFS ITD\Console\Main\Source\FutureTransactionProcessor\Service1.vb:line 159
at FutureTransactionProcessor.Service1.OnStart(String[] args) in C:\TFS ITD\Console\Main\Source\FutureTransactionProcessor\Service1.vb:line 27Csla.DataPortalException: DataPortal.Fetch failed (System.InvalidOperationException: The ConnectionString property has not been initialized.
at System.Data.SqlClient.SqlConnection.PermissionDemand()
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at Afi.Data.ConnectionManager.ExecuteQuery(String Query) in C:\TFS ITD\Console\Main\Source\AFI\Data\ConnectionManager.vb:line 20
at Afi.Configuration.SystemSetting.SystemSettingsCollection.DataPortal_Fetch(Object v_Criteria) in C:\TFS ITD\Console\Main\Source\AFI\Configuration\SystemSettings.vb:line 169) ---> Csla.Server.CallMethodException: DataPortal_Fetch method call failed ---> System.InvalidOperationException: The ConnectionString property has not been initialized.
at System.Data.SqlClient.SqlConnection.PermissionDemand()
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at Afi.Data.ConnectionManager.ExecuteQuery(String Query) in C:\TFS ITD\Console\Main\Source\AFI\Data\ConnectionManager.vb:line 20
at Afi.Configuration.SystemSetting.SystemSettingsCollection.DataPortal_Fetch(Object v_Criteria) in C:\TFS ITD\Console\Main\Source\AFI\Configuration\SystemSettings.vb:line 169
--- End of inner exception stack trace ---
at System.Data.SqlClient.SqlConnection.PermissionDemand()
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at Afi.Data.ConnectionManager.ExecuteQuery(String Query) in C:\TFS ITD\Console\Main\Source\AFI\Data\ConnectionManager.vb:line 20
at Afi.Configuration.SystemSetting.SystemSettingsCollection.DataPortal_Fetch(Object v_Criteria) in C:\TFS ITD\Console\Main\Source\AFI\Configuration\SystemSettings.vb:line 169
at Csla.MethodCaller.CallMethod(Object obj, MethodInfo info, Object[] parameters)
at Csla.Server.SimpleDataPortal.Fetch(Type objectType, Object criteria, DataPortalContext context)
--- End of inner exception stack trace ---
at System.Data.SqlClient.SqlConnection.PermissionDemand()
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at Afi.Data.ConnectionManager.ExecuteQuery(String Query) in C:\TFS ITD\Console\Main\Source\AFI\Data\ConnectionManager.vb:line 20
at Afi.Configuration.SystemSetting.SystemSettingsCollection.DataPortal_Fetch(Object v_Criteria) in C:\TFS ITD\Console\Main\Source\AFI\Configuration\SystemSettings.vb:line 169
at Csla.MethodCaller.CallMethod(Object obj, MethodInfo info, Object[] parameters)
at Csla.Server.SimpleDataPortal.Fetch(Type objectType, Object criteria, DataPortalContext context)
at Csla.DataPortal.Fetch(Type objectType, Object criteria)
at Csla.DataPortal.Fetch[T](Object criteria)
at Afi.Configuration.SystemSetting.get_Collection() in C:\TFS ITD\Console\Main\Source\AFI\Configuration\SystemSettings.vb:line 97
at Afi.Security.SecSystem.get_Collection() in C:\TFS ITD\Console\Main\Source\AFI\Security\SecSystem.vb:line 127
at Afi.Security.AFISecurityIdentifier.LoadObjects() in C:\TFS ITD\Console\Main\Source\AFI\Security\AFISecurityIdentifier.vb:line 21
at AFI.BusinessObjects.Billing.FuturePayment..cctor() in C:\TFS ITD\Console\Main\Source\AFI_BusinessObjects\Billing\FuturePayment.vb:line 26
Если я правильно понять этот проект не может создать свою строку соединения для извлечения данных из SQL? Может кто-то, пожалуйста, помогите мне понять больше о том, что происходит, или помочь мне сузить место, где можно устранить эту проблему? Мне также предложила одна из наших более старших разработчиков, возможно, мне нужно просто использовать службу Windows для запуска методов и поместить все эти методы в веб-службу, а не ... устранить все эти проблемы или они работают в службе Windows?
Я могу предоставить более подробную информацию в комментариях ниже, если у кого есть вопросы, чтобы помочь мне определить мою проблему, спасибо заранее!
EDIT 1: Ниже конструктор FuturePayment
#Region " Constructors "
Public Sub New()
End Sub
#End Region
Почему ваша строка соединения жестко закодирована в середине вашего кода? Он должен быть в вашем файле конфигурации. В какой строке происходит исключение? –
Привет, Шон, я попытался добавить файл конфигурации, в котором он динамически перешел к этому, но я получаю все те же ошибки, когда поместил его в app.config под службу Windows. Исключение происходит на этой линии: futurePayment.FutureTransactionID = sqlReader.GetInt32 (sqlReader.GetOrdinal ("BMW_TRANSACTION_ID")) – mcloud313
Вы уверены? Эта строка: Dim futurePayment Поскольку новый FuturePayment выглядит только подозрительно для меня. Что в конструкторе FuturePayment? – Arkadiusz