In the web API, how do you overload Get when one method contains null value types as parameters

UPDATE

My initial assumption was that the cause was a problem with additional parameters. This seems wrong. Instead, the problem appears to be related to several action methods when one of these methods contains valid value types (for example, int?) For some parameters.

I am using Visual Studio 2012 RC and getting started with the Web API. I encountered a problem and get the error message "There are no actions on the Bars controller that match the request."

I have a Bars controller. It has a Get () method that accepts optional parameters.

public IEnumerable<string> Get(string h, string w = "defaultWorld", int? z=null) { if (z != 0) return new string[] { h, w, "this is z: " + z.ToString() }; else return new string[] { h, w }; } 

So, I am checking it with the following urls

  • / api / bars? H = hi
  • / Api / bars h = hello &? W = world
  • / Api / h bar = hello &? W = peace & r = 15

And it works for all three.

Then I go to add another Get () method, this time with one id parameter

  public string Get(int id) { return "value"; } 

I am checking the URL again. Is it time / api / bars? H = hello & w = world and api / bars? H = hello fail. Error message "No actions were found on the control panel of the controller that match the request.

For some reason, these two methods do not mix well with each other. If I remove Get(int id) , it will work. Should I change int? z to string z, then it works (but then it requires transforming objects inside my action method!).

Why does the web API do this? Is this a bug or design?

Many thanks.

+6
source share
3 answers

The problem is resolved, although it leaves an additional question. The problem is that overloaded Action methods have problems with optional parameters.

So, a new question: why so, but I will leave it to a lower level than me;)

But this is good news. I didn’t like the problem you reported, and the transition to a complex route type, although pleasant to understand, is just a fix for flash drives and will very poorly reflect how something works in Web Api. Therefore, the good news is that if you have this problem, it is solved by simply eliminating the optional parameters, follow a good overload route. The good news is that this does not mean at all that you can install a small optional convenience:

 public class BarsController : ApiController { public string Get(int id) { return "value"; } public IEnumerable<string> Get(string h) { return Get(h, null, null); } public IEnumerable<string> Get(string h, string w) { return Get(h, w, null); } public IEnumerable<string> Get(string h, string w, int? z) { if (z != 0) return new string[] { h, w, "this is z: " + z.ToString() }; else return new string[] { h, w }; } } 

Greetings

+1
source

I have not yet found a true answer to this problem (why the web API does it), but I have a workaround that allows you to overload Get (). The trick is to wrap parameter values ​​in an object.

 public class Foo { public string H { get; set; } public string W { get; set; } public int? Z { get; set; } } 

And for the Bars controller change to

 public IEnumerable<string> Get([FromUri] Foo foo) { if (foo.Z.HasValue) return new string[] { foo.H, foo.W, "this is z: " + foo.Z.ToString() }; else return new string[] { foo.H, foo.W, "z does not have a value" }; } 

[FromUri] necessary because the WebAPI does not use URI parameters by default to form “complex” objects. The general consensus is that complex objects come from <form> actions, not GET requests.

I am still continuing to check why the Web API behaves this way and if it is actually a bug or an alleged behavior.

+3
source

You can overload the methods of the WEB API controller by adding an action parameter to the route.

  routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new {action = "Get", id = RouteParameter.Optional } ); 

Once you make this change in your route, you can call your methods, for example

 /api/bars/get?id=1 /api/bars/get?h=hello&w=world&z=15 

I hope for this help.

Lobster

+2
source

Source: https://habr.com/ru/post/920133/


All Articles