我一直在遇到我希望为动作方法提供稍微更直观或“格式良好”的参数名称的场景,但是对于默认行为,这变得非常痛苦。例如,假设我有一个像GetWidget(int id)这样的动作参数。如果我想要它是GetWidget(int widgetId),我必须添加一个新的路由。当你使用像jqGrid这样的库时它会变得更糟,它的查询字符串参数使用了很糟糕的名字:GetWidgets(int?nodeid,int?n_level)。相反,我想要GetWidgets(int?parentId,int?level)或类似的东西。
那么,我有什么简单的东西可以忽略吗?告诉MVC我的“parentId”参数应该绑定到请求中“nodeid”的值似乎应该是一件非常简单的事情。我想过编写一个自定义动作过滤器来做到这一点,但它似乎很明显,我不相信它不是开箱即用的。
答案 0 :(得分:4)
根据Rony的回答,使用自定义模型绑定器。这是一个例子:
public class BindToAliasAttribute : CustomModelBinderAttribute
{
private readonly string parameterAlias;
public BindToAliasAttribute(string parameterAlias)
{
this.parameterAlias = parameterAlias;
}
public override IModelBinder GetBinder()
{
return new ParameterWithAliasModelBinder(parameterAlias);
}
}
public class ParameterWithAliasModelBinder : IModelBinder
{
private readonly string parameterAlias;
public ParameterWithAliasModelBinder(string parameterAlias)
{
this.parameterAlias = parameterAlias;
}
object IModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return controllerContext.RouteData.Values[parameterAlias];
}
}
public class UserController : Controller
{
[HttpGet]
public ActionResult Show( [BindToAlias("id")] string username)
{
...
}
}
答案 1 :(得分:3)
如果在URL上使用命名参数,则可以在控制器方法中为参数指定特定名称,如下所示:
http://mydomain.com/mycontroller/getwidget?parentid=1&level=2
...您不必在参数上匹配路线。
答案 2 :(得分:1)
使用您自己的自定义模型绑定器来实现IModelBinder