MVC隐式重定向到另一个JsonResult动作可能吗?

时间:2017-02-10 09:58:36

标签: c# asp.net-mvc-5 jsonresult

我有一个操作,并且根据foo的值,我想重定向到特定操作:

 public JsonResult FirstAction(string foo) // foo == "SecondAction"
 {
     return RedirectToAction(foo);
 }

 public JsonResult SecondAction() { }

这不起作用,因为RedirectToAction没有返回JsonResult并且无法转换(据我所知)。

我知道我可以在这里使用一些条件,即switch foo以确定调用哪个方法,但我想尽可能隐含它。

4 个答案:

答案 0 :(得分:0)

RedirectToAction以Http 302响应,它指示用户的浏览器请求不同的URI。

您只需将方法的返回类型更改为ActionResult,您的代码应按预期工作。

答案 1 :(得分:0)

因此,如果我理解正确,您希望根据传递给方法的参数值执行不同的操作和不同的逻辑。

你可以这样做的一种方法是使用路由系统,但如果参数的可能值是可管理的大小,我只建议你选择这个。

然后在 RouteConfig.cs 文件中:

public static void RegisterRoutes(RouteCollection routes)
{
    // ... other routes

    string[] possibleValueSet1 = new[] { ... };
    string[] possibleValueSet2 = new[] { ... };

    for (int i = 0; i < possibleValueSet1.Length; ++i)
    {
        routes.MapRoute(
            name: "YourActionWithValueSet1_" + i.ToString(),
            url: "ControllerName/FirstAction/" + possibleValueSet1[i],
            defaults: new { controller = "ControllerName", action = "FirstAction", foo = possibleValueSet1[i] }
        );
    }

    for (int i = 0; i < possibleValueSet2.Length; ++i)
    {
        routes.MapRoute(
            name: "YourActionWithValueSet2_" + i.ToString(),
            url: "ControllerName/SecondAction/" + possibleValueSet2[i],
            defaults: new { controller = "ControllerName", action = "SecondAction", foo = possibleValueSet2[i] }
        );
    }

}

这样,foo的每个可能值(应该由逻辑#1处理)都有自己的URL,这同样适用于逻辑#2应该处理的值。

我认为你已经可以看到这种情况发生了很大的变化,而隐含的情况下,它并不比简单地在行动中实施你想要避免的决定更具可维护性或通常更好。您所要求的听起来像是基于价值的过载&#34; C#不允许的,上面的代码是让路由引擎为你做的一种肮脏的解决方法,虽然它不是实际的重载,它只是根据硬编码的可能值映射到不同的动作。

答案 2 :(得分:0)

您应该返回SecondAction本身而不是RedirectToAction。

public JsonResult FirstAction(string foo) // foo == "SecondAction"
{
     return SecondAction();
 }

 public JsonResult SecondAction() { }

答案 3 :(得分:0)

除了我上面描述的基于路线的方法之外,您还应该查看ActionMethodSelectorAttribute属性。这是HttpPostHttpGet所基于的属性,可让您通过返回布尔值来控制操作是否有效。这是您需要覆盖的方法:

public abstract bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo);

然后你可以实现这样的东西:

public class ValidBasedOnFoo
{
    public int MethodNum { get; set; }

    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
        var foo = controllerContext.HttpContext.Request["foo"] as string;

        if (MethodNum == 1)
            return YourDecisionLogicForFirstAction(foo);
        else if (MethodNum == 2)
            return YourDecisionLogicForSecondAction(foo);
        else throw new InvalidOperationException("Unknown method number.");
    }
}

然后在您的控制器中,操作如下:

[ValidBasedOnFoo(1)]
public JsonResult FirstAction(string foo) { ... }

[ValidBasedOnFoo(2)]
public JsonResult SecondAction(string foo) { ... }

如果值适合于操作,这将允许执行操作。属性中使用的数字是告诉使用哪个决策逻辑,如果对您更清楚,您也可以为每个操作实现一个属性。