3

I would like to be able to call GET and POST request from the same url (api/test...), but I am currently getting current context error on the following line of code:

[AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]
//The name 'HttpVerbs' does not exist in the current context -- error. 

I have added in the MVC namespace, but since my application is web api, its causing the authorize property to fall through when declaring the mvc namespace.

    [Authorize]
    [AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)] // error
    public HttpResponseMessage post([FromUri] Query query)
    {
        if (User.IsInRole("admin"))
        {

            IQueryable<data_qy> Data = null;

            if (!string.IsNullOrEmpty(query.name))
            {
                var ids = query.name.Split(',');

                var dataMatchingTags = db.data_qy.Where(c => ids.Any(id => c.Name.Contains(id)));

                if (Data == null)
                    Data = dataMatchingTags;
                else
                    Data = Data.Union(dataMatchingTags);
            }

            if (Data == null) 
                Data = db.data_qy;

            if (query.endDate != null)
            {
                Data = Data.Where(c => c.UploadDate <= query.endDate);
            }

            if (query.data_qy != null)
            {
                Data = Data.Where(c => c.UploadDate >= query.data_qy);
            }

            Data = Data.OrderByDescending(c => c.UploadDate);

            var data = Data.ToList();

            if (!data.Any())
            {
                var message = string.Format("No data found");
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
            }

            return Request.CreateResponse(HttpStatusCode.OK, data);
        }

        return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Access Denied, Please try again.");
    }

}

Any advice would be very much appreciated. Many thanks.

user3070072
  • 610
  • 14
  • 37

3 Answers3

8

Instead of writing:

    [AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]

have you tried:

    [AcceptVerbs("GET","POST")]

or, even better:

    [HttpGet]
    [HttpPost]

?

The HttpVerbs class (in namespace System.Web.Mvc) is specific to MVC projects, not Web API.

djikay
  • 10,450
  • 8
  • 41
  • 52
  • I have tried this approach before, the `POST` request does not allow me filter my results, instead throws the entire dataset. However, `POST` request only works with `[FromBody]` method, but then `GET`, throws a object null error. Please advice. Many thanks – user3070072 Jun 17 '14 at 10:08
  • That's probably a different question, but I think the behaviour you're seeing is influenced by how you structure your URI to pass the `query` parameter. Also, make sure there are no other methods called `Get` in your controller, because they will take precedence over methods with the `[HttpGet]` attribute (or equivalent `AcceptVerbs` attribute). I've managed to get this to work for me with a dummy `Query` object that has 2 string members `a` and `b` in it. Then I structure the URI as follows: `.../api/values/post?a=6&b=8` and the parameters were passed into the method as expected. – djikay Jun 17 '14 at 10:55
  • hi, Many thanks for your explanation and help, I would like to ask a small question, in regards to testing GET request, why am I getting a an object reference error `[Object reference not set to an instance of an object.]`, on the line of code `[query.name]`, when I call the get method using the `[fromBody]` method, otherwise it works fine using `[fromUri]`. Please advice, if possible. Thank you very much for your time and help. – user3070072 Jun 23 '14 at 14:47
  • If I understand correctly what you're saying, the reason it's not set is because a `GET` request doesn't have a body (you can't pass data to a `GET` request in the request body like you can for a `POST` request). So it won't work using `[FromBody]` but it should work using `[FromUri]` because the data you're passing is part of the URI. – djikay Jun 23 '14 at 15:24
  • By the way, what you're asking goes beyond the scope of the original problem. It might be a good idea to ask a separate question. Having said that, you're probably trying to do too much with one action. It might be a better idea to have two separate actions (Get and Post) that both link to the same private method. This way, you can choose to get the input parameters for GET from the URI and for POST from the body, and then pass those parameters to your private "worker" method that will do the job. This will be a neater approach and, in my humble opinion, more maintainable in the long run. – djikay Jun 23 '14 at 18:48
  • Hi, Thank you so much for your suggestion and possible solution. I really appreciate your comments and time into this. This has been great help(i.e. I nearly have the private method working), in moving forward from this continuous problem. Thank you for all your help. – user3070072 Jun 24 '14 at 08:24
0

I dont think that you can do that in a web api controller since it's meant to be a REST controller with specific methods with specific accept verbs.

But maybe you can make private methods and use the routing-config to make it do what you want. Haven't tried it though

0
[AcceptVerbs("POST", "GET"), Authorize]
[AcceptVerbs("POST", "GET")]

Yes. You can use multiple verbs in single WEB API method. In my case, WPF application accepting GET method and Android application is accepting POST method, So I have use multiple verbs (HTTP Methods) and it worked.
Below is the example:

[Route("all")]
[AcceptVerbs("POST", "GET"), Authorize]
public IHttpActionResult All(yourParameterListHere)
{
   //Your body;
}
Sender
  • 6,660
  • 12
  • 47
  • 66