0

I have the following controller (.NET Core Web API application) (Source contains multiple Site's)

SitesController.cs

// GET: api/sites
[HttpGet]
public IDictionary<int, Site> GetSites() {
    return _db.Sites.ToDictionary(s => s.SiteId, s => s);
}

// GET: api/sites?source=5
[HttpGet("{source}")]
public IDictionary<int, Site> GetSites([FromRoute] int source) {
    return _db.Sites.Where(s => s.SourceId == source).ToDictionary(s => s.SiteId, s => s);
}

// GET: api/sites/5
[HttpGet("{id}")]
public async Task<IActionResult> GetSite([FromRoute] int id) {

When the Angular client asks Sites only from a Source, I however get all the sites, the function with the int source param is not called... Why?

findAllSourceSites(sourceId: number): Observable<Site[]> {
    return this.http.get(`${this.API_URL}/api/sites`, {
        params: new HttpParams()
            .set('source', sourceId.toString())
    }).pipe(
        map(res => {
            return Object.values(res);
        })
    );
}

enter image description here

2
  • is the sourceId empty? please share the url sufix (api/...) which you are calling the api with Commented Nov 9, 2018 at 17:46
  • @MarcusHöglund, please see the penleychan's answer comments Commented Nov 9, 2018 at 18:07

1 Answer 1

4

Pretty sure it's because of [FromRoute] for that to work your URL should be /api/sites/1, HttpParams is setting the query string which now your URL looks like /api/sites?source=1

If you want to use query string you should change your controller to [FromQuery]

EDIT: Due to AmbiguousActionException: Multiple actions matched. alternative solution would combine both together.

[HttpGet] 
public IDictionary<int, Site> GetSites([FromQuery] int? source) {
    if (source.HasValue) {
        // get specific 
    } else {
        // get all
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

@Serge Ah forgot to mention it should be just [HttpGet] now, without {source}
now any breakpoint is hit... AmbiguousActionException: Multiple actions matched. The following actions matched route data and had all constraints satisfied: LoggerApi.Controllers.SitesController.GetSites (LoggerApi) LoggerApi.Controllers.SitesController.GetSites (LoggerApi)
It shouldn't though, if it detects that it have a query string, it will use GetSites(int source) otherwise GetSites()
Interesting, pretty sure this never was an issue with WebAPI2. Alternative solution you can do [HttpGet] public IDictionary<int, Site> GetSites([FromQuery] int? source) and for your logic you would check if source contains value do something else get all.
yes... the last comment was really helpful, and it worked. However I don't really understand why two separate methods does not have the same effect...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.