绑定/动作/ 1,2,3到List <int> </int>

时间:2011-03-08 03:55:30

标签: asp.net-mvc-2 reflection rest routes

在我的API中,我希望有GET /api/v1/widgets/1,2,3GET /api/v1/widgets/best-widget,major-widget,bob-the-widget等路线

public class WidgetsController : MyApiController
{
    public ActionResult Show(IEnumerable<int> ids)
    {

    }

    public ActionResult Show(IEnumerable<string> names)
    {

    }
}

我已设置路线让我接受操作,但我无法弄清楚如何将1,2,3变为new List<int>(){1, 2, 3}等等。当然,我可以采取string并在我的行动中解析它,但我想避免走那条路。

我想到的一件事是在OnActionExecuting方法中添加一些东西,但后来我不确定该放在那里的东西(我可以在一起破解某些东西,显然,但我正试图写一些可重复使用的东西。)

我遇到的主要问题是如何知道我是否需要做任何事情(有时上游的ValueProviders会解决所有事情),以及如何处理确定要投射的类型(例如,我怎么知道在这种情况下,我需要去一个整数的集合,或一组字符串,然后我该怎么做?)

顺便说一句,我也有实现ValueProvider的想法,但在类似的问题上迷失了方向。

3 个答案:

答案 0 :(得分:2)

  

我无法弄清楚如何将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;
    }
}

然后在Application_Start中注册模型绑定器:

ModelBinders.Binders.Add(typeof(IEnumerable<int>), new IdsModelBinder());

最后你的控制器动作可能看起来像这样(从我在你的问题中可以看到它看起来像这样: - )):

public ActionResult Show(IEnumerable<int> ids)
{
    ...
}

并且自定义模型绑定器会将ids路由令牌解析为相应的IEnumerable<int>值。

您可以使用IEnumerable<string>执行相同操作,只需删除相应模型装订器中的.Select子句即可。

答案 1 :(得分:1)

如果您的网址是

/api/v1/widgets/Show?names=best-widget&names=major-widget&names=bob-the-widget

这将整齐地绑定:)

在这种情况下无需覆盖模型绑定器。 查询字符串变量names将绑定到您的Show-method _

public ActionResult Show(IEnumerable<string> names)

希望这有帮助!

答案 2 :(得分:0)

我对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);
}

您可能还想为无法解析输入ID的情况添加一些更复杂的错误处理,但这就是我将使用的一般方法。