16

处理构建自己的 URL 并用他们喜欢的任何东西替换我们期望的 ID 的访问者的最佳方法是什么?

例如:

ASP.Net MVC - 处理错误的 URL 参数

但用户可以轻松地将 URL 替换为:

https://stackoverflow.com/questions/foo

我考虑过让每个控制器函数参数 a String,并Integer.TryParse()在它们上使用 - 如果通过了,那么我有一个 ID 并且可以继续,否则我可以将用户重定向到一个未知/未找到或索引视图。

Stack Overflow 可以很好地处理它,我也想这样做 - 你是怎么做的,或者你有什么建议?

4

5 回答 5

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”,他们将不会点击 Question 操作,并通过它,因为它失败了参数约束。如果需要,您可以在包罗万象/默认路由中进一步处理它:

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

这会将用户发送到 Home 控制器中的 Lost 操作。可以在此处找到有关通配符的更多信息。

注意:Catchall 应该作为 LAST 路由驻留。考虑到 ASP.NET MVC 中路由的惰性特性,将其置于链的更上方意味着它将处理其下方的所有其他路由。

于 2008-10-26T02:14:59.413 回答
5

这里有一些有用的信息可能会有所帮助。如果你有一个动作方法

public ActionResult Edit(int? id)
{}

那么如果有人输入

/Home/Edit/23

参数 id 将为 23。但是如果有人输入

/Home/Edit/Junk

那么 id 将是 null 这很酷。我认为它会抛出一个演员错误或什么的。这意味着如果 id 不是空值,那么它是一个有效的整数,可以传递给您的服务等以进行数据库交互。

希望这可以为您提供一些我在测试时发现的信息。

于 2008-10-26T00:08:19.030 回答
4

在 ASP.NET MVC 中,您可以定义一个实现 IActionFilter 接口的过滤器。您将能够使用此属性装饰您的操作,以便在您的操作之前、之前或之后执行它。

在您的情况下,您将定义它在您的操作“之前”执行。因此,如果传递的参数中有错误,您将能够取消它。这里的主要好处是您只需编写检查传递参数一次的代码(即您在过滤器中定义它)并在控制器操作中的任何地方使用它。

在此处阅读有关 MVC 过滤器的更多信息:http: //haacked.com/archive/2008/08/14/aspnetmvc-filters.aspx

于 2008-10-25T13:13:49.783 回答
2

您可以将约束指定为正则表达式或定义自定义约束。请查看此博客文章以获取更多信息:

http://weblogs.asp.net/stephenwalther/archive/2008/08/06/asp-net-mvc-tip-30-create-custom-route-constraints.aspx

您仍然需要处理 id 43243 没有映射到可以作为 IActionFilter 或直接在控制器中处理的任何内容的情况。

于 2008-10-25T13:30:06.687 回答
0

这种方法的问题是它们仍然可能传递一个不映射到页面的整数。如果他们这样做,只需返回 404,就像使用“foo”一样。除非您有明确的安全隐患,否则无需担心。

于 2008-10-25T12:50:55.987 回答