处理访问者构建自己的网址并用他们喜欢的任何内容替换我们希望成为ID的最佳方式是什么?
例如:
ASP.Net MVC - handling bad URL parameters
但是用户可以轻松地将URL替换为:
https://stackoverflow.com/questions/foo
我想过让每个Controller Function参数都为String
,并且对它们使用Integer.TryParse()
- 如果通过那么我有一个ID并且可以继续,否则我可以将用户重定向到未知/未找到或索引视图。
Stack Overflow很好地处理它,我也想 - 你怎么做,或者你会建议什么?
答案 0 :(得分: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)。我将此作为练习留给用户解决。 :)
如果用户输入了网址“questions / foo”,他们就不会点击“问题”操作,而是通过它,因为它未通过参数约束。如果需要,您可以在捕获/默认路径中进一步处理:
routes.MapRoute(
"Catchall",
"{*catchall}", // This is a wildcard routes
new { controller = "Home", action = "Lost" }
);
这会将用户发送到Home控制器中的Lost动作。有关通配符的更多信息可以在here找到。
注意:Catchall应该作为LAST路由驻留。考虑到ASP.NET MVC中路由的惰性,这将意味着它将处理其下的所有其他路径。
答案 1 :(得分:5)
这是一些可能有用的有用信息。 如果你有一个行动方法
public ActionResult Edit(int? id)
{}
然后如果有人输入
/Home/Edit/23
参数id为23。 但如果有人输入
/Home/Edit/Junk
然后id将为null,这非常酷。我认为它会抛出一个演员错误或其他东西。这意味着如果id不是空值,那么它是一个有效的整数,可以传递给您的服务等进行数据库交互。
希望这能为您提供我在测试时找到的一些信息。
答案 2 :(得分:3)
在ASP.NET MVC中,您可以定义实现IActionFilter接口的过滤器。您可以使用此属性修饰您的操作,以便在操作之前,之后或之后执行。
在您的情况下,您将其定义为在“行动”之前执行。因此,如果传递的参数中存在错误,您将能够取消它。这里的关键好处是,您只需编写一次检查传递的参数的代码(即您在过滤器中定义它),并在控制器操作中的任何位置使用它。
在此处阅读有关MVC过滤器的更多信息:http://haacked.com/archive/2008/08/14/aspnetmvc-filters.aspx
答案 3 :(得分:2)
您可以将约束指定为正则表达式或定义自定义约束。有关更多信息,请查看此博客文章:
你仍然需要处理id 43243没有映射到任何可以作为IActionFilter或直接在你的控制器中处理的事情的情况。
答案 4 :(得分:0)
该方法的问题在于它们仍然可能传递一个不映射到页面的整数。如果他们这样做,只需返回404,就像你使用“foo”一样。除非你有明确的安全隐患,否则不用担心。