Skip to content

Repository files navigation

MimeTypes logo

MimeTypes

CIReleaseCodeQLCodecovNuGetNuGet downloadsLicense.NET

ManagedCode.MimeTypes is a generated MIME/media type helper for .NET. It combines the IANA media types registry, Apache's maintained mime.types data, mime-db gap-fill entries, curated compatibility overrides, and registry metadata such as template URLs, references, extensions, and parseable magic-number prefixes.

Use it when you need to map file names to MIME types, inspect file content signatures, validate upload claims, classify MIME families, or keep an application aligned with the current public MIME registries.

Contents

Installation

dotnet add package ManagedCode.MimeTypes

Targets: net8.0, net9.0, and net10.0.

What It Does

AreaAPI examplesNotes
Extension lookupGetMimeType("report.pdf")Handles file names, extensions, URLs, query strings, and multi-part extension candidates.
Reverse lookupGetExtensions("image/jpeg")Returns known dot-prefixed extensions for a MIME value.
Registry metadataTryGetMimeTypeInfo(...), GetKnownMimeTypes()Includes IANA registration status, template URLs, references, intended usage, aliases, and magic-number metadata.
Content detectionGetMimeTypeByContent(stream)Sniffs common signatures plus parseable registry magic prefixes. Seekable streams are restored to their original position.
Content validationMatchesMimeTypeByContent(...), MatchesExtensionByContent(...)Checks whether detected bytes match an expected MIME type or the MIME implied by a file name.
CategorisationGetMimeCategory(...), IsImage(...), IsJson(...)Groups MIME values into high-level families such as image, archive, script, document, spreadsheet, and executable.
Runtime mappingsRegisterMimeType(...), UnregisterMimeType(...)Allows application-specific extensions without regenerating the database.
Configuration and DISetDefaultMimeType(...), MimeHelper.InstanceConfigurable fallback MIME and an IMimeHelper adapter for common operations.

Quick Start

usingManagedCode.MimeTypes;varpdf=MimeHelper.GetMimeType("report.pdf");vargzip=MimeHelper.GetMimeType("archive.tar.gz");varavatar=MimeHelper.GetMimeType("https://cdn.example.com/users/42/avatar.png?v=2");Console.WriteLine(pdf);// application/pdfConsole.WriteLine(gzip);// application/gzipConsole.WriteLine(avatar);// image/png

Unknown extensions return MimeHelper.DefaultMimeType, which defaults to application/octet-stream.

varfallback=MimeHelper.GetMimeType("file.unknown");Console.WriteLine(fallback);// application/octet-stream

Content Detection

Extension lookup tells you what a file claims to be. Content detection inspects the first bytes and tells you what the payload looks like.

usingManagedCode.MimeTypes;usingvarstream=File.OpenRead("report.pdf");vardetected=MimeHelper.GetMimeTypeByContent(stream);Console.WriteLine(detected);// application/pdfif(MimeHelper.TryGetMimeTypeByContent(stream,outvarcontentMime)){Console.WriteLine($"Detected by signature: {contentMime}");}

GetMimeTypeByContent returns MimeHelper.DefaultMimeType when no known signature matches. TryGetMimeTypeByContent returns false in that case and still gives the fallback value through the out parameter.

Seekable streams are rewound to their original position after detection:

usingvarstream=File.OpenRead("image.png");stream.Position=4;vardetected=MimeHelper.GetMimeTypeByContent(stream);Console.WriteLine(detected);// image/pngConsole.WriteLine(stream.Position);// 4

Content detection is signature-based. It is useful for upload checks and mismatch detection, but it is not a full document parser, virus scanner, or guarantee that the entire file is structurally valid.

Validating Uploads

For upload flows, compare the detected content type with the declared MIME type or with the file extension.

usingManagedCode.MimeTypes;usingvarstream=upload.OpenReadStream();if(!MimeHelper.MatchesMimeTypeByContent(stream,upload.ContentType)){thrownewInvalidOperationException("The uploaded file content does not match its declared MIME type.");}

If you trust the file name as the expected claim:

usingvarstream=upload.OpenReadStream();if(!MimeHelper.MatchesExtensionByContent(upload.FileName,stream)){thrownewInvalidOperationException("The uploaded file content does not match its extension.");}

There is also a file-path overload:

varok=MimeHelper.MatchesExtensionByContent("/tmp/report.pdf");

Registry Metadata

The package ships generated metadata for known MIME values. This is useful when you need to display registry details, audit data sources, inspect aliases, or use IANA magic-number metadata.

usingManagedCode.MimeTypes;if(MimeHelper.TryGetMimeTypeInfoByExtension("report.pdf",outvarpdfInfo)){Console.WriteLine(pdfInfo.Mime);// application/pdfConsole.WriteLine(pdfInfo.IsIanaRegistered);// trueConsole.WriteLine(pdfInfo.TemplateUrl);// https://www.iana.org/assignments/media-types/application/pdfConsole.WriteLine(pdfInfo.MagicSignatures.FirstOrDefault()?.Hex);// 25 50 44 46 2D}

Lookup directly by MIME:

if(MimeHelper.TryGetMimeTypeInfo("application/json",outvarjsonInfo)){Console.WriteLine(jsonInfo.Source);Console.WriteLine(jsonInfo.PublishedSpecification);}

List the bundled catalog:

varregisteredImages=MimeHelper.GetKnownMimeTypes().Where(info =>info.IsIanaRegistered&&info.Mime.StartsWith("image/",StringComparison.OrdinalIgnoreCase)).OrderBy(info =>info.Mime).ToList();

MimeTypeInfo includes:

PropertyMeaning
MimeCanonical MIME value known to the catalog.
ExtensionsDot-prefixed extensions associated with the MIME value.
IsIanaRegisteredWhether the type is registered in the IANA media types registry.
IsObsolete / PreferredMimeObsolescence state and replacement when available.
Template / TemplateUrlIANA registration template path and URL.
SourceSource that supplied the metadata, such as iana, apache, mime-db, or curated.
Registered / UpdatedRegistry dates when available.
IntendedUsage, EncodingConsiderations, PublishedSpecification, ApplicationsTemplate fields parsed from registry data.
DeprecatedAliases / ReferencesAlias and reference metadata.
MagicSignaturesParseable fixed byte prefixes from registration templates.

Categories

GetMimeCategory maps a MIME value to a high-level MimeTypeCategory.

varcategory=MimeHelper.GetMimeCategory("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");Console.WriteLine(category);// Spreadsheetif(MimeHelper.IsArchive("application/zip")){Console.WriteLine("Archive upload");}if(MimeHelper.IsScript("application/x-powershell")){Console.WriteLine("Treat this as executable script content");}

Available categories:

Unknown, Video, Audio, Image, Document, Spreadsheet, Presentation, Pdf, Archive, Text, Json, Xml, Font, Model, Executable, Certificate, Calendar, Email, Script, Binary, Multipart, Message.

Predicate helpers are available for the main categories: IsVideo, IsAudio, IsImage, IsDocument, IsPdf, IsArchive, IsText, IsJson, IsXml, IsFont, IsModel, IsExecutable, IsCertificate, IsSpreadsheet, IsPresentation, IsCalendar, IsEmail, IsScript, and IsBinary.

Reverse Lookup

varjpegExtensions=MimeHelper.GetExtensions("image/jpeg");foreach(varextensioninjpegExtensions){Console.WriteLine(extension);// .jpe, .jpeg, .jpg}if(MimeHelper.TryGetExtensions("application/pdf",outvarpdfExtensions)){Console.WriteLine(string.Join(", ",pdfExtensions));// .pdf}

Runtime Registration

Applications can add or replace extension mappings at runtime.

MimeHelper.RegisterMimeType("acme","application/x-acme");varcustom=MimeHelper.GetMimeType("invoice.acme");Console.WriteLine(custom);// application/x-acmeMimeHelper.UnregisterMimeType("acme");

Runtime registrations update extension lookup and reverse lookup, but they do not create generated registry metadata:

MimeHelper.RegisterMimeType("internal","application/x-company-internal");Console.WriteLine(MimeHelper.GetMimeType("file.internal"));// application/x-company-internalConsole.WriteLine(MimeHelper.TryGetMimeTypeInfoByExtension("file.internal",out_));// falseMimeHelper.UnregisterMimeType("internal");

The helper uses immutable dictionaries internally so lookup remains safe while mappings are updated.

Default MIME Type

The default fallback is application/octet-stream.

Console.WriteLine(MimeHelper.DefaultMimeType);// application/octet-streamMimeHelper.SetDefaultMimeType(MimeHelper.JSON);Console.WriteLine(MimeHelper.GetMimeType("unknown.extension"));// application/jsonMimeHelper.SetDefaultMimeType(MimeHelper.BIN);

Use this carefully in shared applications because it changes process-wide behavior.

DI-Friendly Adapter

For code that prefers an interface, use MimeHelper.Instance.

usingManagedCode.MimeTypes;publicsealedclassUploadClassifier(IMimeHelpermimeHelper){publicstringGetClaimedMime(stringfileName){returnmimeHelper.GetMimeType(fileName);}}services.AddSingleton<IMimeHelper>(MimeHelper.Instance);

IMimeHelper covers common operations: extension lookup, content lookup, reverse lookup, runtime registration, unregistration, and categorisation. The static MimeHelper class exposes the full metadata and validation surface.

Data Sources

The generated database is built from:

SourcePurpose
IANA media types registryOfficial media type registrations and templates.
Apache mime.typesBroad extension coverage used by common web server deployments.
mime-dbCompatibility gap-fill entries used by the JavaScript and web tooling ecosystem.
curatedMimeTypes.jsonProject-maintained overrides for practical compatibility cases.

Curated compatibility mappings and maintained runtime/server maps take precedence over raw IANA extension hints when they conflict. IANA remains the source for registration metadata.

Refreshing The Catalog

The sync utility regenerates mimeTypes.json and mimeTypes.metadata.json.

dotnet run --project ManagedCode.MimeTypes.Sync

Provide custom inputs or outputs:

DOTNET_CLI_TELEMETRY_OPTOUT=1 dotnet run --project ManagedCode.MimeTypes.Sync -- \
--iana-source https://www.iana.org/assignments/media-types/media-types.xml \
--output ./artifacts/mimeTypes.json \
--metadata-output ./artifacts/mimeTypes.metadata.json

Preserve an existing local map only when intentionally carrying compatibility data forward:

dotnet run --project ManagedCode.MimeTypes.Sync -- --preserve-existing --prefer-remote

Disable or replace the curated compatibility layer for policy experiments:

dotnet run --project ManagedCode.MimeTypes.Sync -- --no-curated
dotnet run --project ManagedCode.MimeTypes.Sync -- --curated-source ./my-curated-mime-types.json

Running the tool updates the JSON inputs. The source generator consumes those files on the next build and regenerates the helper constants, mappings, and metadata.

Development

dotnet restore
dotnet build ManagedCode.MimeTypes.sln
dotnet test ManagedCode.MimeTypes.sln

The release workflow reads the package version from Directory.Build.props, packs the project, publishes to NuGet on main, and creates the GitHub release/tag when publishing succeeds.

Contributing

Issues and pull requests are welcome. Please run dotnet test ManagedCode.MimeTypes.sln before sending changes. For catalog updates, prefer the sync utility so generated MIME data and metadata stay reproducible.

About

Official IANA and Apache MIME/media type lookup, metadata, categorisation, and content detection for .NET.

Topics

Resources

Stars

17 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages