2012-02-19 39 views
0

我正在管理一個MVC3應用程序,我需要支持第三方創建鏈接到我的域中的資產的能力。因爲某些環節的切片,並通過郵件合併和其他文本編輯問題切丁,連錯別字的網址已經出臺,如:使用路線糾正URL中的拼寫錯誤

/Content/ima!+ges/email/spacer.gif 

/Content/image++s/email+/spacer.gif 

我想剝奪這些無關在嘗試提供服務之前,RegEx提供的字符。我認爲這是一種Route方法可以完成的事情,我希望有一兩個指向這些方法的文章。

增編(因爲我需要的格式):

實現@彌敦道的路由我無法將文件名發送到控制器處理器 - 它總是看到在一個空值傳遞我都試過'filepath '和'path'具有相同的'空'結果。

 routes.MapRoute(
      "MangledFilename", 
      "{*filepath}", 
      new { controller = "MangledFilename", action = "ServeFile" } 
     ); 

我覺得這是配置通配符處理上IISExpress和我單獨尋找一個解決方案的問題。更嚴重的直接問題是你的建議如何返回HttpNotFound - 我得到一個硬IIS異常(執行暫停與YellowScreenDeath),而不是沉默的404結果。

public ActionResult ServeFile(string filePath) 
    { 
     if (filePath != null) // workaround the null 
     { 
       ... 
     } 
     return HttpNotFound(); 
    } 

THX

回答

0

我想沿着這一做法的東西應該工作:

首先像這樣添加路由到您的路線註冊聲明的末尾:

routes.MapRoute(
     "MangledFilename", 
     "{*filepath}", 
     new { controller = "MangledFilename", action = "ServeFile" }); 

如果你的避風港之前沒有看到它們,開幕後*的路由參數{是通配符參數,在這種情況下,它將匹配ent ire路徑。如果您想將此行爲限制在您的content目錄中,您也可以將其編寫爲content/{*filepath}

然後控制器這樣的事情應該做的伎倆:

public class MangledFilenameController : Controller 
    { 
     public ActionResult ServeFile(string filePath) 
     { 
      filePath = CleanFilePath(filePath); 
      var absolutePath = Server.MapPath(filePath); 

      if (System.IO.File.Exists(absolutePath)) 
      { 
       var extension = System.IO.Path.GetExtension(absolutePath); 
       var contentType = GetContentTypeForExtenion(extension); 
       return File(absolutePath, contentType); 
      } 

      return HttpNotFound(); 
     } 

     private string CleanFilePath(string filepath) 
     { 
      //clean the path up 
      return filepath; 
     } 

     private string GetContentTypeForExtenion(string extension) 
     { 
      //you will want code here to map extensions to content types 
      return "image/gif"; 
     } 
    } 

在問候中映射擴展到MIME /內容類型爲GetContentTypeForExtension方法,你可以選擇硬編碼類型你期待服務,或使用在這篇文章中詳細介紹的解決方案之一:

File extensions and MIME Types in .NET

編輯:

想過之後,我意識到還有另一種方法可以處理ServeFile操作。重定向到現有的文件可能會更簡單。我要離開我上面寫的原始方法,在這裏將替代一個:

public ActionResult ServeFile(string filePath) 
    { 
     filePath = CleanFilePath(filePath); 
     var absolutePath = Server.MapPath(filePath); 

     if (System.IO.File.Exists(absolutePath)) 
     { 
      return RedirectPermanent(filePath); 
     } 

     return HttpNotFound(); 
    } 
+0

感謝彌敦道 - 我認爲有一個代碼位,你'返回HttpNotFound();'的問題 - 我編輯的問題中的細節。 - 讚賞 – justSteve 2012-02-27 15:46:35

0

我相信@Nathan安德森提供了一個很好的答案,但它似乎不完整的。

如果您想糾正錯別字,並且類型與您提到的類型一樣簡單,那麼您可以使用Nathan代碼,但在嘗試查找該文件之前,可以刪除路徑中的任何加號或感嘆號字符,並且可以執行它是這樣的:

String sourcestring = "source string to match with pattern"; 
String matchpattern = @"[+!]"; 
String replacementpattern = @""; 
Console.WriteLine(Regex.Replace(sourcestring,matchpattern,replacementpattern)); 

My Regex Tester工具生成此代碼。

這是您需要的代碼。此代碼還會從文件名中刪除任何+字符。如果你不想要這種行爲,你可以選擇一個沒有文件名的子字符串,只需要替換+和!文件名之前的字符。

+0

這有幫助 - thx。 – justSteve 2012-02-27 15:47:33

+0

@justSteve,那麼爲什麼不提高它並將其標記爲正確的答案,以便其他人可以更快地獲得答案? – 2012-02-27 18:57:37

+0

有幫助但不是問題的真正意義是什麼?如何處理後續? – justSteve 2012-02-28 11:58:11