带可选参数的MVC操作 – 哪个更好?
在您的行动签名中使用以下两种备选方案是否有任何利弊:
public ActionResult Action(int? x) // get MVC to bind null when no parameter is provided { if(x.HasValue) { // do something } }
要么
public ActionResult Action(int? x = null) // C# optional parameter (virtual overload) { if(x.HasValue) { // do something } }
我在实践中从未见过第二个动作签名,也看不出它的任何用处。
第一个通常涵盖所有场景:
- 如果没有发送参数(
GET /somecontroller/action
),则x参数的值在操作中将为null - 如果发送ax参数,但它不是有效整数(
GET /somecontroller/action?x=abc
),则x参数的值在操作中将为null,并且模型状态将无效 - 如果发送ax参数并且值表示有效整数(
GET /somecontroller/action?x=123
),则将为其分配x。
在我的示例中,我使用了具有查询字符串参数的GET请求,但显然同样适用于其他HTTP谓词并且x
是路由参数。
您只需要指定可选参数值,如果它将是除null
之外的任何其他null
。
如果在重载或调用Action中没有指定任何内容,MVC3将自动将null
设置为参数的值。
但是,值得注意的是,如果签名中的此参数后面有任何非可选参数,则必须在调用中指定null
。
因此,最好将所有可选参数放在签名的末尾。
最好的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
操作方法选择器提供非常简单的代码即可。 您可以在此博客文章中找到完全相同的代码。
我认为这是解决这个问题的最佳方法,因为:
- 它通过删除不必要的分支简化了代码
- 使代码更易于维护(由于复杂性较低)
- 尽可能地扩展Asp.net MVC框架
- 保持参数类型应该是它们,而不需要使它们可以为空
- 等等
无论如何。 关于此技术的所有细节都在链接的post中详细解释。