I've written the following extension to determine the MIME type of a base64 string. It's worked in my local tests, but can anyone point out issues or alternate methods?
public static AttachmentType GetMimeType(this string value)
{
if(String.IsNullOrEmpty(value))
return new AttachmentType
{
FriendlyName = "Unknown",
MimeType = "application/octet-stream",
Extension = ""
};
var data = value.Substring(0,5);
switch (data.ToUpper())
{
case "IVBOR":
case "/9J/4":
return new AttachmentType
{
FriendlyName = "Photo",
MimeType = "image/png",
Extension = ".png"
};
case "AAAAF":
return new AttachmentType
{
FriendlyName = "Video",
MimeType = "video/mp4",
Extension = ".mp4"
};
case "JVBER":
return new AttachmentType
{
FriendlyName = "Document",
MimeType = "application/pdf",
Extension = ".pdf"
};
default:
return new AttachmentType
{
FriendlyName = "Unknown",
MimeType = string.Empty,
Extension = ""
};
}
}
public class AttachmentType
{
public string MimeType { get; set; }
public string FriendlyName { get; set; }
public string Extension { get; set; }
}
2 Answers 2
Your attachment types look like static data to me, so I'd personally make AttachmentType
an immutable class and define your common bits as static
members. I also like making things like this implement an interface
for ease of mocking during unit testing. So I have this:
public interface IAttachmentType
{
string MimeType
{
get;
}
string FriendlyName
{
get;
}
string Extension
{
get;
}
}
public sealed class AttachmentType : IAttachmentType
{
// Possibly make this private if you only use the static predefined MIME types.
public AttachmentType(string mimeType, string friendlyName, string extension)
{
this.MimeType = mimeType;
this.FriendlyName = friendlyName;
this.Extension = extension;
}
public static IAttachmentType UnknownMime { get; } = new AttachmentType("application/octet-stream", "Unknown", string.Empty);
public static IAttachmentType Photo { get; } = new AttachmentType("image/png", "Photo", ".png");
public static IAttachmentType Video { get; } = new AttachmentType("video/mp4", "Video", ".mp4");
public static IAttachmentType Document { get; } = new AttachmentType("application/pdf", "Document", ".pdf");
public static IAttachmentType Unknown { get; } = new AttachmentType(string.Empty, "Unknown", string.Empty);
public string MimeType { get; }
public string FriendlyName { get; }
public string Extension { get; }
}
Then, to avoid a big long switch
, I put those into a Dictionary<T,U>
as such (note the case-insensitive specification, which will remove the ToUpper()
later). You can add MIME types with your detection string as needed:
private static readonly IDictionary<string, IAttachmentType> mimeMap =
new Dictionary<string, IAttachmentType>(StringComparer.OrdinalIgnoreCase)
{
{ "IVBOR", AttachmentType.Photo },
{ "/9J/4", AttachmentType.Photo },
{ "AAAAF", AttachmentType.Video },
{ "JVBER", AttachmentType.Document }
};
Your calling code then simplifies to:
public static IAttachmentType GetMimeType(this string value) => string.IsNullOrEmpty(value)
? AttachmentType.UnknownMime
: (mimeMap.TryGetValue(value.Substring(0, 5), out IAttachmentType result) ? result : AttachmentType.Unknown);
Your switch is wrong: "/9J/4
" is for JPG images, not PNG (e.g. as shown in these examples).