StaticFileMiddleware针对媒体类型的解析是通过一个名为ContentTypeProvider的对象来实现的,而默认使用的则是一个FileExtensionContentTypeProvider对象。顾名思义,FileExtensionContentTypeProvider是根据文件的扩展命名来解析媒体类型的。FileExtensionContentTypeProvider内部预定了数百种常用文件扩展名与对应媒体类型之间的映射关系,所以如果我们发布的静态文件具有标准的扩展名,StaticFileMiddleware就能为对应的响应赋予正确的媒体类型。
那么如果某个文件的扩展名没有在这个预定义的映射之中,或者我们需要某个预定义的扩展名匹配不同的媒体类型,我们应该如何解决呢?还是针对我们演示的这个实例,想在我将“~/wwwroot/img/ dophin1.jpg”这个文件的扩展名改成“.img”,毫无疑问StaticFileMiddleware将能为针对该文件的请求解析出正确媒体类型。这个问题具有若干不同的解决方案,第一种方案就是让StaticFileMiddleware支持不能识别的文件类型,并为它们设置一个默认的媒体类型,如下所示了具体采用的编程方式。
1: public class Program 2: { 3: public static void Main() 4: { 5: new WebHostBuilder() 6: .UseContentRoot(Directory.GetCurrentDirectory();) 7: .UseKestrel() 8: .Configure(app => app.UseStaticFiles(new StaticFileOptions { 9: ServeUnknownFileTypes = true, 10: DefaultContentType = "image/jpg" 11: })) 12: .Build() 13: .Run(); 14: } 15: }
上述这种解决方案只能设置一种默认媒体类型,如果具有多种需要映射成不同媒体类型的非识别文件类型,采用这种方案就无能为力了,所以最根本的解决方案还是需要将不能识别的文件类型和对应的媒体类型进行映射。由于StaticFileMiddleware使用的ContentTypeProvider是可以定制的,我们可以按照如下的方式显式地为StaticFileMiddleware指定一个FileExtensionContentTypeProvider对象作为它的ContentTypeProvider,然后将取缺失的映射添加到这个FileExtensionContentTypeProvider对象上。
1: public class Program 2: { 3: public static void Main() 4: { 5: FileExtensionContentTypeProvider contentTypeProvider = new FileExtensionContentTypeProvider(); 6: contentTypeProvider.Mappings.Add(".img", "image/jpg"); 7: 8: new WebHostBuilder() 9: .UseContentRoot(Directory.GetCurrentDirectory()) 10: .UseKestrel() 11: .Configure(app => app.UseStaticFiles(new StaticFileOptions{ 12: ContentTypeProvider = contentTypeProvider 13: })) 14: .Build() 15: .Run(); 16: } 17: }
将ASP.NET Core应用程序部署至生产环境中(CentOS7)