Send email with attachment¶
This operation is the library's single-attachment send path. Four public overloads let a caller supply the attachment as an open Stream, a file path, or an already-loaded Byte() array, with or without a message body; all four converge on the same SendWithAttach SOAP call once the attachment has been normalized to bytes.
| Field | Value |
|---|---|
| Operation ID | MAIL-OP-004 |
| Trigger | Caller invokes any Mail.SendMailWithAttachment(...) overload. |
| Inputs | inToAddress, inFromAddress, inSubject, optional inMessage, one attachment source (Stream, file path, or Byte()), and inAttachName. |
| Outputs | An attachment byte payload for SendWithAttach; SOAP dispatch; the function returns True. |
| Primary components | Mail.SendMailWithAttachment, GetStreamAsBytes, GetFileAsBytes, SAIFMail.clsSAIFMessage, AppGlobal.EnvironmentService |
| Entry point | SAIF.Framework.Mail\MailServices.vb |
Steps¶
- Determine the message body from the overload the caller selected.
- The stream/no-body overload always uses
String.Emptyas the message; it accepts no body parameter. - The stream/body, file/body, and byte-array/body overloads forward the caller-supplied
inMessageunchanged. - Normalize the attachment source into the byte array
SendWithAttachrequires. -
For the stream overloads, call the local
GetStreamAsBytes(inStream)helper (BR-005).- If
inStream Is Nothing, the helper returnsNothingimmediately rather than raising an exception (BR-005). - Otherwise the helper allocates a buffer sized from
inStream.Lengthand reads starting at the stream's current position.
Origin: These sub-steps are implemented in Read a stream into bytes and are executed on behalf of this operation. - For the file-path overload, call the local
GetFileAsBytes(inFilePath)helper (BR-004). - The helper opens the file, allocates a buffer sized fromFS.Length, reads the file's bytes, and closes the stream inFinallyregardless of outcome (BR-004). - If opening or reading the file raises an exception, the helper re-throws it withThrow ex(BR-004).Origin: These sub-steps are implemented in Read a file into bytes and are executed on behalf of this operation. - For the byte-array overload, the caller-supplied
inAttachmentarray is forwarded unchanged — no copy, validation, or size check is performed. 3. Create a newSAIFMail.clsSAIFMessageSOAP client. 4. Look up the mail endpoint by callingAppGlobal.EnvironmentService.GetConfigSetting("legacyMailServiceUrl")and assign the result to the proxy'sUrlproperty (BR-001). -AppGlobal.EnvironmentServicelazily instantiates the environment-service implementation appropriate to the current execution context. -GetConfigSettingreturns the resolved setting value from an override or cached configuration data, or throws if the key cannot be found. - If
Origin: Steps 4.1–4.2 are implemented in Retrieve a configuration setting (
SAIF.Framework.Security.EnvironmentApi) and are executed on behalf of this operation. 5. CallSendWithAttach(inToAddress, inFromAddress, inSubject, message, attachmentBytes, inAttachName). 6. Dispose the SOAP proxy and clear the module-level reference. 7. ReturnTrueonce the dispatch path completes (BR-003). - On failure: exceptions from attachment normalization, configuration lookup, or the SOAP call itself all propagate to the caller unmodified, because this method never catches them.
Process flow¶
The following diagram visualizes this operation's control flow.
flowchart TD
Start([SendMailWithAttachment call]) --> Source{Attachment source}
Source -->|Stream| Stream[Read stream into bytes]
Source -->|File path| File[Read file into bytes]
Source -->|Byte array| Bytes[Reuse caller bytes]
Stream --> Proxy[Create clsSAIFMessage]
File --> Proxy
Bytes --> Proxy
Proxy --> Url[Resolve legacyMailServiceUrl]
Url --> Send[Call SendWithAttach]
Send --> Dispose[Dispose proxy]
Dispose --> End([Return True])
Failure and edge-case behavior¶
- Both byte-conversion helpers size their buffer with
Lengthas a VB array upper bound rather than an element count, so an attachment converted from a stream or a file always carries one extra, zero-valued trailing byte. - Neither helper rewinds its source before reading; a stream that has already been partially consumed produces an attachment payload that is only partially populated, and there is no compensating logic in this operation.
- A
Nothingstream input becomes aNothingattachment array rather than an exception, soSendWithAttachcan be invoked with no attachment data even though an attachment overload was selected. - The operation always calls
SendWithAttach; it never selects the generated proxy'sSendWithAttachAsTextmethod, so there is no plain-text-specific attachment path distinct from the one described here.
Related documentation¶
- Operations and processes
- Overview
- Architecture
- Dependencies
- Business rules
- Configuration
- API reference
Sources¶
- SAIF.Framework.Mail\MailServices.vb
- SAIF.Framework.Mail\Web References\SAIFMail\Reference.vb
- SAIF.Framework.Security\AppGlobal.vb
- SAIF.Framework.Security.EnvironmentApi\Core\Services\IEnvironmentService.cs
- SAIF.Framework.Security.EnvironmentApi\Services.Common\EnvironmentServiceBase.cs