【问题标题】:How do I get the MIME type of a file being requested in ASP.NET C#?如何获取 ASP.NET C# 中请求的文件的 MIME 类型?
【发布时间】:2010-11-21 02:19:14
【问题描述】:

我想根据 MIME 类型以不同方式处理请求。例如,我有 PDF、图像和其他媒体文件,我想根据它们各自的 MIME 类型来禁止访问它们。关于如何做到这一点的任何想法?感谢您的帮助。

我还应该注意,访问 Windows 注册表不是我的应用程序的选项。

【问题讨论】:

  • 这是关于限制这些文件的上传或下载
  • 这是关于下载和/或 URL 重写的。
  • 如果您使用的是 ASP.NET Core,请参阅stackoverflow.com/a/35880687

标签: c# asp.net httpwebrequest httphandler


【解决方案1】:

.NET 的 mime 类型映射存储在提供 GetMimeMapping 方法的 System.Web.MimeMapping 类中。

在 .NET 4.5 之前,此类被标记为 internal,因此对您的代码不可用。在这种情况下,您能做的最好的事情就是窃取列表,您可以使用 Reflector 获取该列表并反编译静态构造函数 (cctor)。

如果采用这种方法,您最好创建一个支持的扩展及其 mime 类型的列表并将其存储在字典中。 (MimeMapping 里面的列表有点冗长)

【讨论】:

  • 这正是我采取的路线。我确定我错过了一些扩展,但它们很可能是最好处理的极端情况,因为它们的出现是为了满足“生产/工作软件”的要求 LOL。感谢您的建议!我从来不知道 MimeMappings。很酷!
  • 从 4.5 开始,这个类已经公开了!使用方便的GetMimeMapping(string fileName) 方法。 - msdn.microsoft.com/en-us/library/…
【解决方案2】:

几个月前我遇到了类似的问题,并通过这个简单的 System.Web.MimeMapping 包装类解决了它(正如 Richard Szalay 所提到的):

/// <summary>
/// This class allows access to the internal MimeMapping-Class in System.Web
/// </summary>
class MimeMappingWrapper
{
    static MethodInfo getMimeMappingMethod;

    static MimeMappingWrapper() {
        // dirty trick - Assembly.LoadWIthPartialName has been deprecated
        Assembly ass = Assembly.LoadWithPartialName("System.Web");
        Type t = ass.GetType("System.Web.MimeMapping");

        getMimeMappingMethod = t.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic);
    }

    /// <summary>
    /// Returns a MIME type depending on the passed files extension
    /// </summary>
    /// <param name="fileName">File to get a MIME type for</param>
    /// <returns>MIME type according to the files extension</returns>
    public static string GetMimeMapping(string fileName) {
        return (string)getMimeMappingMethod.Invoke(null, new[] { fileName });
    }
}

【讨论】:

  • 通过引用公共类型来避免脏黑客有什么问题吗? Assembly.GetAssembly(typeof(System.Web.HttpApplication))。只要方法和引用的类型不改变或消失,那就是……?
  • 我喜欢你的 Assembly 变量名。
【解决方案3】:

来自Why would Reflection search suddenly not find anything?的交叉发帖

好消息是MimeMapping 类及其GetMimeMapping 方法似乎可以在.NET 4.5 中公开。

但是,这意味着above answer 中给出的代码会中断,因为它只在NonPublic 方法中搜索GetMimeMapping

为确保与 .NET 4.5 的兼容性(但保留 .NET 4.0 及更早版本中的功能),请更改...

getMimeMappingMethod = t.GetMethod("GetMimeMapping", 
    BindingFlags.Static | BindingFlags.NonPublic);

…到:

getMimeMappingMethod = t.GetMethod("GetMimeMapping",
    BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);

【讨论】:

  • 不错的一个..虽然我不明白。我仍在使用 .NET 4,但该框架的行为似乎与您描述的一样(就像在 .NET 4.5 中一样)..非常奇怪
  • @mare 你可能已经安装了 .NET 4.5 - 这是一个就地升级,因此程序集将在运行时拥有新代码,但 VS 在编译时将你限制为 .NET 4.0 可用的代码.
【解决方案4】:

此信息在注册表中,HKEY_CLASSES_ROOT\&lt;file_extension&gt;\Content Type

using(var key = Registry.ClassesRoot.OpenSubKey(".htm"))
{
    string mimeType = key.GetValue("Content Type") as string;
}

【讨论】:

  • 感谢您的意见,但我收到的技术要求表明无法访问注册表。
【解决方案5】:

如果我正确理解了您的问题,您正在提供静态文件,并且希望能够对静态文件请求进行处理,以确定用户是否有权访问该文件。 (基于 MIME 类型)

如果您通过自定义 IHttpHandler 映射所有文件请求(请参阅 web.config 文件的处理程序部分),您应该能够完成此操作。

在 ProcessRequest(或 BeginProcessRequest,如果您实现异步处理程序)中,您可以调用 HttpContext.Current.Server.MapPath("~" + HttpContext.Current.Request.Path) (可能是更好的方法)来获取当前请求的静态文件。

然后您可以分析该文件的扩展名来做出决定。

不确定这是否是您想要的,但希望对您有所帮助

【讨论】:

  • 这与我想要的非常接近,但我希望有一种更自动的方式来做这件事,而不是分析扩展。更多类似 Request.MIMEType 的内容。感谢您的意见!
猜你喜欢
  • 1970-01-01
  • 2010-09-30
  • 2014-01-30
  • 2015-09-13
  • 2018-12-01
  • 2011-08-02
  • 2011-04-20
  • 2014-09-28
  • 2010-11-24
相关资源
最近更新 更多