2

我在我的项目中使用 RouteAttributes,它们工作正常,但在这种情况下除外:我有两个类似的操作,一个接受两个 int 参数,另一个只接受一个。

第一个接受两个参数并使用它们加载一个对象并将其传递给视图;第二个只是试图找到第二个变量的默认值,并重定向到第一个动作,传递两个变量。

问题是ActionResultExample(int idVar1),我希望被重定向到ControllerExample/Edit/idVar1/Brands/idVar2;但是我被重定向到ControllerExample/Edit/idVar1/Brands?idVar2=idVar2. 当然,这会产生一个无限重定向循环。

这是示例代码:

    [Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2}")]
    public ActionResult ActionResultExample(int idVar1, int idVar2)
    {
        var objectForView= ObjectController.Get(idVar1, idVar2);

        return View("ActionResultExample", objectForView);
    }

    [Route("ControllerExample/Edit/{idVar1}/Brands")]
    public ActionResult ActionResultExample(int idVar1)
    {
        ...
        var idVar2 = getDefaultVar2();
        return RedirectToAction("ActionResultExample", //redirects to ControllerExample/Edit/idVar1/Brands?idVar2=idVar2 instead of ControllerExample/Edit/idVar1/Brands/idVar2
            new {idVar1= idVar1, idVar2 = idVar2 });
    }
4

3 回答 3

3

您可以使用 1 个路由和 1 个操作方法来执行此操作:

在这里,我们使用 ? 表示最后一个 URL 参数是可选的,我们在 action 方法中使用默认方法参数做同样的事情。

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2?}")]
public ActionResult ActionResultExample(int idVar1, int? idVar2 = null)
{
    var idVar2Int = !idVar2.HasValue ? getDefaultVar2() : idVar2.Value;
    var objectForView= ObjectController.Get(idVar1, idVar2Int);

    return View("ActionResultExample", objectForView);
}

如果您真的想将此作为 2 个单独的操作方法,您可能需要升级到 System.Web.Mvc 5.1(可以通过 nuget 完成)。然后,您可以在 RouteAttribute 上使用 Order 参数。但是,您还应该重命名至少一个操作方法,因为在 MVC 中,您不应该有 2 个具有相同名称的 GET 重载

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2}", Order = 1)]
public ActionResult ActionResultExample(int idVar1, int idVar2)
{
    var objectForView= ObjectController.Get(idVar1, idVar2);

    return View("ActionResultExample", objectForView);
}

[Route("ControllerExample/Edit/{idVar1}/Brands", Order = 2)]
public ActionResult ActionResultExampleWithoutDefaults(int idVar1)
{
    ...
    var idVar2 = getDefaultVar2();
    return RedirectToAction("ActionResultExample", //redirects to ControllerExample/Edit/idVar1/Brands?idVar2=idVar2 instead of ControllerExample/Edit/idVar1/Brands/idVar2
        new {idVar1= idVar1, idVar2 = idVar2 });
}
于 2014-02-14T13:26:04.250 回答
0

我还没有使用 RouteAttribute,但它看起来像一个订单问题。

检查http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#order

在 .\App_Start\RouteConfig.cs 中进行路由的旧方法,您必须以正确的方式订购路由。如果其他一切都失败了,则使用最后一条路线。

因此,使用您需要的 RouteAttribute 设置路线的顺序。也许 RouteAttribute 有可能,也许不是。如果不是,您将不得不退回到旧的做事方式。

于 2014-02-14T13:27:54.140 回答
0

不支持对所有参数使用相同的名称,因为 ASP.NET MVC 无法区分您是要使用 idVar1 和 idVar2 作为路由值还是使用 idVar2 作为查询字符串值。将代码更改为第二种方法以使用另一个路由值名称:

    [Route("ControllerExample/Edit/{idVar3}/Brands")]
    public ActionResult ActionResultExample(int idVar3)
    {
        var idVar2 = 100;
        return RedirectToAction("ActionResultExample",
            new { idVar1 = idVar3, idVar2 = idVar2 });
    }

这应该按预期工作。

但是,如果您仅使用 2 种方法为 idVar2 提供默认值,请注意您不需要。你可以做:

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2=100}")]

设置默认值 100。或者在控制器上使用可为空的类型:

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2?}")]
 public ActionResult ActionResultExample(int idVar1, int? idVar2)

请注意,路由值名称以要设置的路由属性中的问号结尾,这是一个可选参数。

于 2014-02-14T13:32:09.440 回答