12

I am new to WebApi and right now i have two httpPost method like this

[HttpPost]
public List<YellowPages.Person> AddPersonDetails(YellowPages.Person person)
{
  Repository.Repository.personsList.Add(person);
  return Repository.Repository.personsList;
}

and the second method is

[HttpPost]
public List<YellowPages.City> getRelevantCity(string stateID)
{
   return new Repository.YellowPages.City().getCity()
   .Where(x => x.StateID ==stateID).ToList();
}

whenever i make a call to the getRelevantCity method, AddPersonDetails method gets called, i believe this is something to do with the REST architecture. now my question is how can i handle this situation.Is there anything i can do in the WebApiConfig.cs file and add constraints? if yes, how to handle constraints for the model type which i am using. Thank you.

UPDATE 1

as suggested i have changed my both the method removing the attributes as follows

public List<YellowPages.Person> AddPersonDetails(YellowPages.Person person)
{
   Repository.Repository.personsList.Add(person);
   return Repository.Repository.personsList;
} 

public List<YellowPages.City> getRelevantCity(string stateID)
{
            return new Repository.YellowPages.City().getCity().Where(x => x.StateID == stateID).ToList();
}

my ajax call is like this

 $('#StateID').change(function () {
        $.ajax({
            type: 'POST',
            url: '/api/shoppingCart/getRelevantCity',
            ContentType: 'application/json',
            data: { 'stateID': $('#StateID').val() },
            dataType: 'json',
            success: function (returnData) {
                var grid = '';
                $.each(returnData, function (i, d) {
                    grid = grid + createDom(d);
                });
                $('#result').empty().append(
                    grid
                    );
            },
            error: function (xhr, ajaxOptions, thrownError) {
                alert('error');
            }
        });
    }); 

$('#btnAjax').click(function (e) {
        debugger;
        e.preventDefault();
        var d = { 'PersonName': $('#PersonName').val(), 'gender': $('#gender').prop('checked', true).val(), 'StreetAddress': $('#StreetAddress').val(), 'StateID': $("#StateID option:selected").text(), 'Pincode': $('#Pincode').val() };
        $.ajax({
            type: 'POST',
            url: '/api/shoppingCart/AddPersonDetails',
            ContentType: 'application/json',
            data: d,
            dataType: 'json',
            success: function (returnData) {
                var grid = '';
                $.each(returnData, function (i, d) {
                    grid = grid + createDom(d);
                });
                $('#result').empty().append(
                    grid
                    );
            },
            error: function (xhr, ajaxOptions, thrownError) {
                alert('error');
            }
        });

    });

no matter which ajax call i make, the first method gets called, can you help me how to hendle it?

UPDATE 2

my question is simple

Suppose if i have 4 GET methods in my webApi, then how can I handle the webApi so that i could get all the 4 GET methods implemented

Lijin Durairaj
  • 4,910
  • 15
  • 52
  • 85
  • Possible duplicate of [Multiple HttpPost method in Web API controller](http://stackoverflow.com/questions/11407267/multiple-httppost-method-in-web-api-controller) – CodeCaster Aug 28 '16 at 16:17
  • 1
    @CodeCaster my question is how can i add constraints for my model and string in the MapHttpRoute method. adding constraints for int and string can be done but how to add constraints for models, please help me understand. – Lijin Durairaj Aug 28 '16 at 16:20
  • I'm not sure what you mean by that. Do you mean you want the routing to happen based on which property names are POSTed? Then you need attribute routing, just as explained in the duplicate. – CodeCaster Aug 28 '16 at 16:21
  • @CodeCaster i have two post methods, now one is accepting string as an argument and the other is accepting my Model as an argument, how can i handle this scenario, Thank you – Lijin Durairaj Aug 28 '16 at 16:23
  • 3
    You [cannot trivially do that](http://stackoverflow.com/questions/16524737/route-to-different-actions-based-on-json-value), simply use attribute routing (`/YourController/AddPerson` and `/YourController/GetCity`). The latter should be GET anyway. – CodeCaster Aug 28 '16 at 16:29
  • @CodeCaster let me update my question for you – Lijin Durairaj Aug 28 '16 at 16:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/122044/discussion-between-lijin-john-and-codecaster). – Lijin Durairaj Aug 28 '16 at 16:40
  • Did you ever had a chance to try out the answer I have mentioned below? Thats gonna solve your problem; you can implement multiple GET (or any) calls easily via attribute routing. – Developer Oct 20 '16 at 00:21
  • Api automatically calls method starting with get for GET operations.Thats why getRelevantcity does not get called for POST operation.You can use attribute routing as explained by @Developer – DAre G Oct 25 '16 at 07:34

2 Answers2

16

Go for attribute routing. In your api config, add

config.MapHttpAttributeRoutes();

And on top of your controller:

[RoutePrefix("api")]
public class ShoppingCartController....

And for actions:

[HttpPost]
[Route("getRelevantCity")]
public List<YellowPages.Person> GetRelevantCity

[HttpPost]
[Route("addPersonDetails")]
public List<YellowPages.Person> AddPersonDetails

Thus said, your GetRelevantCity ideally should be a GET method and not a POST. I would suggest you to change that to HttpGet in action as well as in your javascript code:

[HttpGet] //this is not required; as per naming convention this will be a GET request by default
[Route("getRelevantCity/{stateId}")]
public List<YellowPages.Person> GetRelevantCity(int stateId)

And in $.ajax, change type: 'GET' and pass stateId in params or as query string or api/getRelevantCity/123 where 123 is the state id

Developer
  • 6,240
  • 3
  • 18
  • 24
0

Is it your case? I fully agree with answer about GET and POST methods, but you can use an OdataController. It will look as common rest call, but it can call methods (which you define) like api/Object(123)/GetRelevantCity or api/Object(123)/getRelevantCity (but instead of api/Object/123 )

Also you are able to create a custom constraint based on body of request (an example of the constraint): Sorry for this way of reading the post data...

public class TypeConstraint: IHttpRouteConstraint
{

    public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values,
        HttpRouteDirection routeDirection)
    {
        return IsItCorrect(request.Content.ReadAsStringAsync().Result);
    }
}

this way of reading the requestMessage and there is full example of multiple pust (this code can be not so clean and should be refactored, but I hope the idea is pretty clear)

Community
  • 1
  • 1
VVildVVolf
  • 136
  • 2
  • 12