RedirectToAction生成错误的url(querystring参数而不是routedata param)

时间:2014-02-14 13:08:19

标签: c# asp.net-mvc asp.net-mvc-5 redirecttoaction routeattribute

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

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

问题在于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 });
    }

3 个答案:

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

如果您真的希望将其作为两个单独的操作方法,则可能需要升级到System.Web.Mvc 5.1(可以通过nuget完成)。然后,您可以在RouteAttribute上使用Order参数。但是,您还应该rename at least one of the action methods because in MVC, you should not have 2 GET overloads with the same name

[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 });
}

答案 1 :(得分: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可能不是。如果不是这样,你就不得不回归旧的做事方式。

答案 2 :(得分:0)

不支持对所有参数使用相同的名称,因为ASP.NET MVC无法区分是否要将idVar1和idVar2作为routevalues转到路由,或者使用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)

请注意,routevalue名称以route属性中的问号结尾,以设置为可选参数。