Search code examples
.neturimailto

MailTo URI object in .NET?


Given a URI (that is confirmed to be a Uri.UriSchemeMailto) is there an object this can be cast to that would give provide mailto properties?

Like if the .TargetURI was {mailto:[email protected]?subject=I'm all done&body=Finished&[email protected]&[email protected]} is there an object that will take this as a URI and spit back MailTo properties? Like

Pseudo Code

Dim mailDetails as New MailDetailsObject(MyURI.TargetURI)

Console.WriteLine(mailDetails.To)
Console.WriteLine(mailDetails.CC)
Console.WriteLine(mailDetails.BCC)
Console.WriteLine(mailDetails.Subject)
Console.WriteLine(mailDetails.Body)

That results in:

[email protected]
[email protected]
[email protected]
I'm all done
Finished

Or is this something people normally just manually parse or construct out of the properties under .TargetURI?


Solution

  • I ended up writing my own class for this. It's not complete and haven't tested it with all possible parts of the schema, but it appears to work well enough for most mailtos. Feel free to edit this answer with improvements.

    Class MailToItem
        Public Property [To] As String
        Public Property Cc As String
        Public Property Subject As String
        Public Property Body As String
        Public Property Bcc As String
        Private _mailToParameters As String()
        Sub New(uri As String)
            Dim mailtoString As String() = uri.Split("?")
            Me.To = GetEmailToRecipients(mailtoString(0).Split(":")(1))
            _mailToParameters = mailtoString(1).Split("&")
            SetOtherEmailRecipients()
            SetSubject()
            SetBody()
        End Sub
        Private Sub SetOtherEmailRecipients()
            Me.Cc = GetEmailRecipients("cc")
            Me.Bcc = GetEmailRecipients("bcc")
        End Sub
        Private Function GetEmailRecipients(type As String) As String
            Dim recipients As String = Field(type)
            If recipients IsNot Nothing Then
                Dim recipientsAll() As String
                recipientsAll = recipients.Split("=")(1).Split(",")
                Dim s As New System.Text.StringBuilder
                If recipientsAll.Count > 1 Then
                    For r = 0 To recipientsAll.Count - 1
                        If r < recipientsAll.GetUpperBound(0) Then
                            s.Append(recipientsAll(r) + ";")
                        Else
                            s.Append(recipientsAll(r))
                        End If
                    Next
                Else
                    s.Append(recipientsAll(0))
                End If
                Return s.ToString
            Else
                Return ""
            End If
        End Function
        Private Function Field(type As String) As String
            Return _mailToParameters.Where(Function(f) f.StartsWith(type, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault
        End Function
        Private Function GetEmailToRecipients(toString As String) As String
            Dim recipientsAll() As String = toString.Split(",")
            Dim s As New System.Text.StringBuilder
                If recipientsAll.Count > 1 Then
                    For r = 0 To recipientsAll.Count - 1
                        If r < recipientsAll.GetUpperBound(0) Then
                            s.Append(recipientsAll(r) + ";")
                        Else
                            s.Append(recipientsAll(r))
                        End If
                    Next
                Else
                    s.Append(recipientsAll(0))
                End If
                Return s.ToString
        End Function
        Private Sub SetSubject()
            Dim subject As String = Field("subject")
            If subject IsNot Nothing Then
                Me.Subject = NormalizeText(subject.Split("=")(1))
            End If
        End Sub
        Private Sub SetBody()
            Dim body As String = Field("body")
            If body IsNot Nothing Then
                Me.Body = NormalizeText(body.Split("=")(1))
            End If
        End Sub
        Private Function NormalizeText(text As String) As String
            text.Replace("%20", " ")
            text.Replace("%0A%0A", Environment.NewLine + Environment.NewLine)
            text.Replace("%0A", Environment.NewLine)
            text.Replace("%0D", Environment.NewLine)
            Return text
        End Function
    End Class
    

    Note that passing a .TargetURI into the constructor may cause failures as it doesn't appear to cover the full schema. For example mailto:[email protected],[email protected] (two recipients) will cause .TargetURI to fail. In that case, you can pass in .TargetURI.OriginalString instead.