带可选参数的MVC操作 - 哪个更好?

时间:2012-03-28 11:05:37

标签: c# .net asp.net-mvc asp.net-mvc-3 c#-4.0

在您的行动签名中使用以下两种备选方案是否有任何利弊:

public ActionResult Action(int? x) // get MVC to bind null when no parameter is provided
{
    if(x.HasValue)
    {
        // do something
    }
}

OR

public ActionResult Action(int? x = null) // C# optional parameter (virtual overload)
{
    if(x.HasValue)
    {
        // do something
    }
}

3 个答案:

答案 0 :(得分:29)

我在实践中从未见过第二个动作签名,也看不出它的任何用处。

第一个通常涵盖所有场景:

  • 如果没有发送参数(GET /somecontroller/action),则x参数的值在操作中将为null
  • 如果发送了x参数,但它不是有效的整数(GET /somecontroller/action?x=abc),则x参数的值在操作中将为null,并且模型状态将无效
  • 如果发送了x参数且值表示有效整数(GET /somecontroller/action?x=123),则会为其分配x。

在我的示例中,我使用了带有查询字符串参数的GET请求,但显然同样适用于其他HTTP谓词,如果x是路由参数。

答案 1 :(得分:7)

如果它是除null以外的任何其他值,您只需指定可选参数值。

如果在重载或调用Action中没有指定任何内容,MVC3将自动将null设置为参数的值。

但是,值得注意的是,如果签名中的此参数后面有任何非可选参数,则必须在调用中指定null

因此最好将所有可选参数放在签名的末尾。

答案 2 :(得分:6)

最好的Asp.net MVC解决方案 - 使用操作方法选择器

为什么不通过删除不必要的代码分支来简化控制器操作方法,并且具有如下所示的这种代码:

public ActionResult Index()
{
    // do something when there's no id
}

[RequiresRouteValues("id")]
public ActionResult Index(int id)
{
    // do something when id is present
}

这当然是可行的,只要您为RequiresRouteValuesAttribute操作方法选择器提供非常简单的代码即可。您可以在this blog post中找到完全相同的代码。

我认为这是解决这个问题的最佳方法,因为:

  1. 通过删除不必要的分支来简化代码
  2. 使代码更易于维护(由于复杂性较低)
  3. 尽可能地扩展Asp.net MVC框架
  4. 保留参数类型,而不需要使它们成为可空的
  5. 反正。关于这项技术的所有细节都在链接的帖子中详细解释。