How are args represented (if at all) in Web API Attribute Routing annotations and if they aren't, how are they discovered?

StackOverflow https://stackoverflow.com/questions/21690046

Question

I am currently using attribute routings such as this:

[Route("api/InventoryItems/{ID}/{packSize:int}/{CountToFetch:int}")]

...and am using even longer ones (with more "pieces," or arguments), and in practice they work fine.

However, I need to refactor this (args masquerading as part of the path considered bad practice) so that the URI passed by the client is not like so:

//http://<machineName>:<portNum>/api/InventoryItems/<IDVal>/<packSizeVal>/<CountToFetchVal>
http://platypus:8675309/api/InventoryItems/42/24/50

...but rather like this:

//http://<machineName>:<portNum>/api/InventoryItems/?<argName>=<argVal>?<argName>=<argVal>?<argName>=<argVal>
http://platypus:8675309/api/InventoryItems?ID=42?packSize=24?CountToFetch=50

Currently I can grab the args passed within the "path" info and pass them from the Controller (where they arrive) to the Repository (which uses them to get the precise data required).

For example, this Controller method:

[System.Web.Http.Route("api/Departments/{ID:int}/{CountToFetch:int}/{dbContext=03}")]
public IEnumerable<Department> GetBatchOfDepartmentsByStartingID(int ID, int CountToFetch, string dbContext)
{
    return _deptsRepository.Get(ID, CountToFetch, dbContext);
}

...has the values passed via a URI from the client assigned to the method parameters. What, if anything, do I need to change in this code for args passed in the URI via the "?=" method to also be assigned to the method parameters?

Can I do this, with those args simply stripped out of the Attribute Routing annotation, like so:

[System.Web.Http.Route("api/Departments")]
public IEnumerable<Department> GetBatchOfDepartmentsByStartingID(int ID, int CountToFetch, string dbContext)
{
    return _deptsRepository.Get(ID, CountToFetch, dbContext);
}

?

...or possibly leave it as-is, with just the format of the URI changing (but nothing in the Controller)?

UPDATE

I wasn't expecting it to work, but I can definitely verify that leaving the server code as is, and replacing the URI with this jazz:

"?<argName>=<argVal>"

...does not work - it returns null without even hitting my Controller method!

UPDATE 2

With an URI like this:

http://localhost:28642/api/InventoryItems/PostInventoryItem?id=42?pack_size=12?description=ValuableDesc?vendor_id=venderado?department=42?subdepartment=85?unit_cost=2.50?unit_list=3.75?open_qty25.25?UPC_code=12345?UPC_pack_size=24?vendor_item=someVendorItem?crv_id=9898987?dbContext=03

...I can reach the Controller if I remove all args from the routing attribute and the method signature:

[Route("api/InventoryItems/PostInventoryItem")]
public void PostInventoryItem()
{
    HandheldServerGlobals.SaveTypes st = HandheldServerGlobals.SaveTypes.CSV; //Works (C:\Program Files (x86)\IIS Express\SiteQuery3.csv created) // <-- I reach the breakpoint on this line, but...:
    //commented out for now:
    //_inventoryItemRepository.PostInventoryItem(id, pack_size, description, vendor_id, department, subdepartment, unit_cost, unit_list, open_qty, UPC_code, UPC_pack_size, vendor_item, crv_id, dbContext, st);
}

...but where/how do I get the args passed in the URI now?

Was it helpful?

Solution

By annotating the Controller method with "[FromURI]":

[Route("api/InventoryItems/PostInventoryItem")]
public HttpResponseMessage PostInventoryItem([FromUri] InventoryItem ii)
{
    _inventoryItemRepository.PostInventoryItem(ii.ID, ii.pksize, ii.Description, ii.vendor_id, ii.dept,
        ii.subdept, ii.UnitCost, ii.UnitList, ii.OpenQty, ii.UPC, ii.upc_pack_size, ii.vendor_item, ii.crv_id);
    var response = Request.CreateResponse<InventoryItem>(HttpStatusCode.Created, ii);
    string uri = Url.Link("DefaultApi", new { id = ii.ID });
    response.Headers.Location = new Uri(uri);
    return response;
}

...and by replacing all but the first "?" in the URI passed in with "&"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top