Asp.net mvc 2 绑定/操作/1,2,3到列表<;int>;
在我的API中,我希望有像Asp.net mvc 2 绑定/操作/1,2,3到列表<;int>;,asp.net-mvc-2,reflection,rest,routes,Asp.net Mvc 2,Reflection,Rest,Routes,在我的API中,我希望有像GET/API/v1/widgets/1,2,3和GET/API/v1/widgets/best widget、mair widget、bob the widget这样的路由 public class WidgetsController : MyApiController { public ActionResult Show(IEnumerable<int> ids) { } public ActionResult Sho
GET/API/v1/widgets/1,2,3
和GET/API/v1/widgets/best widget、mair widget、bob the widget这样的路由
public class WidgetsController : MyApiController
{
public ActionResult Show(IEnumerable<int> ids)
{
}
public ActionResult Show(IEnumerable<string> names)
{
}
}
公共类WidgetsController:MyApicController
{
公共操作结果显示(IEnumerable ID)
{
}
公共操作结果显示(IEnumerable名称)
{
}
}
我已经设置了到达动作的路线,但我不知道如何将1,2,3
转换为newlist(){1,2,3}
等等。当然,我可以只使用字符串
并在操作中对其进行解析,但我希望避免使用这种方法
我想到的一件事是在OnActionExecuting
方法中放一些东西,但我不确定到底放什么(显然,我可以把一些东西拼凑在一起,但我正在尝试编写一些可重用的东西。)
我面临的主要问题是如何知道我是否需要做任何事情(有时上游的ValueProviders会解决所有问题),以及如何处理确定要转换到的类型(例如,在这种情况下,我如何知道我需要转到int集合或字符串集合,然后如何做?)
顺便说一句,我也有实现ValueProvider
的想法,但在类似的问题上迷失了方向。我对ASP.Net MVC比较陌生,因此我不确定是否有更简单的方法来实现这一点,但是我的方法是执行以下操作:
public class WidgetsController : MyApiController
{
public ActionResult Show(string ids)
{
List<int> parsedIds = new List<int>();
foreach (var id in ids.Split(','))
{
parsedIds.Add(int.Parse(id));
}
return Show(parsedIds);
}
private ActionResult Show(List<int> ids);
}
公共类WidgetsController:MyApicController
{
公共操作结果显示(字符串ID)
{
List parsedIds=新列表();
foreach(id.Split(',')中的变量id)
{
Add(int.Parse(id));
}
返回显示(parsedIds);
}
私有操作结果显示(列表ID);
}
对于无法解析输入的ID的情况,您可能还希望添加一些更复杂的错误处理,但这是我将使用的一般方法
我不知道如何将1,2,3转换为新的List(){1,2,3}等等
为了避免污染需要接收此参数的每个控制器操作,我建议使用自定义模型绑定器:
public class IdsModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var result = base.BindModel(controllerContext, bindingContext);
var ids = bindingContext.ValueProvider.GetValue("ids");
if (ids != null)
{
return ids.AttemptedValue
.Split(',')
.Select(id => int.Parse(id))
.ToList();
}
return result;
}
}
然后在应用程序\u Start
中注册模型活页夹:
ModelBinders.Binders.Add(typeof(IEnumerable<int>), new IdsModelBinder());
ModelBinders.Binders.Add(typeof(IEnumerable),new-IdsModelBinder());
最后,你的控制器动作可能是这样的(从你的问题中我可以看到它已经是这样了:-):
公共操作结果显示(IEnumerable ID)
{
...
}
自定义模型绑定器将负责将ids
路由令牌解析为相应的IEnumerable
值
您可以对IEnumerable
执行相同的操作,只需删除。在相应的模型绑定器中选择子句。如果您的URL是
/api/v1/widgets/Show?names=best-widget&names=major-widget&names=bob-the-widget
这样就可以很好地捆绑在一起:)
在这种情况下,不需要重写ModelBinder。
querystring变量names
将绑定到Show方法_
public ActionResult Show(IEnumerable名称)
希望这有帮助 太好了,谢谢,这就是我要找的。这对我想做的其他事情也会有帮助,比如支持矩阵参数。刚刚尝试了一下,它似乎工作得很顺利。我对代码的一个修改是将.GetValue
调用更改为使用bindingContext.ModelName
而不是硬编码名称。我建议对您的答案进行编辑。谢谢,但我试图避免使用查询变量。
/api/v1/widgets/Show?names=best-widget&names=major-widget&names=bob-the-widget