Search code examples
azure-web-app-servicemime-typesblazorblazor-server-sideios-universal-links

Serving static content without a file extension on a Blazor server project


As per Apple's requirements for Universal Links, I have a file called "apple-app-site-association", which is in the root folder of a web site in azure. Visiting mysite.com/apple-app-site-association should return the JSON text in the browser. I am hosting the site on Azure, and am running a Blazor server project. My project does not have a web.config file.

To be clear, the file "apple-app-site-association" should not have the extension of ".json"

I have looked at this solution and this solution.

I have also tried modifying the Configure() method in Startup.cs to serve static files

app.UseStaticFiles(new StaticFileOptions
{
    ServeUnknownFileTypes = true,
    DefaultContentType = "application/json"
});

While the above code does correctly serve mysite.com/apple-app-site-association, it has an unwanted side-effect of 404'ing _framework/blazor.server.js.

How can I modify the MIME type of apple-app-site-association so my Blazor server project serves the file up when visiting mysite.com/apple-app-site-association?

Or, using the UseStaticFiles() method above, how can I resolve the 404 error when loading _framework/blazor.server.js?

In _Host.cshtml

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="~/" />
    <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />
    <link rel="stylesheet" href="_content/Radzen.Blazor/css/default.css" />
</head>
<body>
    ...some stuff...

    <script src="_framework/blazor.server.js"></script>
</body>
</html>

Solution

  • Although you're using Blazor, it's still an ASP.NET Core application at heart and the issue is really one about ASP.NET Core, routing and how static files are handled.

    As seen in this answer it's probably simplest to do this via a controller, rather than trying to coerce the router to process URLs with no extension. I've also done this for robots.txt in a project to control what is shown for different brands.

    I tried this:

        public class StaticContentController : Controller
        {
            [HttpGet]
            [Route("apple-app-site-association")]
            public ContentResult AppleAppSiteAssociation()
            {
                // source in root of wwwroot folder
                const string source = @"apple-app-site-association.json";
                string json = System.IO.File.ReadAllText(source);
                return Content(json, "application/json", Encoding.UTF8);
            }
        }
    

    The source file (with the .json extension) is in the project with a "Copy if newer" property set, so it's present in the /bin folder.

    Running: enter image description here