SandroRiz
SandroRiz

Reputation: 1107

Blazor server app cannot download .msg files

I have a Blazor Server 6.0 app where I have links to download .msg files.

I have setup IIS to serve that mime-type trying both application/octet-stream and application/vnd.ms-outlook (and restarting IIS)

I have also tried to put in web.config the staticcontent tag like suggested here: .msg file gives download error

And obviously in my program.cs I have app.UseStaticFiles();

I try to put the .msg in a non-blazor app and they work ok, so I think is not IIS related

So why I cannot download (or open automatically in outlook) this type of file, while other (docx, pdf, zip, etc.) are Ok ?

enter image description here

enter image description here

enter image description here

Upvotes: 0

Views: 506

Answers (1)

Gabe Szabo
Gabe Szabo

Reputation: 278

ASP.NET Core -- on the server side -- also needs to know about the files it has to serve. You can enable serving all unknown file types (I'd rather not include the relevant code as it is a major security risk), or you can add you own additional mappings like so:

var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".msg"] = "application/vnd.ms-outlook";

// app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
    ContentTypeProvider = provider
});

More info in the official docs: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-7.0#fileextensioncontenttypeprovider


Additionally, Blazor Server registers custom options for serving static files (like .server.js, which is different from just .js). It's not directly exposed as a public API to configure, but you can look at the source here as to what the AddServerSideBlazor extension method actually does. The solution there relies on you calling UseStaticFiles without explicitly specifying the options, so that it can retrieve the StaticFilesOptions instance from DI.

Armed with this knowledge, you can override an already configured options instance as follows:

builder.Services.PostConfigure<StaticFileOptions>(o =>
{
    ((FileExtensionContentTypeProvider)o.ContentTypeProvider).Mappings[".msg"] = "application/vnd.ms-outlook";
});

This configures the already initialized options instance registered in the DI (after all other configurations happened on it, thus PostConfigure).

Note that if you would for whatever reason decide to use a different IContentTypeProvider, the unsafe cast above would need to be revised as well.

Upvotes: 1

Related Questions