Vous voulez probablement continuer à utiliser MailBee ... mais si vous êtes ouvert à des solutions de rechange, permettez-moi de répondre à cette question comme si vous utilisiez mon open source MimeKit/MailKit bibliothèques au lieu:
Lorsque l'analyseur MIME MimeKit rencontre des pièces jointes avec un en-tête Content-Type
qui correspond application/vnd.ms-tnef
ou application/ms-tnef
, il utilisera automatiquement le but spécial TnefPart classe pour représenter cette attach ment.
Pour extraire les pièces jointes encapsulées à partir de cela, vous pouvez simplement utiliser la méthode ExtractAttachments() qui fonctionne probablement un peu comme la méthode GetAttachmentsFromTnef()
de MailBee.
La traduction de votre code de MailBee à MimeKit ressemblerait à ceci:
var attachments = message.Attachments.ToList();
var encapsulated = attachments.OfType<TnefPart>().SelectMany(a => a.ExtractAttachments());
// Add encapsulated attachments
attachments.AddRange(encapsulated);
Très probablement la raison pour laquelle IsTnef
propriété de MailBee retourne faux pour vous, cependant, est probablement parce que l'en-tête Content-Type
ne correspond aux tnef mime-types que j'ai mentionnés plus tôt. Si c'est effectivement le cas, le code traduit que j'ai posté ci-dessus échouera également sous MimeKit.
Mais ...
MimeKit propose également des cours de soutien TNEF niveau inférieur que vous pouvez utiliser si vous décidez d'utiliser une autre méthode pour déterminer d'une partie MIME contient le contenu TNEF.
static void ExtractAttachments (MimePart attachment, IList<MimeEntity> attachments)
{
using (var reader = new TnefReader (attachment.ContentObject.Open(), 0, TnefComplianceMode.Loose)) {
// skip past the non-attachment tnef content...
while (reader.ReadNextAttribute()) {
if (reader.AttributeLevel == TnefAttributeLevel.Attachment)
break;
}
if (reader.AttributeLevel == TnefAttributeLevel.Attachment)
ExtractAttachments (reader, attachments);
}
}
static void ExtractAttachments (TnefReader reader, IList<MimeEntity> attachments)
{
var attachMethod = TnefAttachMethod.ByValue;
var filter = new BestEncodingFilter();
var prop = reader.TnefPropertyReader;
MimePart attachment = null;
int outIndex, outLength;
TnefAttachFlags flags;
string[] mimeType;
byte[] attachData;
string text;
do {
if (reader.AttributeLevel != TnefAttributeLevel.Attachment)
break;
switch (reader.AttributeTag) {
case TnefAttributeTag.AttachRenderData:
attachMethod = TnefAttachMethod.ByValue;
attachment = new MimePart();
break;
case TnefAttributeTag.Attachment:
if (attachment == null)
break;
while (prop.ReadNextProperty()) {
switch (prop.PropertyTag.Id) {
case TnefPropertyId.AttachLongFilename:
attachment.FileName = prop.ReadValueAsString();
break;
case TnefPropertyId.AttachFilename:
if (attachment.FileName == null)
attachment.FileName = prop.ReadValueAsString();
break;
case TnefPropertyId.AttachContentLocation:
text = prop.ReadValueAsString();
if (Uri.IsWellFormedUriString (text, UriKind.Absolute))
attachment.ContentLocation = new Uri (text, UriKind.Absolute);
else if (Uri.IsWellFormedUriString (text, UriKind.Relative))
attachment.ContentLocation = new Uri (text, UriKind.Relative);
break;
case TnefPropertyId.AttachContentBase:
text = prop.ReadValueAsString();
attachment.ContentBase = new Uri (text, UriKind.Absolute);
break;
case TnefPropertyId.AttachContentId:
attachment.ContentId = prop.ReadValueAsString();
break;
case TnefPropertyId.AttachDisposition:
text = prop.ReadValueAsString();
if (attachment.ContentDisposition == null)
attachment.ContentDisposition = new ContentDisposition (text);
else
attachment.ContentDisposition.Disposition = text;
break;
case TnefPropertyId.AttachData:
var stream = prop.GetRawValueReadStream();
var content = new MemoryStream();
var guid = new byte[16];
if (attachMethod == TnefAttachMethod.EmbeddedMessage) {
var tnef = new TnefPart();
foreach (var param in attachment.ContentType.Parameters)
tnef.ContentType.Parameters[param.Name] = param.Value;
if (attachment.ContentDisposition != null)
tnef.ContentDisposition = attachment.ContentDisposition;
attachment = tnef;
}
// read the GUID
stream.Read (guid, 0, 16);
// the rest is content
using (var filtered = new FilteredStream (content)) {
filtered.Add (filter);
stream.CopyTo (filtered, 4096);
filtered.Flush();
}
content.Position = 0;
attachment.ContentTransferEncoding = filter.GetBestEncoding (EncodingConstraint.SevenBit);
attachment.ContentObject = new ContentObject (content);
filter.Reset();
attachments.Add (attachment);
break;
case TnefPropertyId.AttachMethod:
attachMethod = (TnefAttachMethod) prop.ReadValueAsInt32();
break;
case TnefPropertyId.AttachMimeTag:
mimeType = prop.ReadValueAsString().Split ('/');
if (mimeType.Length == 2) {
attachment.ContentType.MediaType = mimeType[0].Trim();
attachment.ContentType.MediaSubtype = mimeType[1].Trim();
}
break;
case TnefPropertyId.AttachFlags:
flags = (TnefAttachFlags) prop.ReadValueAsInt32();
if ((flags & TnefAttachFlags.RenderedInBody) != 0) {
if (attachment.ContentDisposition == null)
attachment.ContentDisposition = new ContentDisposition (ContentDisposition.Inline);
else
attachment.ContentDisposition.Disposition = ContentDisposition.Inline;
}
break;
case TnefPropertyId.AttachSize:
if (attachment.ContentDisposition == null)
attachment.ContentDisposition = new ContentDisposition();
attachment.ContentDisposition.Size = prop.ReadValueAsInt64();
break;
case TnefPropertyId.DisplayName:
attachment.ContentType.Name = prop.ReadValueAsString();
break;
}
}
break;
case TnefAttributeTag.AttachCreateDate:
if (attachment != null) {
if (attachment.ContentDisposition == null)
attachment.ContentDisposition = new ContentDisposition();
attachment.ContentDisposition.CreationDate = prop.ReadValueAsDateTime();
}
break;
case TnefAttributeTag.AttachModifyDate:
if (attachment != null) {
if (attachment.ContentDisposition == null)
attachment.ContentDisposition = new ContentDisposition();
attachment.ContentDisposition.ModificationDate = prop.ReadValueAsDateTime();
}
break;
case TnefAttributeTag.AttachTitle:
if (attachment != null && string.IsNullOrEmpty (attachment.FileName))
attachment.FileName = prop.ReadValueAsString();
break;
case TnefAttributeTag.AttachMetaFile:
if (attachment == null)
break;
// TODO: what to do with the meta data?
break;
case TnefAttributeTag.AttachData:
if (attachment == null || attachMethod != TnefAttachMethod.ByValue)
break;
attachData = prop.ReadValueAsBytes();
filter.Flush (attachData, 0, attachData.Length, out outIndex, out outLength);
attachment.ContentTransferEncoding = filter.GetBestEncoding (EncodingConstraint.EightBit);
attachment.ContentObject = new ContentObject (new MemoryStream (attachData, false));
filter.Reset();
attachments.Add (attachment);
break;
}
} while (reader.ReadNextAttribute());
}
Bien sûr ... vous pouvez aussi tout simplement tricher en faisant ceci:
var tnef = new TnefPart { ContentObject = attachment.ContentObject };
attachments.AddRange (tnef.ExtractAttachments());
Ainsi, le résultat final pourrait ressembler à ceci (si vous décidez de faire correspondre FileName à la place):
var attachments = message.Attachments.ToList();
var encapsulated = attachments.OfType<MimePart>()
.Where(x => (x is TnefPart) || x.FileName == "winmail.dat")
.SelectMany(x => {
var tnef = (x as TnefPart) ?? new TnefPart { ContentObject = x.ContentObject };
return tnef.ExtractAttachments();
});
// Add encapsulated attachments
attachments.AddRange(encapsulated);