2009-08-19 117 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