Imports System.Net.Http Imports System.Text Imports System.Xml Imports DigitalData.Modules.Logging Imports MultiTool.Shared.Documents Imports MultiTool.Shared.Templates.GeneralConfig Imports MultiTool.Shared.Winline.Entities Namespace Winline Public Class WebServiceData Inherits BaseClass Private ReadOnly Config As WebServiceConfig Private ReadOnly Serializer As Serializer Private ReadOnly OutputDirectory As String Private ReadOnly Helpers As Helpers Public Event WebServiceProgress As EventHandler(Of String) Public Sub New(pLogConfig As LogConfig, pWebserviceConfig As WebServiceConfig, pOutputDirectoryPath As String) MyBase.New(pLogConfig) Helpers = New Helpers(pLogConfig) Serializer = New Serializer(pLogConfig) Config = pWebserviceConfig OutputDirectory = pOutputDirectoryPath End Sub Public Async Function TransferDocumentToWinline(pDocument As Document, pMandator As Mandator, Optional pIsTest As Boolean = False) As Task(Of Boolean) Dim oBytes As Byte() = GetBytesFromDocument(pDocument) Dim oWS = Config ' --- Get and create path for request/response files Dim oOutputDirectory = Helpers.GetDateDirectory(OutputDirectory) RaiseEvent WebServiceProgress(Me, "Einstellungen laden") ' --- Build all teh filenamez and pathz Dim oBaseFileName As String = Helpers.GetDateTimeString() Dim oFileName = Helpers.GetFilenameWithSuffix(oBaseFileName, "Request", "xml") ' Relative Path for Webservice Call Dim oImportRelativeFilePath = IO.Path.Combine(Helpers.GetDateDirectory(oWS.ImportRelativePath), oFileName) ' Absolute Path to copy Request file Dim oImportAbsolutePath = IO.Path.Combine(oWS.ImportBasePath, oWS.ImportRelativePath) Dim oImportAbsoluteFilePath = IO.Path.Combine(Helpers.GetDateDirectory(oImportAbsolutePath), oFileName) ' --- Serialize Data into XML string RaiseEvent WebServiceProgress(Me, "Dateien schreiben") Dim oOutputFilePath = IO.Path.Combine(oOutputDirectory, oFileName) IO.File.WriteAllBytes(oOutputFilePath, oBytes) ' --- Copy file to Winline Import Directory Try IO.File.Copy(oOutputFilePath, oImportAbsoluteFilePath, True) Catch ex As Exception Logger.Error(ex) Throw ex End Try ' --- Prepare URL and HTTP Client Dim oTemplateType = pDocument.TemplateType Dim oTemplateName = pDocument.TemplateName ' ActionCode: Should this be a test or not? ' 0 = Test call ' 1 = Real call Dim oActionCode = 1 If pIsTest = True Then oActionCode = 0 End If ' Byref: Should data be supplied as file or as string? ' 0 = As String ' 1 = As File (relative to Winline Server directory) Dim oByref = 1 Dim oURL As String = $"{oWS.BaseUrl}/ewlservice/import?User={oWS.Username}&Password={oWS.Password}&Company={pMandator.Id}&Type={oTemplateType}&Vorlage={oTemplateName}&ActionCode={oActionCode}&Byref={oByref}&Data={oImportRelativeFilePath}" Dim oClient As New HttpClient() Logger.Info("Creating HTTP Request to [{0}]", oWS.BaseUrl) RaiseEvent WebServiceProgress(Me, "Anfrage absenden") ' --- Bring the action! Try Dim oResponse As HttpResponseMessage = Await oClient.GetAsync(oURL) Await HandleResponse(oResponse, oOutputDirectory, oBaseFileName) Return True Catch ex As Exception Logger.Error(ex) Throw ex Finally oClient.Dispose() End Try End Function Private Async Function HandleResponse(pResponse As HttpResponseMessage, pOutputPath As String, pBaseFileNAme As String) As Task pResponse.EnsureSuccessStatusCode() Dim oResponseBody As String = Await pResponse.Content.ReadAsStringAsync() Dim oContentType = pResponse.Content.Headers.ContentType.MediaType Dim oSerializer = Serializer.GetSerializer(GetType(Templates.Entities.MESOWebServiceResult)) RaiseEvent WebServiceProgress(Me, "Antwort verarbeiten") Select Case oContentType Case "text/xml" WriteResponseFile(pOutputPath, pBaseFileNAme, oResponseBody, "xml") Dim oBytes As Byte() = Encoding.UTF8.GetBytes(oResponseBody) Using oStream As New IO.MemoryStream(oBytes) Dim oResponseObject As Templates.Entities.MESOWebServiceResult = oSerializer.Deserialize(oStream) Dim oErrorStrings As New List(Of String) If oResponseObject.ResultDetails IsNot Nothing Then For Each oDetails As Templates.Entities.MESOWebServiceResultResultDetails In oResponseObject.ResultDetails If oDetails.Success = True Then Logger.Info("KeyValue: [{0}]", oDetails.KeyValue) Logger.Info("VoucherNumber: [{0}]", oDetails.VoucherNumber) Else Logger.Warn("ErrorCode: [{0}]", oDetails.ErrorCode) Logger.Warn("ErrorText: [{0}]", oDetails.ErrorText) oErrorStrings.Add($"[{oDetails.ErrorCode}] {oDetails.ErrorText}") End If Next End If If oResponseObject.OverallSuccess = False Then Dim oMessage = $"Request to Webservice was unsuccessful:{vbNewLine}{vbNewLine}{String.Join(vbNewLine, oErrorStrings.ToArray)}" Throw New ApplicationException(oMessage) End If End Using Case "text/html" WriteResponseFile(pOutputPath, pBaseFileNAme, oResponseBody, "txt") Throw New ApplicationException(oResponseBody) Case Else Throw New ApplicationException(oResponseBody) End Select End Function Private Function WriteResponseFile(pPath As String, pBaseFileName As String, pResponseBody As String, pExtension As String) Try Dim oRequestFileName As String = Helpers.GetFilenameWithSuffix(pBaseFileName, "Response", pExtension) Dim oFilePath As String = IO.Path.Combine(pPath, oRequestFileName) IO.File.WriteAllText(oFilePath, pResponseBody) Return True Catch ex As Exception Logger.Error(ex) Return False End Try End Function Private Function GetBytesFromDocument(pDocument As Document) As Byte() Using oStream As New IO.MemoryStream() Dim w = XmlWriter.Create(oStream) w.WriteStartDocument() w.WriteStartElement("MESOWebService") w.WriteAttributeString("Template", pDocument.TemplateName) w.WriteAttributeString("TemplateType", pDocument.TemplateType) w.WriteAttributeString("option", pDocument.Option) w.WriteAttributeString("printVoucher", pDocument.PrintVoucher) pDocument.Rows.Sort() For Each oRow In pDocument.Rows w.WriteStartElement(oRow.Name) For Each oField As KeyValuePair(Of String, DocumentRow.FieldValue) In oRow.Fields If oField.Value.Final = String.Empty Then Continue For End If If oField.Value.IsVirtual Then Continue For End If w.WriteStartElement(oField.Key) w.WriteValue(oField.Value.Final) w.WriteEndElement() ' Field Next w.WriteEndElement() ' Row Next w.WriteEndElement() ' MESOWebService w.WriteEndDocument() ' Document w.Close() Return oStream.ToArray() End Using End Function End Class End Namespace