2009-08-19 68 views
6

我想根据MIME类型不同地处理请求。例如,我有PDF,图像和其他媒体文件,我想根据各自的MIME类型禁止访问。任何想法如何做到这一点?谢谢您的帮助。如何获取ASP.NET C#中请求的文件的MIME类型?

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

+0

这是关于对这些文件的上传限制或下载 – 2009-08-19 19:54:22

+0

这是对于下载和/或URL重写。 – mkelley33 2009-08-19 19:59:26

回答

10

.NET的MIME类型映射存储在System.Web.MimeMapping类报价GetMimeMapping方法。

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

如果采取这种方法,只需创建受支持扩展列表及其MIME类型并将其存储在字典中即可。 (内MimeMapping名单冗长一点点)

+0

这正是我所走的路线。我相信我错过了一些扩展,但它们很可能是最好的处理角落案例,因为它们满足“正在生产/工作的软件”要求LOL。感谢您的建议!我从来不知道MimeMappings。很酷! – mkelley33 2009-08-19 20:49:04

+2

从4.5开始,这门课已经上市!用方便的'GetMimeMapping(string fileName)'方法。 - http://msdn.microsoft.com/en-us/library/system.web.mimemapping.getmimemapping.aspx – Snixtor 2013-02-08 01:50:36

0

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

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

在ProcessRequest(或BeginProcessRequest如果你实现一个异步处理程序),你可以调用HttpContext.Current.Server.MapPath(“〜”+ HttpContext.Current.Request.Path)(可能是一个更好的方法来做到这一点)获取当前请求的静态文件。

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

不知道如果这就是你想要什么,但希望它有助于

+0

这与我想要的非常接近,但我希望有一种更自动的方式来执行此操作,而不是分析扩展名。更多沿着Request.MIMEType的行。谢谢您的意见! – mkelley33 2009-08-19 20:44:04

1

此信息是在注册表中,HKEY_CLASSES_ROOT\<file_extension>\Content Type

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

感谢您的输入,但我提交的技术要求决定不需要注册表访问。 – mkelley33 2009-08-19 20:45:40

9

我数个月前也有类似的问题,周围System.Web.MimeMapping这种简单的包装类(如理查德·绍洛伊提到)解决了这个问题:

/// <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 }); 
    } 
} 
+1

任何通过引用公共类型避免肮脏的黑客的问题? 'Assembly.GetAssembly(typeof运算(System.Web.HttpApplication))'。只要方法和引用类型不改变或消失,那就是...? – 2010-06-30 20:13:50

+6

我喜欢Assembly的变量名称。 – 2010-08-19 15:06:39

8

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); 
+0

不错的一个..虽然我不明白。我仍然在.NET 4,但框架似乎像你描述的行为(这是像在.NET 4.5中)..非常奇怪 – mare 2012-06-21 22:50:12

+1

@mare你可能已经安装了.NET 4.5 - 这是一个就地升级,所以程序集在运行时会有新的代码,但是VS在编译时会限制.NET 4.0可用的代码。 – 2013-02-11 01:05:56