9
\$\begingroup\$

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; }
}
\$\endgroup\$
0

2 Answers 2

5
\$\begingroup\$

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);
\$\endgroup\$
8
\$\begingroup\$

Your switch is wrong: "/9J/4" is for JPG images, not PNG (e.g. as shown in these examples).

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.