将路由参数转换为整数的正确方法是什么?

时间:2014-03-26 16:10:52

标签: c# asp.net-mvc model-binding

我正在尝试从网址中提取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 }
    );
}

Action链接和生成的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抛出此异常:

  

mscorlib.dll中发生了'System.FormatException'类型的异常,但未在用户代码中处理

     

其他信息:输入字符串的格式不正确。

抱怨这条线:

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

我做错了什么?

3 个答案:

答案 0 :(得分: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();
}

使用FormCollection,您不必深入了解Request对象,有时您需要这种低级别的控制。但是,如果您的所有数据都在Request.Form,路由数据或URL查询字符串中,那么您可以让模型绑定发挥其神奇作用:

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

    return View();
}

在此示例中,模型绑定器将创建newRecipe对象,并使用在请求中找到的数据填充它(通过将数据与配方的属性名称进行匹配)。这是纯粹的自动魔术。使用“白名单”,“黑名单”,前缀和标记界面customize绑定过程有很多种方法。为了更好地控制绑定何时发生,您可以使用UpdateModel和TryUpdateModel方法。请注意无意识的绑定 - 请参阅Justin Etheredge的Think Before You Bind

答案 1 :(得分:2)

您可以使用它的绑定功能让框架为您完成此任务:

public ActionResult Video(int? id)

无需从路径数据中提取id明确。

答案 2 :(得分:2)

如果您真的希望该参数是可选的,那么您需要类似以下的内容:

   public ActionResult Video(int? id) ...

但是,当您实际拥有id并相应地调整路线时,可能更容易对案例采取单独行动。