2014-03-26 100 views
0

我想從URL中提取一個ID。我的路線是這樣的:將路由參數轉換爲整數的正確方法是什麼?

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapRoute(
     name: "Default", 
     url: "{action}/{id}", 
     defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
    ); 
} 

和動作鏈接和生成的URL看起來像這樣:

<li>@Html.ActionLink((string)link.Name, "Video", new { id = link.ID })</li> 
http://localhost:57762/Video/3 // <-- generated URL 

然後我們得到的控制器:

public ActionResult Video() 
{ 
    int id = Convert.ToInt32(RouteData.Values["id"].ToString()); 
    var treatment = Treatment.Find(id); 
    ViewBag.Title = treatment.Name; 
    ViewBag.Treatment = treatment; 
    return View(); 
} 

這裏的怪異的一部分:

該視圖呈現正確的一切。我整天都可以訪問ViewBag.Treatment,一切工作正常,但第二次我的瀏覽器完成加載視圖時,Visual Studio將引發此異常:

型「System.FormatException」的異常出現在mscorlib中。但沒有在用戶代碼中處理

附加信息:輸入字符串格式不正確。

據抱怨這一行:

int id = Convert.ToInt32(RouteData.Values["id"].ToString()); 

我在做什麼錯?

+1

嗯,爲什麼你的ActionResult Video沒有'int id'參數?類似'public ActionResult Video(int id)' –

+0

@RaphaëlAlthaus沒有必要 –

+0

@RaphaëlAlthaus我不認爲我完全理解你的評論。但它看起來可能會解決我的問題。你能發表一個完整的答案嗎? – drewwyatt

回答

4

在控制你到指定id是什麼:

public ActionResult Index(int id) 
{ 
    return View(); 
} 

public ActionResult Index2(string id) 
{ 
    return View(); 
} 

模型綁定將值自動轉換(或拋出一個黃色屏幕,如果它不能)。

一些技巧取自6 Tips for ASP.NET MVC Model Binding。 (我想在這裏複製整個事情,但真正只有一個是相關的)。

提示#1:不想綁定過的Request.Form

如果你正在寫你這樣的行爲..

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create() 
{ 
    Recipe recipe = new Recipe(); 
    recipe.Name = Request.Form["Name"]; 

    // ... 

    return View(); 
} 

..然後你正在做這一切是錯誤的。模型聯編程序可以使您免於使用Request和HttpContext屬性 - 這些屬性使操作更難以閱讀並且難以測試。一是加大將使用的FormCollection參數,而不是:

public ActionResult Create(FormCollection values) 
{ 
    Recipe recipe = new Recipe(); 
    recipe.Name = values["Name"];  

    // ... 

    return View(); 
} 

有了你不必深入到Request對象中的FormCollection,有時你需要控制的這種低水平。但是,如果所有的數據都在的Request.Form,路線數據,或URL查詢字符串,那麼你可以讓模型綁定工作它的神奇:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(Recipe newRecipe) 
{    
    // ... 

    return View(); 
} 

在這個例子中,模型綁定將創建newRecipe對象並使用它在請求中找到的數據填充它(通過將數據與配方的屬性名稱進行匹配)。這是純粹的自動魔法。有很多方法可以用「白名單」,「黑名單」,前綴和標記界面來綁定過程customize。要進一步控制綁定發生的時間,可以使用UpdateModel和TryUpdateModel方法。只要小心無意的約束 - 請參閱賈斯廷Etheredge的Think Before You Bind

+0

+1:請注意,在OP的示例中,它也用作「索引」(或「主頁」)操作。考慮如何處理'/'(root沒有'id')url。 –

+0

聽起來像你想要一個OP沒有問的問題的答案。 –

+0

我相信模型聯編程序會自動轉換這個值(或者如果不能的話就會拋出一個黃色的屏幕)。*是公正的警告。 –

2

與它的結合能力,你可以得到的框架,爲你這樣做:

public ActionResult Video(int? id) 

無需從路由數據明確地提取ID。

2

你想要的東西像下面的,如果你真的希望這個參數是可選的:

public ActionResult Video(int? id) ... 

但它可能會更容易對案件獨立行動時,你實際上有id並相應地調整路線。

+1

重要的是要注意,在這個例子中,如果模型聯編程序不能將字符串綁定到可爲空的int,所以'/ Home/Index/Test'仍然會拋出一個錯誤,但是在積極的一面,如果url參數是空的/ null,那麼這是一個測試Id是否被傳遞的好方法(如果沒有值傳遞,'.HasValue = false')。 –

相關問題