【问题标题】:ActionResult with different parameters具有不同参数的 ActionResult
【发布时间】:2015-03-25 13:27:14
【问题描述】:

我有一个关于 ASP.NET MVC 中 ActionResult 行为的简单问题。

我需要有两个名称相同但参数不同的操作结果。 我特别想要这个:

public class CarController : Controller
{
    [AuthorizeUser(AccessLevel = "New")]
    public ActionResult New()
    {
       return View("New");
    }

    [AuthorizeUser(AccessLevel = "New?type=2")]
    public ActionResult New(string type)
    {
       return View("NewCarType2");
    }
}

我知道我可以用不同的名称重命名第二个操作结果,但如果我想将其保留为“新”?

我尝试使用 route.maps 没有成功。 我想这样做:

 public class CarController : Controller
{
    public ActionResult New (string type) {
        if(!string.IsNullOrEmpty(type) && type.Equals("2")) {
            return NewCarType2()
        else
            return New()
        }
    }
    [AuthorizeUser(AccessLevel = "New?type=2")]
    private ActionResult NewCarType2()
    {
        return View("NewCarType2");
    }
    [AuthorizeUser(AccessLevel = "New")]
    private ActionResult New()
    {
        return View("New");
    }
}

但用户授权的属性被忽略.. 方法的签名也是 public 和属性 [NoAction]。

我发现做我想做的事情的唯一方法是使用类继承:

public class CarController : Controller
{
    public virtual ActionResult New(string type)
    {
        if (!string.IsNullOrEmpty(type) && type.Equals("2"))
            return RedirectToAction("NewCarType2", "CarOverride");
        else
            return RedirectToAction("New", "CarOverride");
    }
}  
public class CarOverrideController : CarController
{
    [AuthorizeUser(AccessLevel = "New?type=2")]
    public ActionResult NewCarType2(string type)
    {
        return View("NewCarType2");
    }
    [AuthorizeUser(AccessLevel = "New")]
    public override ActionResult New(string type)
    {
        return View("New");
    }
 }

但是这是处理这种情况的正确方法吗(ActionResults 的名称部分写的都不同)?

【问题讨论】:

  • 其实这就是方法重载的概念stackoverflow.com/a/436935/3354492这个帖子会回答你的问题。
  • 另一种管理方法是将一个定义为 [HttpGet] 操作,另一个定义为 [HttpPost] 操作 注意:不确定这是您想要的,但它可以这样工作(无论如何,参数必须不同)
  • 绝对建议不要在这里使用继承
  • 您的 AuthorizeUser 属性执行什么逻辑?
  • @timothyclifford 与 AuthorizeUser 属性我检查用户的角色以及他是否有权显示页面(使用 IsInRole 方法)

标签: c# asp.net asp.net-mvc asp.net-mvc-4 actionresult


【解决方案1】:

有两种可能做你想做的事。

正如 Puneet 在评论中回复的那样,您可以重载控制器中的方法,如 this 帖子中所述。

[ActionName("MyOverloadedName")]

您可以在控制器方法上定义Route 属性,并将操作从不同的 URL 路由到此方法。如需进一步说明,请访问ASP.NET Tutorial

 [Route("URL")]
public ActionResult New(string type) { ... }

【讨论】:

  • 但是我必须调用 2 个不同的 URL(“new”和“newOverloaded”),对吗?我可以使用相同的 URL(“新”)并且选择是否存在参数吗?
  • 另一种可能性是定义一个带有可选参数的方法。因此,您的控制器中只有 1 个操作,并且您的参数为 null 或设置为默认值(如果用户未提供数据)。这是你想要的吗? msdn.microsoft.com/en-us/library/dd410269%28v=vs.100%29.aspx
  • 是的,我认为是一种方法。我将使用可选参数执行一种方法,如果值为空,我将检查一个角色的授权,否则检查另一个角色。如果检查结果为真,我将显示该页面。相反,使用 [Route("URL")] 我可以指定一个类似 'Car/New?type=2' 的 url,并且关联的操作仅在此响应?
  • @DanieleLicini 是的,这就是我的意思。希望它对你有用:)
【解决方案2】:

我会质疑为什么你需要两条同名的路线来做两件不同的事情?

如果您的 AuthorizeUser 属性所做的只是检查用户的角色,为什么不做类似的事情:

public ActionResult New(string type)
{
    if (!string.IsNullOrWhiteSpace(type) && User.IsInRole("YOUR-ROLE-HERE"))
    {
        // Display NewCarType2 view if type requested and user is in correct role
        return View("NewCarType2");
    }

    // Default to New view if no type requested or user not in role
    return View("New");
}

这将捕获/new/new?type=foo 请求。

【讨论】:

  • 这两条路线做几乎相同的事情:例如内容的可视化是不同的。你的答案是我想做的,但唯一的区别是 AuthorizeUser 的属性不仅使用 IsInRole 检查用户的角色。我将把这个 Authorization 的逻辑放在一个方法中,并在 ActionResult 中使用它。
  • 如果他们在做几乎相同的事情,那么您可能会争辩说他们应该在同一条路线上。您是说这回答了您的问题,还是您需要更多信息?
猜你喜欢
  • 2013-05-10
  • 1970-01-01
  • 2015-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
相关资源
最近更新 更多