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

C# 将路由参数转换为整数的正确方法是什么?,c#,asp.net-mvc,model-binding,C#,Asp.net Mvc,Model Binding,我正在尝试从URL中提取ID。我的路线如下所示: public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{action}/{id}", defaults: new { controller

我正在尝试从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 }
    );
}
<li>@Html.ActionLink((string)link.Name, "Video", new { id = link.ID } )</li>
http://localhost:57762/Video/3 // <-- generated URL
操作链接和生成的URL如下所示:

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 }
    );
}
<li>@Html.ActionLink((string)link.Name, "Video", new { id = link.ID } )</li>
http://localhost:57762/Video/3 // <-- generated URL
这是奇怪的部分:

int id = Convert.ToInt32(RouteData.Values["id"].ToString());
视图正确地渲染了所有内容。我可以访问ViewBag.Treatment一整天,一切正常,但在我的浏览器加载完视图后,Visual Studio会引发此异常:

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

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

它正在抱怨这一行:

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

我做错了什么?

在控制器中,您可以指定
id
是什么:

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

public ActionResult Index2(string id)
{
  return View();
}
模型绑定器将自动转换值(如果不能转换,则抛出黄色屏幕)

我从你那里学到了一些技巧。(我想在这里复制整个内容,但实际上只有一个提示是相关的)

提示#1:更喜欢绑定而不是请求。表单

如果你这样写你的行为

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

    // ...

    return View();
}
。。那你就大错特错了。model binder可以避免您使用Request和HttpContext属性——这些属性使操作更难阅读和测试。其中一个步骤是使用FormCollection参数:

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

    // ...

    return View();
}
使用FormCollection,您不必深入研究请求对象,有时您需要这种低级别的控制。但是,如果您的所有数据都在Request.Form、route数据或URL查询字符串中,那么您可以让模型绑定发挥其魔力:

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

    return View();
}

在本例中,模型绑定器将创建newRecipe对象,并使用在请求中找到的数据填充它(通过将数据与配方的属性名称匹配)。这是纯粹的汽车魔法。有很多方法可以通过“白名单”、“黑名单”、前缀和标记接口来完成绑定过程。为了更好地控制绑定发生的时间,可以使用UpdateModel和TryUpdateModel方法。请注意无意绑定–请参阅JustinEtherEdge的。

您可以使用框架的绑定功能为您实现此操作:

public ActionResult Video(int? id)

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

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

   public ActionResult Video(int? id) ...

但是,当您实际拥有
id
并相应地调整路由时,可能更容易对案例进行单独操作。

Hmmm,为什么您的ActionResult视频没有
int id
参数?类似于公共行动结果视频(int-id)@RaphaëlAlthaus的东西,但事实并非如此necessary@RaphaëlAlthaus我不认为我完全理解你的评论。但看起来它可能会解决我的问题。你能给出一个完整的答案吗?@Selman22什么是不必要的?@anwyatt定义了一个参数(我对Raphael说了),因为你已经在routeconfig中定义了它。我想这应该可以用了。+1:注意,在OP的示例中,这也用作
索引
(或“home”)操作。考虑如何处理<代码> /<代码>(根没有代码> ID/COD>)URL。听起来好像你想回答OP没有问的问题。我相信模型绑定器会自动转换值(如果不能的话,扔掉黄色屏幕)。值得注意的是,在本例中,如果模型绑定器无法将字符串绑定到可为null的int,则
/Home/Index/Test
仍将抛出错误,但从积极的一面来看,如果url参数为空/null,则这是测试是否传递了Id的好方法(
.HasValue=false,如果没有传递值)。