Imports System.IO Imports System.ServiceModel Imports DigitalData.Modules.EDMI.API.Constants Imports DigitalData.Modules.EDMI.API.EDMIServiceReference Imports DigitalData.Modules.EDMI.API.Rights Imports DigitalData.Modules.Language.Utils Imports DigitalData.Modules.Logging Public Class Client ' Constants Private Const UPDATE_INTERVAL_IN_MINUTES As Integer = 1 Public Const INVALID_OBEJCT_ID As Long = 0 Private Const KIND_TYPE_DOC = "DOC" ' Helper Classes Private ReadOnly LogConfig As LogConfig Private ReadOnly Logger As Logger Private ReadOnly FileEx As Filesystem.File ' Runtime Variables Private ReadOnly ServerAddress As String Private ReadOnly ServerPort As Integer Private ClientConfig As ConfigClientConfiguration ' Channel Private ReadOnly ChannelFactory As ChannelFactory(Of IEDMIServiceChannel) Private Channel As IEDMIServiceChannel ' Update Timer Private WithEvents UpdateTimer As New Timers.Timer ' Public Variables Public CachedTables As New List(Of String) ''' ''' Parse a IPAddress:Port String into its parts ''' ''' Public Shared Function ParseServiceAddress(AddressWithOptionalPort As String) As Tuple(Of String, Integer) Dim oSplit() As String = AddressWithOptionalPort.Split(":"c) Dim oAppServerAddress As String = oSplit(0) Dim oAppServerPort As Integer If oSplit.Length = 2 Then If Integer.TryParse(oSplit(1), oAppServerPort) Then oAppServerPort = DEFAULT_SERVICE_PORT End If Else oAppServerPort = DEFAULT_SERVICE_PORT End If Return New Tuple(Of String, Integer)(oAppServerAddress, oAppServerPort) End Function ''' ''' Creates a new EDMI Client object ''' ''' LogConfig object ''' The IP address/hostname and port, separated by semicolon or colon, ex. 1.2.3.4:9000 Public Sub New(pLogConfig As LogConfig, pServiceAdress As String) LogConfig = pLogConfig Logger = pLogConfig.GetLogger() FileEx = New Filesystem.File(pLogConfig) Dim oServiceAddress As String = pServiceAdress Dim oAddressArray() As String If oServiceAddress.Contains(";") Then oAddressArray = oServiceAddress.Split(";") Else oAddressArray = oServiceAddress.Split(":") End If UpdateTimer.Interval = 60 * 1000 * UPDATE_INTERVAL_IN_MINUTES UpdateTimer.Start() Try ServerAddress = oAddressArray(0) ServerPort = oAddressArray(1) Dim oBinding = API.Channel.GetBinding() Dim oAddress = New EndpointAddress($"net.tcp://{ServerAddress}:{ServerPort}/DigitalData/Services/Main") Dim oFactory = New ChannelFactory(Of IEDMIServiceChannel)(oBinding, oAddress) ChannelFactory = oFactory Catch ex As Exception Logger.Error(ex) End Try End Sub ''' ''' Creates a new EDMI Client object ''' ''' LogConfig object ''' The IP address to connect to ''' The Port number to use for the connection Public Sub New(LogConfig As LogConfig, IPAddress As String, PortNumber As Integer) Me.LogConfig = LogConfig Logger = LogConfig.GetLogger() FileEx = New Filesystem.File(LogConfig) Try ServerAddress = IPAddress Dim oBinding = API.Channel.GetBinding() Dim oAddress = New EndpointAddress($"net.tcp://{IPAddress}:{PortNumber}/DigitalData/Services/Main") Dim oFactory = New ChannelFactory(Of IEDMIServiceChannel)(oBinding, oAddress) Logger.Debug("Connecting to Service at: [{0}]", oAddress) ChannelFactory = oFactory Catch ex As Exception Logger.Error(ex) End Try End Sub ''' ''' Connect to the service ''' ''' True if connection was successful, false otherwise Public Function Connect() As Boolean Try Channel = GetChannel() Logger.Debug("Opening channel..") Channel.Open() Dim oResponse = Channel.GetClientConfig() If oResponse.OK Then ClientConfig = oResponse.ClientConfig Else Logger.Warn("Client Configuration could not be loaded: [{0}]", oResponse.ErrorMessage) End If Logger.Info($"Connection to AppService {ServerAddress} successfully established!") Return True Catch ex As Exception Logger.Error(ex) Return False End Try End Function ''' ''' Aborts the channel and creates a new connection ''' Public Sub Reconnect() Logger.Warn("Connection faulted. Trying to reconnect..") Try Channel.Abort() Channel = GetChannel() Channel.Open() Catch ex As Exception Logger.Error(ex) End Try End Sub Public Function TryGetClientConfig() As ConfigClientConfiguration If ClientConfig Is Nothing Then Throw New ApplicationException("ClientConfig is empty! Please connect to the service before calling this function") End If Return ClientConfig End Function Private Async Function UpdateTimer_Elapsed(sender As Object, e As Timers.ElapsedEventArgs) As Task Handles UpdateTimer.Elapsed Try Dim oTables As String() = Await Channel.GetCachedTablesAsync() CachedTables = oTables. Select(Function(table) table.ToUpper). ToList() Catch ex As Exception Logger.Warn("Update of CachedTable was not successful!") Logger.Error(ex) CachedTables = New List(Of String) End Try End Function ''' ''' Imports a file from a filepath, creating a IDB ObjectId and Filesystem Object ''' ''' Type of ObjectStore. Can be WORK or ARCHIVE. ''' Business entity that the new file object should belong to. ''' Other file import options ''' When local filepath was not found ''' When there was a error in the Service ''' The ObjectId of the newly generated filesystem object Public Async Function NewFileAsync(pFilePath As String, pObjectStoreName As String, pObjectKind As String, pBusinessEntity As String, Optional pImportOptions As Options.NewFileOptions = Nothing) As Task(Of Long) Try ' Set default options If pImportOptions Is Nothing Then pImportOptions = New Options.NewFileOptions() End If ' Check if file exists If File.Exists(pFilePath) = False Then Throw New FileNotFoundException("Path does not exist") End If Dim oFileInfo As New FileInfo(pFilePath) Dim oExtension As String = oFileInfo.Extension Dim oFileName As String = oFileInfo.Name Dim oFileCreatedAt As Date = oFileInfo?.CreationTime Dim oFileModifiedAt As Date = oFileInfo?.LastWriteTime Dim oFileHash As String = FileEx.GetChecksum(oFileInfo.FullName) ' Importing the file now Using oFileStream As New FileStream(pFilePath, FileMode.Open, FileAccess.Read) Using oMemoryStream As New MemoryStream() oFileStream.CopyTo(oMemoryStream) Dim oContents = oMemoryStream.ToArray() Dim oFileImportResponse = Await Channel.NewFileAsync(New NewFileRequest With { .BusinessEntity = pBusinessEntity, .File = New FileProperties With { .FileName = oFileInfo.Name, .FileCreatedAt = oFileCreatedAt, .FileChangedAt = oFileModifiedAt, .FileContents = oContents, .FileImportedAt = pImportOptions.DateImported, .FileChecksum = oFileHash }, .KindType = pObjectKind, .StoreName = pObjectStoreName, .User = New UserState With { .Language = pImportOptions.Language, .UserName = pImportOptions.Username } }) If oFileImportResponse.OK = False Then Throw New ApplicationException("Could not Import File Contents!") End If Return oFileImportResponse.ObjectId End Using End Using Catch ex As Exception Logger.Error(ex) Return INVALID_OBEJCT_ID End Try End Function Public Async Function Globix_ImportFileAsync( pFilePath As String, pProfileId As Integer, pAttributeValues As List(Of UserAttributeValue), pObjectStoreName As String, pObjectKind As String, pBusinessEntity As String, Optional pImportOptions As Options.ImportFileOptions = Nothing) As Task(Of ImportFileResponse) Try Dim oImportFile As New Modules.Globix.ImportFile(LogConfig, Channel) Return Await oImportFile.RunAsync(pFilePath, pProfileId, pAttributeValues, pObjectStoreName, pObjectKind, pBusinessEntity, pImportOptions) Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Function Zooflow_GetFileObject(pObjectId As Long, pLoadFileContents As Boolean) As FileObject Try Dim oGetFileObject As New Modules.Zooflow.GetFileObject(LogConfig, Channel) Dim oFileObject = oGetFileObject.Run(pObjectId, pLoadFileContents) Return oFileObject Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Async Function GetFileObjectAsync(pObjectId As Long, pLoadFileContents As Boolean) As Task(Of FileObject) Try Dim oGetFileObject As New Modules.Zooflow.GetFileObject(LogConfig, Me) Dim oFileObject = Await oGetFileObject.RunAsync(pObjectId, pLoadFileContents) Return oFileObject Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function ''' ''' Sets a value to an attribute ''' ''' IDB ObjectId ''' Name of the attribute ''' ''' ''' Public Function SetVariableValue(pObjectId As Long, pAttributeName As String, pValue As Object, Optional pOptions As Options.SetVariableValueOptions = Nothing) As Boolean Try ' Set default options If pOptions Is Nothing Then pOptions = New Options.SetVariableValueOptions() End If Dim oOptions As New Options.GetVariableValueOptions With { .Language = pOptions.Language, .Username = pOptions.Username } Try Dim oResponse = Channel.TestObjectIdExists(New TestObjectIdExistsRequest With {.ObjectId = pObjectId}) If oResponse.Exists = False Then Return False End If Catch ex As Exception Logger.Error(ex) Return False End Try Dim oType = pValue.GetType.Name If oType = GetType(DataTable).Name Then Dim oValueTable As DataTable = pValue Dim oCurrentValue As VariableValue ' Get current value oCurrentValue = GetVariableValue(pObjectId, pAttributeName, oOptions) ' If current value is datatable If oCurrentValue.Type = GetType(DataTable) Then ' Convert value to Datatable Dim oTable As DataTable = oCurrentValue.Value If oTable.Rows.Count > 1 Then 'now Checking whether the old row still remains in Vector? If not it will be deleted as it cannot be replaced in multivalues For Each oRow As DataRow In oTable.Rows Dim oExists As Boolean = False For Each oNewValueRow As DataRow In oValueTable.Rows Logger.Debug($"Checking oldValue[{oCurrentValue}] vs NewValue [{oNewValueRow.Item(1)}]") If oNewValueRow.Item(1).ToString.ToUpper = oRow.Item(0).ToString.ToUpper Then oExists = True Exit For End If Next If oExists = False Then Logger.Debug($"Value [{oRow.Item(0)}] no longer existing in Vector-Attribute [{pAttributeName}] - will be deleted!") DeleteTermObjectFromMetadata(pObjectId, pAttributeName, oRow.Item(0)) End If Next End If Else If oValueTable.Rows.Count > 1 Then 'now Checking whether the old row still remains in Vector? If not it will be deleted as it cannot be replaced in multivalues Dim oExists As Boolean = False For Each oNewValueRow As DataRow In oValueTable.Rows Logger.Debug($"Checking oldValue[{oCurrentValue}] vs NewValue [{oNewValueRow.Item(1)}]") If oNewValueRow.Item(1).ToString.ToUpper = oCurrentValue.ToString.ToUpper Then oExists = True Exit For End If Next If oExists = False Then Logger.Debug($"Value [{oCurrentValue}] no longer existing in Vector-Attribute [{pAttributeName}] - will be deleted!") DeleteTermObjectFromMetadata(pObjectId, pAttributeName, oCurrentValue.Value) End If Else Logger.Debug($"Value [{oCurrentValue}] of Attribute [{pAttributeName}] obviously was updated during runtime - will be deleted!") DeleteTermObjectFromMetadata(pObjectId, pAttributeName, oCurrentValue.Value) End If End If For Each oNewValueRow As DataRow In oValueTable.Rows Dim oResult As Boolean = NewObjectData(pObjectId, pAttributeName, pValue, New Options.NewObjectOptions With { .Language = pOptions.Language, .Username = pOptions.Username }) If oResult = False Then Return False End If Next Return True Else Return NewObjectData(pObjectId, pAttributeName, pValue, New Options.NewObjectOptions With { .Language = pOptions.Language, .Username = pOptions.Username }) End If Catch ex As Exception Logger.Error(ex) Return False End Try End Function ''' ''' ''' ''' ''' ''' ''' Public Function GetVariableValue(pObjectId As Long, pAttributeName As String, Optional pOptions As Options.GetVariableValueOptions = Nothing) As VariableValue If pOptions Is Nothing Then pOptions = New Options.GetVariableValueOptions() End If ' Check if ObjectId exists Try Dim oResponse = Channel.TestObjectIdExists(New TestObjectIdExistsRequest With {.ObjectId = pObjectId}) If oResponse.Exists = False Then Return New VariableValue() End If Catch ex As Exception Logger.Error(ex) Return New VariableValue() End Try Try ' Get Attributes and Values from Database Dim oAttributes As List(Of ObjectAttribute) = GetAttributesForObject(pObjectId, pOptions.Language) If oAttributes Is Nothing Then Return New VariableValue() End If Dim oValues = oAttributes.AsEnumerable(). Where(Function(pAttr) Return pAttr.Title.ToUpper = pAttributeName.ToUpper End Function). Select(Function(pAttr) pAttr.Value). ToList() ' Either return a list or a single value or nothing, always wrapped in VariableValue If oValues.Count > 1 Then Return New VariableValue(oValues) ElseIf oValues.Count = 1 Then Return New VariableValue(oValues.First()) Else Return New VariableValue() End If Catch ex As Exception Logger.Error(ex) Return New VariableValue() End Try End Function Private Function GetValueByType(pRow As DataRow, pTypeString As String) As Object Try Dim oAttributeValue As Object Select Case pTypeString Case Constants.AttributeTypeName.BIT oAttributeValue = pRow.Item("ValueBigInt") Case Constants.AttributeTypeName.BIG_INTEGER oAttributeValue = pRow.Item("ValueBigInt") Case Constants.AttributeTypeName.DATE oAttributeValue = pRow.Item("ValueDate") Case Constants.AttributeTypeName.DATETIME oAttributeValue = pRow.Item("ValueDate") Case Constants.AttributeTypeName.DECIMAL oAttributeValue = pRow.Item("ValueDecimal") Case Constants.AttributeTypeName.FLOAT oAttributeValue = pRow.Item("ValueDecimal") Case Constants.AttributeTypeName.VARCHAR oAttributeValue = pRow.Item("ValueText") Case Constants.AttributeTypeName.VECTOR_INTEGER oAttributeValue = pRow.Item("ValueBigInt") Case Constants.AttributeTypeName.VECTOR_STRING oAttributeValue = pRow.Item("ValueText") Case Else oAttributeValue = Nothing End Select Return oAttributeValue Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Private Function GetAttributesForObject(pObjectId As Long, pLanguage As String) As List(Of ObjectAttribute) Dim oAttributes As New List(Of ObjectAttribute) Try Dim oResult As TableResult = Channel.ReturnDatatable_MSSQL_IDB($"EXEC [PRIDB_GET_VALUE_DT] {pObjectId}, '{pLanguage}'") If oResult.OK = False Then Throw New ApplicationException(oResult.ErrorMessage) End If If oResult.Table Is Nothing OrElse oResult.Table.Rows.Count = 0 Then Return Nothing End If For Each oRow As DataRow In oResult.Table.Rows Dim oAttribute As New ObjectAttribute With { .Id = oRow.Item("AttributeId"), .Title = oRow.Item("AttributeTitle"), .Type = oRow.Item("AttributeType"), .ValueBigInt = NotNull(oRow.Item("ValueBigInt"), Nothing), .ValueDate = NotNull(oRow.Item("ValueDate"), Nothing), .ValueDecimal = NotNull(oRow.Item("ValueDecimal"), Nothing), .ValueText = NotNull(oRow.Item("ValueText"), Nothing) } oAttributes.Add(oAttribute) Next Return oAttributes Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Private Function NewObjectData(pObjectId As Long, pAttributeName As String, pValue As Object, pOptions As Options.NewObjectOptions) If pOptions Is Nothing Then pOptions = New Options.NewObjectOptions() End If Dim oLanguage = GetUserLanguage(pOptions.Language) Dim oUsername = GetUserName(pOptions.Username) Dim oSql = $"DECLARE @NEW_OBJ_MD_ID BIGINT EXEC PRIDB_NEW_OBJ_DATA({pObjectId}, '{pAttributeName}', '{oUsername}', '{pValue}', '{oLanguage}', 0, @OMD_ID = @NEW_OBJ_MD_ID OUTPUT)" Dim oResult = Channel.ExecuteNonQuery_MSSQL_IDB(oSql) If oResult.OK = False Then Logger.Warn("Error while deleting Term object") Logger.Error(oResult.ErrorMessage) End If Return oResult.OK End Function Private Function DeleteTermObjectFromMetadata(pObjectId As Long, pAttributeName As String, pTerm2Delete As String, Optional pUsername As String = "", Optional pLanguage As String = "") As Boolean Try Dim oLanguage = GetUserLanguage(pLanguage) Dim oUsername = GetUserName(pUsername) Dim oIdIsForeign As Integer = 1 Dim oDELSQL = $"EXEC PRIDB_DELETE_TERM_OBJECT_METADATA {pObjectId},'{pAttributeName}','{pTerm2Delete}','{oUsername}','{oLanguage}',{oIdIsForeign}" Dim oResult = Channel.ExecuteNonQuery_MSSQL_IDB(oDELSQL) If oResult.OK = False Then Logger.Warn("Error while deleting Term object") Logger.Error(oResult.ErrorMessage) End If Return oResult.OK Catch ex As Exception Logger.Error(ex) Return False End Try End Function Public Function GetDatatableFromIDB(pSQL As String, Optional pConnectionId As Integer = 0) As GetDatatableResponse Try Dim oResponse = Channel.ReturnDatatable(New GetDatatableRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function GetDatatableFromECM(pSQL As String, Optional pConnectionId As Integer = 0) As GetDatatableResponse Try Dim oResponse = Channel.ReturnDatatable(New GetDatatableRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetDatatableFromIDBAsync(pSQL As String, Optional pConnectionId As Integer = 0) As Task(Of GetDatatableResponse) Try Dim oResponse = Await Channel.ReturnDatatableAsync(New GetDatatableRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetDatatableFromECMAsync(pSQL As String, Optional pConnectionId As Integer = 0) As Task(Of GetDatatableResponse) Try Dim oResponse = Await Channel.ReturnDatatableAsync(New GetDatatableRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function GetScalarValueFromIDB(pSQL As String, Optional pConnectionId As Integer = 0) As GetScalarValueResponse Try Dim oResponse = Channel.ReturnScalarValue(New GetScalarValueRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function GetScalarValueFromECM(pSQL As String, Optional pConnectionId As Integer = 0) As GetScalarValueResponse Try Dim oResponse = Channel.ReturnScalarValue(New GetScalarValueRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetScalarValueFromIDBAsync(pSQL As String, Optional pConnectionId As Integer = 0) As Task(Of GetScalarValueResponse) Try Dim oResponse = Await Channel.ReturnScalarValueAsync(New GetScalarValueRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetScalarValueFromECMAsync(pSQL As String, Optional pConnectionId As Integer = 0) As Task(Of GetScalarValueResponse) Try Dim oResponse = Await Channel.ReturnScalarValueAsync(New GetScalarValueRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function ExecuteNonQueryFromIDB(pSQL As String, Optional pConnectionId As Integer = 0) As ExecuteNonQueryResponse Try Dim oResponse = Channel.ExecuteNonQuery(New ExecuteNonQueryRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function ExecuteNonQueryFromECM(pSQL As String, Optional pConnectionId As Integer = 0) As ExecuteNonQueryResponse Try Dim oResponse = Channel.ExecuteNonQuery(New ExecuteNonQueryRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function ExecuteNonQueryFromIDBAsync(pSQL As String, Optional pConnectionId As Integer = 0) As Task(Of ExecuteNonQueryResponse) Try Dim oResponse = Await Channel.ExecuteNonQueryAsync(New ExecuteNonQueryRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function ExecuteNonQueryFromECMAsync(pSQL As String, Optional pConnectionId As Integer = 0) As Task(Of ExecuteNonQueryResponse) Try Dim oResponse = Await Channel.ExecuteNonQueryAsync(New ExecuteNonQueryRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function GetDatatableByName(DatatableName As String, Optional FilterExpression As String = "", Optional SortByColumn As String = "") As TableResult Try Dim oResponse = Channel.ReturnDatatableFromCache(DatatableName, FilterExpression, SortByColumn) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetDatatableByNameAsync(DatatableName As String, Optional FilterExpression As String = "", Optional SortByColumn As String = "") As Task(Of TableResult) Try Dim oResponse = Await Channel.ReturnDatatableFromCacheAsync(DatatableName, FilterExpression, SortByColumn) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function ''' ''' Return infos about a file object ''' ''' ''' ''' Public Function GetDocumentInfo(UserId As Long, ObjectId As Long) As DocumentInfo Try Dim oResponse As DocumentInfoResponse = Channel.GetFileInfoByObjectId(New DocumentInfoRequest With { .ObjectId = ObjectId, .UserId = UserId }) Return New DocumentInfo With { .AccessRight = oResponse.FileRight, .FullPath = oResponse.FullPath } Catch ex As FaultException(Of ObjectDoesNotExistFault) Logger.Error(ex) Throw ex Catch ex As FaultException Logger.Error(ex) Throw ex Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetDocumentInfoAsync(UserId As Long, ObjectId As Long) As Task(Of DocumentInfo) Try Dim oParams = New DocumentInfoRequest With { .ObjectId = ObjectId, .UserId = UserId } Dim oResponse As DocumentInfoResponse = Await Channel.GetFileInfoByObjectIdAsync(oParams) Return New DocumentInfo With { .AccessRight = oResponse.FileRight, .FullPath = oResponse.FullPath } Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function #Region "Private Functions" ''' ''' Creates a channel and adds a Faulted-Handler ''' ''' A channel object Private Function GetChannel() As IEDMIServiceChannel Try Logger.Debug("...Creating channel..") Dim oChannel = ChannelFactory.CreateChannel() AddHandler oChannel.Faulted, AddressOf Reconnect Return oChannel Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Private Function GetUserLanguage(pOverrideLanguage As String) As String Return NotNull(pOverrideLanguage, Threading.Thread.CurrentThread.CurrentUICulture.Name) End Function Private Function GetUserName(pOverrideName) As String Return NotNull(pOverrideName, Environment.UserName) End Function #End Region #Region "Response Classes" Public Class StreamedFile Public Stream As MemoryStream Public FileName As String End Class Public Class FileList Public Datatable As DataTable End Class Public Class DocumentInfo Public Id As Long Public FullPath As String Public AccessRight As AccessRight End Class Public Class VariableValue Public ReadOnly Property IsVector As Boolean = False Public Property Value As Object Public Property Type As Type Public Sub New() MyClass.New(Nothing) End Sub Public Sub New(pValue As Object) ' Check if value is a collection If TypeOf pValue Is IEnumerable Then IsVector = True End If ' Try to determine the type If IsNothing(pValue) Then Type = Nothing Else Type = pValue.GetType End If Value = pValue End Sub End Class #End Region Public Class ObjectAttribute Public Property Id As Long Public Property Title As String Public Property Type As String Public Property ValueBigInt As Long Public Property ValueText As String Public Property ValueDecimal As Decimal Public Property ValueDate As DateTime Public ReadOnly Property Value As Object Get Return GetValue() End Get End Property Private Function GetValue() As Object Select Case Type Case AttributeTypeName.VECTOR_INTEGER Return ValueBigInt Case AttributeTypeName.BIG_INTEGER Return ValueBigInt Case AttributeTypeName.VECTOR_STRING Return ValueText Case AttributeTypeName.VARCHAR Return ValueText Case AttributeTypeName.BIT Return IIf(ValueBigInt = 1, True, False) Case AttributeTypeName.DATE Return ValueDate Case AttributeTypeName.DATETIME Return ValueDate Case AttributeTypeName.DECIMAL Return ValueDecimal Case AttributeTypeName.FLOAT Return ValueDecimal Case Else Return Nothing End Select End Function End Class End Class