名称为(NameofController)的RedirectToAction无法定位操作

时间:2018-02-01 08:18:31

标签: c# asp.net-core asp.net-core-mvc

根据内联文档,ControllerBase.RedirectToAction同时采用操作名称和控制器名称:

// Parameters:
//   actionName:
//     The name of the action.
//
//   controllerName:
//     The name of the controller.
public virtual RedirectToActionResult RedirectToAction(string actionName, string controllerName);

现在,我们假设我想重定向到以下操作:

[Route("Whatever")]
public class WhateverController : Controller
{
    [HttpGet("Overview")]
    public IActionResult Overview()
    {
        return View();
    }
}

当然,我想使用nameof运算符“:

[Route("Home")]
public class HomeController : Controller
{
    [HttpGet("Something")]
    public IActionResult Something()
    {
        return RedirectToAction(
            nameof(WhateverController.Overview), // action name
            nameof(WhateverController) // controller name
        );
    }
}

但是该调用因错误InvalidOperationException: No route matches the supplied values.

而失败

我知道我可以将控制器名称硬编码为“what”而不是使用nameof运算符,但有没有办法从类名中获取正确的名称?

3 个答案:

答案 0 :(得分:5)

问题是nameof(WhateverController)返回WhateverController,而不是(无论如何)您和路由系统所期望的。
您可以使用nameof(WhateverController).Replace("Controller", "")来获得所需内容。

编辑:
如果你想要的不是硬编码的控制器/动作名称,那么最好使用像R4MVC这样的东西。

答案 1 :(得分:1)

nameof(WhateverController)将返回" WhateverController"。 RedirectToAction期待以" Whatever"。的形式获取您的控制器名称。 使用nameof代替硬编码字符串肯定是好的(在很多情况下),但在这种情况下看起来像是什么让你失望。

答案 2 :(得分:0)

我不喜欢扩展方法,因为在这种情况下它会污染 API,但如果您愿意,这并不是最糟糕的主意。

public static class StringExtensions
{
    /// <summary>
    /// Removes the word "Controller" from the string.
    /// </summary>
    public static string RemoveController(this string value)
    {
        string result = value.Replace("Controller", "");

        return result;
    }
}

使用

nameof(WhateverController).RemoveController();

更好的方法

创建一个基本控制器并将方法放入其中,而不是扩展方法。

public class ControllerBase : Controller
{
    /// <summary>
    /// Removes the word "Controller" from the string.
    /// </summary>
    protected string _(string value)
    {
        string result = value.Replace("Controller", "");

        return result;
    }
}

如果我认为方法名称没有用,我有时会使用 _,但如果您愿意,您可以将其替换为名称,例如 RemoveController

使用

public class SomeController : ControllerBase
{
    public ActionResult Index(string value)
    {
        return RedirectToAction(nameof(WhateverController.Overview), _(nameof(WhateverController)));
    }
}

您可以从上面的用法中看到 _ 如何不碍事并提高可读性。这也是我所做的,如果你不喜欢它,你不需要这样做。