2008-10-25 149 views
16

處理訪問者構建自己的URL並用他們喜歡的任何東西替換我們所期望的ID的最佳方式是什麼?ASP.Net MVC - 處理錯誤的URL參數

例如:

ASP.Net MVC - handling bad URL parameters

但用戶可以很容易地與更換網址:

https://stackoverflow.com/questions/foo

我想使每一個控制器功能參數String的,並在它們上使用Integer.TryParse() - 如果通過,那麼我有一個ID並可以繼續,否則我可以將用戶重定向到未知/未找到或索引視圖。

堆棧溢出處理它很好,我也想 - 你怎麼做,或者你會建議什麼?

回答

12

這裏有你們這樣一個路徑的一個例子,對數量的限制:

routes.MapRoute(
    "Question", 
    "questions/{questionID}", 
    new { controller = "StackOverflow", action = "Question" }, 
    new { questionID = @"\d+" } //Regex constraint specifying that it must be a number. 
); 

這裏我們設置questionID至少有一個數字。這也將阻止任何包含除了整數之外的任何URL,並且也阻止需要可爲空的int。

注意:這沒有考慮到大於Int32範圍的數字(-2147483647 - +2147483647)。我將此作爲練習留給用戶解決。 :)

如果用戶輸入URL「questions/foo」,他們將不會遇到問題操作,並且通過它,因爲它沒有參數約束。如果需要,您可以在catchall/default路徑中進一步處理它:

routes.MapRoute(
    "Catchall", 
    "{*catchall}", // This is a wildcard routes 
    new { controller = "Home", action = "Lost" } 
); 

這會將用戶發送到Home控制器中的Lost操作。有關通配符的更多信息可以參見here

注意:Catchall應該作爲LAST路線。考慮到ASP.NET MVC中路由的惰性,將它放在鏈的更上方意味着這將處理其下的所有其他對象。

+2

這看起來像是一個很好的方式來處理瘋狂的用戶=) – JOBG 2009-08-20 22:13:46

0

該方法的問題是它們仍然可能傳遞一個不映射到頁面的整數。如果他們這樣做,就返回一個404,就像你用「foo」一樣。除非您有明確的安全隱患,否則不要擔心。

+0

當然,我不得不檢查整數是否有效,但是使用String作爲Function參數類型的路要走? - TaskList示例(http://www.asp.net/learn/mvc/tutorial-01-cs.aspx〜35min 43s)將ID強制鍵入Integer,並在'foo'傳入時導致錯誤: o/ – Andrew 2008-10-25 13:04:28

3

在ASP.NET MVC中,您可以定義一個實現IActionFilter接口的過濾器。您將能夠使用此屬性修飾您的動作,以便在動作之前或之後執行動作。

對於您的情況,您將其定義爲在您的操作之前「執行」。因此,如果傳遞參數中有錯誤,您將能夠取消它。這裏最關鍵的好處是你只編寫一次檢查通過的參數的代碼(即你在過濾器中定義它)並在你的控制器動作中隨時隨地使用它。

瞭解更多關於MVC過濾器在這裏:http://haacked.com/archive/2008/08/14/aspnetmvc-filters.aspx

5

以下是一些有用的信息,可能有所幫助。 如果你有一個動作方法

public ActionResult Edit(int? id) 
{} 

然後如果

/Home/Edit/23 

有人類型的參數ID將是23 但是如果有人類型在

/Home/Edit/Junk 

則ID將null這非常酷。我認爲它會拋出一個鑄造錯誤或什麼的。這意味着如果id不是一個空值,那麼它是一個有效的整數,可以傳遞給你的服務等數據庫交互。

希望這能爲您提供一些我在測試時發現的信息。

+0

另外,ModelState中會出現一個模型錯誤,它反映了參數「id」的問題。 – 2008-10-26 00:23:54