【问题标题】:Web-API Get with objectWeb-API 获取对象
【发布时间】:2016-02-02 03:18:09
【问题描述】:

我创建了一个 Web-API,我想获取所有带有参数 BeginAddress (string)、EndAddress(string)、BegineDate (Datetime) 的路由。我用这些属性创建了一个新的类 SearchRoute。

我可以用一个 id 或一个字符串来做一个普通的 Get,但是如何通过给一个对象来做一个 Get?这可能吗?

是否可以对一个对象进行发布/放置而不是要求退货?

using (HttpClient client = new HttpClient())
{
    HttpResponseMessage response = await client.GetAsync(url + userid);
    if (response.IsSuccessStatusCode)
    {
        string content = await response.Content.ReadAsStringAsync();
        List<Route> list = await SerializeService.Deserialize<List<Route>>(content);
        return list;
    }
    return null;
}

Web API 函数

public List<Route> GetAllByCity(SearchRoute sr)
{
    return RouteDAO.GetAllByCity(sr);
}

更新: 如果我这样做,则 Post 不起作用,但如果我创建一个新控制器,它就会起作用。

[HttpPost]
// POST api/route
public void Post([FromBody]Route route)
{
    RouteDAO.Create(route);
}

// POST api/route
[HttpPost]
public List<Route> Post([FromBody]SearchRoute sr)
{
    return RouteDAO.GetAllByCity(sr);
}

【问题讨论】:

标签: c# asp.net-web-api


【解决方案1】:

即使使用复杂对象作为参数,我也更喜欢坚持使用 GET。如果您担心 URI 的长度,请记住:

  1. 没有必要为简单的复杂对象的属性名称添加前缀,因为 Web API 对象绑定可以仅根据属性名称自动解析。
  2. maximum allowed URL length 是 2083 个字符,这在大多数情况下已经足够了。

如果我们以你为榜样

public class SearchRoute {
   public string BeginAddress {get;set;}
   public string EndAddress {get;set;}
   public DateTime BeginDate {get;set;}
}

[HttpGet]
public List<Route> Get([FromUri]SearchRoute sr)
{
    return RouteDAO.GetAllByCity(sr);
}

搜索时的 Uri

  • BeginAddress = "某个开始";
  • EndAddress = "某个结局"
  • BeginDate = "2016-01-01T16:40:00"

结果查询字符串:

?BeginAddress=Some beginning&amp;EndAddress=Some ending&amp;BeginDate=2016-01-01T16:40:00

同样,即使没有对象前缀/限定符,属性也会自动解析并填充对象实例。

  • 将域信息添加到 URL 中可能还有 50 个左右的字符
  • 添加一个控制器名称可能另外 30 个左右的字符
  • 添加查询字符串 = 82 个字符

请注意,我没有考虑将空格等特殊字符解析为 Url 转义字符序列

总共 ≈ 162 个字符 给予或接受

考虑到允许的最大 URL 长度为 2083 个字符,这还不错,因此在这个简单示例中,您只用了 7%

这可能是首选方式,因为它符合RESTful API standard,其中 GET 调用/动词不会改变数据,而 POST 调用/动词会这样做。

【讨论】:

    【解决方案2】:

    您可以通过在 URI 中使用复杂类型来传递对象。您需要使用格式正确的查询字符串来帮助 Web API。这就是一个例子:

    ?SearchRoute.BeginAddress=TheAddressValue&SearchRoute.EndAddress=TheAddressValue
    

    但是,如果您的查询字符串开始变得太大,您可能会错误地对交互进行建模。

    然后,在服务器中,您应该让 Web API 知道它应该在 URI 中查找值:

    public List<Route> GetAllByCity([FromUri]SearchRoute sr)
        {
            return RouteDAO.GetAllByCity(sr);
        }
    

    【讨论】:

    • 我知道我可以做到,但问题是字符串的长度。没有任何可能对对象进行获取。在帖子中你可以给一个对象,那为什么不在 Get 中呢?
    • 是否可以在 Body 中给出对象?然后做 [FromBody]?
    • 不,GET 的 HTTP 规范说“GET 方法意味着检索由 Request-URI 标识的任何信息(以实体的形式)。”
    • 换句话说,GET 中没有正文。
    • 那么可以使用 Put 或 Post 方法吗?然后重新发送列表?
    猜你喜欢
    • 2018-12-05
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 2021-03-23
    • 2015-07-12
    相关资源
    最近更新 更多