使用带有web api操作的viewmodel

时间:2013-06-01 15:14:49

标签: asp.net asp.net-mvc asp.net-web-api asp.net-web-api-routing

我刚刚阅读了Dave Ward(http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/)的这篇文章,我试图将一个简单的web api控制器放在一起,它将接受一个视图模型,而且我没有点击我

我希望我的viewmodel是一个具有几个DateTime属性的对象:

public class DateRange
    {
        public DateTime Start { get; set; }
        public DateTime End { get; set; }
    }

在不改变股票web api项目中的任何内容的情况下,我将我的值控制器编辑为:

public IEnumerable<float> Get()
    {
        DateRange range = new DateRange()
        {
            Start = DateTime.Now.AddDays(-1),
            End = DateTime.Now
        };

        return Repo.Get(range);
    }

    // GET api/values/5
    public IEnumerable<float> Get(DateRange id)
    {
        return Repo.Get(range);
    }

但是,当我尝试使用此控制器时,出现此错误:

Multiple actions were found that match the request: System.Collections.Generic.IEnumerable 1 [System.Single]类型FEPIWebService.Controllers.ValuesController上的Get() System.Collections.Generic.IEnumerable 1[System.Single] Get(FEPIWebService.Models.DateRange) on type FEPIWebService.Controllers.ValuesController

点击

时出现此消息
/api/values

/api/values?start=01/01/2013&end=02/02/2013

如何解决第一次和第二次获取操作之间的歧义?

如果我有进一步的功劳,

public void Post(DateRange value)
{
}

如何使用jQuery将Start和End属性发布到该对象,以便modelbinding构建DateRange参数?

谢谢!

克里斯

1 个答案:

答案 0 :(得分:2)

答案在此详细描述:Routing and Action Selection。提取

在此背景下,这是动作选择算法。

  
      
  1. 创建控制器上与HTTP请求方法匹配的所有操作的列表。
  2.   
  3. 如果路线词典有“操作”条目,请删除名称与此值不匹配的操作。
  4.   
  5. 尝试将操作参数与URI匹配,如下所示:   
        
    • 对于每个操作,获取一个简单类型的参数列表,其中绑定从URI获取参数。排除   可选参数。
    •   
    • 从此列表中,尝试在路径字典或URI查询字符串中查找每个参数名称的匹配项。比赛是   不区分大小写,不依赖于参数顺序。
    •   
    • 选择一个操作,其中列表中的每个参数都与URI匹配。
    •   
    • 如果多一个操作符合这些条件,请选择参数匹配最多的一个。
    •   
  6.         

    4.Ignore具有[NonAction]属性的动作。

换句话说,您使用的 ID 参数不是 SimpleType ,因此无法确定要使用哪种Get方法。 通常Id是整数或guid ...,然后两种方法可以并排生存

如果它们都返回IList<float>,解决办法可能是省略其中一个:

public IEnumerable<float> Get([FromUri]DateRange id)
{
    range = range ?? new DateRange()
    {
       Start = DateTime.Now.AddDays(-1),
       End = DateTime.Now
    };
    return Repo.Get(range);
}

现在两者都会起作用

/api/values

/api/values?Start=2011-01-01&End=2014-01-01