简体   繁体   中英

How can I properly overload a WebAPI 2 Controller with multiple collection parameters?

I'm trying to design my WebAPI controller with overloaded Get methods that will be selected based on the parameters a user provides. I'm able to get this to work properly in some cases, but when I have multiple collection parameters on a method my controller is no longer able to select the correct route, even if I am not specifying both collections.

For example the following set up works:

[RoutePrefix("data/stock")]
public class StockDataController 
    : ApiController {

    private readonly IDataProvider<StockDataItem> _dataProvider;

    public StockDataController() {
        _dataProvider = new StockDataProvider();
    }

    [Route("")]
    public IEnumerable<StockDataItem> Get([FromUri] string[] symbols) {
        // Return current stock data for the provided symbols
    }

    [Route("")]
    public IEnumerable<StockDataItem> Get([FromUri] string[] symbols, DateTime time) {
        // Return stock data at a specific time for the provided symbols
    }

}

Selects Method 1

GET http://server/data/stock/?symbols[]=GOOG&symbols[]=MSFT

Selects Method 2

GET http://server/data/stock/?symbols[]=GOOG&symbols[]=MSFT&time=2015-01-01

Once I add the following overload, then everything breaks down:

    [Route("")]
    public IEnumerable<dynamic> Get(
        [FromUri] string[] symbols, [FromUri] string[] fields) {
        // Return specified stock data fields for the specified symbols
    }

I would expect the following request to select Method 3:

GET http://server/data/stock/?symbols[]=GOOG&symbols[]=MSFT&fields[]=Price&fields[]=Volume

Instead I receive the error:

Multiple actions were found that match the request: Get on type StockDataController Get on type StockDataController

Is it possible to have multiple collection parameters in this way? If so, what am I doing wrong here?

You need an optional parameter in your REST service.

Just use your time variable as nulleable: DateTime? time

public IEnumerable<StockDataItem> Get([FromUri] string[] symbols, DateTime? time) {
    // Return stock data at a specific time for the provided symbols
}

Now you can call your service as:

GET http://server/data/stock/?symbols[]=GOOG&symbols[]=MSFT

or

GET http://server/data/stock/?symbols[]=GOOG&symbols[]=MSFT&time=2015-01-01

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM