4

I am trying to add a Get() function in a MVC 6 (Asp .Net 5) Web Api to pass a configuration option as a query string. Here are the two functions that I already have:

[HttpGet]
public IEnumerable<Project> GetAll()
{
    //This is called by http://localhost:53700/api/Project
}

[HttpGet("{id}")]
public Project Get(int id)
{
    //This is called by http://localhost:53700/api/Project/4
}

[HttpGet()]
public dynamic Get([FromQuery] string withUser)
{
    //This doesn't work with http://localhost:53700/api/Project?withUser=true
    //Call routes to first function 'public IEnumerable<Project> GetAll()
}

I've tried several different ways to configure the routing, but MVC 6 is light on documentation. What I really need is a way to pass some configuration options to the list of Projects for sorting, custom filtering etc.

4
  • 2
    did you try [FromUri] attribute instead of [FromQuery]? in your last method. Commented Sep 23, 2015 at 13:53
  • 1
    [FromUri] is not an option. The only options are From+ [Body,Form,Header,Query,Route,Services]. Commented Sep 23, 2015 at 15:21
  • bootRom and @Prashant are correct - This changed from MVC5 to MVC6. That was my problem. Commented Jul 19, 2016 at 23:36
  • My first question is why are you passing a bool as a string? Second is, you have two of the same items methods, and its totally fine for you to change "GetAll" to just be a "Get." Commented Apr 4, 2017 at 17:03

2 Answers 2

4

You can't have two [HttpGet]s with the same template in a single controller. I'm using asp.net5-beta7 and in my case it even throws the following exception:

Microsoft.AspNet.Mvc.AmbiguousActionException Multiple actions matched. The following actions matched route data and had all constraints satisfied:

The reason for this is that [From*] attributes are meant for binding, not routing.

The following code should work for you:

    [HttpGet]
    public dynamic Get([FromQuery] string withUser)
    {
        if (string.IsNullOrEmpty(withUser))
        {
            return new string[] { "project1", "project2" };
        }
        else
        {
            return "hello " + withUser;
        }
    }

Also consider using Microsoft.AspNet.Routing.IRouteBuilder.MapRoute() instead of attribute routing. It may give you more freedom defining the routes.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, that works. I also came across the answer by trial and error, but I didn't understand why it worked. I agree using IRouteBuilder.MapRoute() is a cleaner solution.
0

Accessing the query string is very doable by using either the RESTful routing conventions (enforced by ASP.NET 5 / MVC 6 by default) or by defining custom routes, as explained in this answer.

Here's quick example using custom, attribute-based routes:

[HttpGet("GetLatestItems/{num}")]
public IEnumerable<string> GetLatestItems(int num)
{
    return new string[] { "test", "test2" };
}

For more info about custom routing, read the following article on my blog.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.