2

I created a Web-API and i would like to get all routes with parameters BeginAddress (string), EndAddress(string), BegineDate (Datetime). I created a new Class SearchRoute with these properties.

I can do a normal Getwith an id or a string but how to do a Get by giving an object? Is this possible?

Would it be possible to do a post/put with an object and than ask for a return?

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 Function

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

Update: If i do this, the Post doesn't work but if i create a new controller it works.

[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);
}
Craig W.
  • 16,585
  • 6
  • 44
  • 77
Sam_vdd
  • 616
  • 1
  • 6
  • 18
  • I don't think you can have two method named the same, you should adjust your route table and place the action in the URI. – Davin Tryon Jan 08 '13 at 16:15
  • Also read this article: http://weblog.west-wind.com/posts/2013/Dec/13/Accepting-Raw-Request-Body-Content-with-ASPNET-Web-API – Tohid Apr 18 '16 at 21:44

2 Answers2

3

I prefer sticking with GET even when using a complex object as a parameter. If you are concerned about the length of the URI then remember that:

  1. Prefixing the property names for simple like complex objects is not necessary because the Web API object binding can auto resolve based on property names alone.
  2. The maximum allowed URL length is 2083 characters which is more than sufficient in most cases.

If you we take your example

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 when searching on

  • BeginAddress = "Some beginning";
  • EndAddress = "Some ending"
  • BeginDate = "2016-01-01T16:40:00"

Resulting query string:

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

Again, the properties will auto resolve even without the object prefix/qualifier and populate the object instance.

  • Add a domain info to the URL maybe another 50 or so characters
  • Add a controller name maybe another 30 or so characters
  • Add the query string = 82 characters

Note that I am not taking into account resolving the special characters like spaces to Url escaped character sequence

Total ≈ 162 characters give or take

Not bad considering that the maximum allowed URL length is 2083 characters, so you have used up only 7% of what is possible in this simple example.

This would probably be the preferred way of doing it because it conforms to the RESTful API standard where GET calls/verbs do not alter data and POST calls/verbs do.

Igor
  • 55,253
  • 10
  • 80
  • 149
1

You can pass an object by using a complex type in the URI. You need to help Web API by using the correctly formatted Query String. This would be an example:

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

However, if your Query String starts to become too big, you might be modeling the interaction incorrectly.

Then, in the server you should let Web API know that it should look in the URI for the values:

public List<Route> GetAllByCity([FromUri]SearchRoute sr)
    {
        return RouteDAO.GetAllByCity(sr);
    }
Davin Tryon
  • 62,665
  • 13
  • 135
  • 126
  • i know i could do that but the problem is the lenght of the string. Isn't there any possibility to do a get with an object. In a post you can give an object so why not in a Get? – Sam_vdd Jan 08 '13 at 14:58
  • Would it be possible to give the object in the Body? en then do [FromBody]? – Sam_vdd Jan 08 '13 at 15:01
  • No, The HTTP specification for GET says "The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI." – Davin Tryon Jan 08 '13 at 15:01
  • In other words, no body in a GET. – Davin Tryon Jan 08 '13 at 15:02
  • so is it possible with a Put or Post method? and then to resend the List ? – Sam_vdd Jan 08 '13 at 15:02
  • Sure, PUT and POST can be used to move a body payload to the server. Then you can use the [FromBody]. [This is a good discussion on payloads in GET](http://stackoverflow.com/questions/978061/http-get-with-request-body). – Davin Tryon Jan 08 '13 at 15:04
  • Ok but how do i get the return list in my application? – Sam_vdd Jan 08 '13 at 15:06
  • PUT and POST also return a body. So, the POST method, for example, would return a `List`. – Davin Tryon Jan 08 '13 at 15:07
  • Is it possible to put multiple Post methods in the APIcontroller – Sam_vdd Jan 08 '13 at 15:32
  • Yes, that is possible as well. You might have to attribute the methods with a `[HttpPost]` attribute. – Davin Tryon Jan 08 '13 at 15:36