22

I want to make a web api that is passed 4 parameters.

Here is my route:

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{email}/{firstname}/{lastname}/{source}"
        );

Here is the method signature

public string GetId(string email, string firstname, string lastname, string source)

Here is the calling url

http://fakedomain.com/api/Contacts/GetId?email=user@domain.com&firstname=joe&lastname=shmoe&source=123

I get a 404 error.

If I set each parameter to optional in the route config, and set up each argument with a default value it gets called. However, each argument gets the default value and not the passed value.

I feel like I am close, what am I missing?

Nick
  • 841
  • 2
  • 9
  • 30

3 Answers3

33

You don't need a special routing record to handle multiple parameters. The routing record you created would be looking for the following route

/api/controller/Dan@dan.com/Dan/FunnyLastName/TheCoffeeShop

but you are trying to pass in parameters, not specify a route.

with this routing record:

config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional, action = "DefaultAction" });

the following GET endpoint:

public HttpResponseMessage Get(int requestId = 0, string userName = null, string departmentName = null, bool includeCompleted = false)
    {
      //code
    }

could be hit as :

 /api/controllername/?requestId=15&username=Dan

or

/api/controllername/?departmentName=SoftwareEngineering

or any other combination of the parameters (or no parameters since they have default values)

Since you have a "Named" action (GetId) instead of the default actions (GET,POST,PUT..), this complicates things a little bit and you would have to work out a custom route to handle the action name. The following is what I use for custom action names (id is required in this example)

config.Routes.MapHttpRoute("ActionRoute", "api/{controller}/{action}/{id}");

Your endpoint would have to explicitly accept one parameter with the name 'id'

  public HttpResponseMessage LockRequest(int id, bool markCompleted)
    {
        //code
    }

This endpoint would be hit at the following route:

/api/controllerName/LockRequest/id?markCompleted=true

Following the RESTful spec, it is better to stay away from custom action names when possible. Most of the time you can get away with the normal HTTP verbs and just use named actions to manipulate existing items (hence why ID is required in my example). For your code you could just have two GET endpoints, one that takes a specific ID to get the item, one that returns all items (including ids) based on "search parameters".

public HttpResponseMessage Get(int id)
public HttpResponseMessage Get(int requestId = 0, string userName = null, string departmentName = null, bool includeCompleted = false)

These would both be handled by the default routing record.

vesuvious
  • 2,753
  • 4
  • 26
  • 39
8

Ensure you have default api route setting in WebApiConfig.cs file.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

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

        config.Routes.MapHttpRoute(
        name: "ContactApi",
        routeTemplate: "api/{controller}/{email}/{firstname}/{lastname}/{source}"
        );
    }
}

http://fakedomain.com/api/Contacts/GetId?email=user@domain.com&firstname=joe&lastname=shmoe&source=123

Note : I replaced fakedomain with localhost and it works... (localhost/api/Contacts/GetId?email=user@domain.com&firstname=joe&lastname=shmoe&source=123)

Deepu Madhusoodanan
  • 1,495
  • 1
  • 14
  • 26
  • I replaced the defaultapi with the contactapi. When I added back the defaulapi it worked. Thanks. – Nick Aug 06 '14 at 14:40
0
public class Parameters
    {
        public int Param1 { get; set; }
        public string Param2 { get; set; }
    }

and then in your controller method:

    [ActionName("DoSomething")]
    [HttpPost]
    public IHttpActionResult DoSomething(Parameters myParameters)
    {
        var x = myParameters.Param1;
        var y = myParameters.Param1;
       //do something else..

    }

And build a ajax call like this:

var request = {
                    Param1 : "1",
                    Param2 : "Mystring"
                };

    function callToMethodController(request) {
        var deferred = $q.defer();
        $http.post('api/object/DoSomething', request)
            .success(function (data) {
                deferred.resolve(data);
            }).error(function (error) {
                deferred.reject('There was an error.');
            });
        return deferred.promise;
    }
Si8
  • 9,141
  • 22
  • 109
  • 221
David Castro
  • 1,773
  • 21
  • 21