Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to Instantiate Objects in Web API from Args Passed in a URI to a RESTful Method

0.00/5 (No votes)
12 Feb 2014 1  
Easily (and elegantly) inflate objects based on args passed to a REST method in a URI

Tails of Two Setters

You can have a Controller with very explicit routing/arg attributes, like this:

[Route("api/InventoryItems/PostInventoryItem/{id}/{pack_size:int}/
{description}/{vendor_id}/{department:int}/{subdepartment:int}/{unit_cost:double}/
{unit_list:double}/{open_qty:double}/{UPC_code}/{UPC_pack_size:int}/{vendor_item}/
{crv_id:long}/{dbContext=03}")]
public void PostInventoryItem(string id, int pack_size, string description, 
string vendor_id, int department, int subdepartment, double unit_cost, double unit_list, 
double open_qty, string UPC_code, int UPC_pack_size, string vendor_item, long crv_id, string dbContext)
{ ... }

And it does work ... It works, but is considered kludgish, unsafe, rude, crude, and unrefined - not to mention "9X Uglier than a Bag of Butts" (™ Eddie J. Nelson, Esquire, 199X). It is considered better to segregate the path elements, namely "InventoryItems/PostInventoryItem" above, where "InventoryItems" indicates the Controller to be called ("InventoryItemsController") and "PostInventoryItem" indicates the method in that Controller to be invoked, from the arguments to be used by the method.

In this way, the method is much cleaner like so:

[Route("api/InventoryItems/PostInventoryItem")]
public void PostInventoryItem(string serialNum, [FromUri] InventoryItem ii)
{
    string serNum = serialNum;
    _inventoryItemRepository.PostInventoryItem(
        ii.ID, ii.pksize, ii.Description, ii.vendor_id, ii.UnitCost, ii.UnitList, 
        ii.OpenQty,
        ii.UPC, ii.dept, ii.subdept, ii.upc_pack_size, ii.vendor_item, ii.crv_id);
}

In fact, this is even better:

[Route("api/InventoryItems/PostInventoryItem")]
public void PostInventoryItem(string serialNum, [FromUri] InventoryItem ii)
{
    string serNum = serialNum;
    _inventoryItemRepository.PostInventoryItem(serNum, ii);
}

...with the method in the Repository taking just two args - the serial number and the inflated object - rather than a gazillion (or so) args - the individual members of the object.

If the first way is 9X Uglier than a Bag of Butts, this way is downright callipygian.

The snazzy part of this is the "[FromUri]" in the method signature, which allows the client to in effect send an InventoryItem object without the Client needing to know what such a thing is. The Web API framework figures it out, when that "[FromUri]" business is used, where possible (when there is a class whose members correspond to the arguments passed in).

For example, the client could pass the following URI to the server, which would hit this method and instantiate an InventoryItem class:

http://localhost:28642/api/InventoryItems/PostInventoryItem?serialNum=8675309e9&ID=146&
pksize=1&Description=Valdesc4&vendor_id=venderad4&UnitCost=2.57&UnitList=3.83&
OpenQty=25.71&UPC=12348&dept=140&subdept=88&upc_pack_size=16&vendor_item=VendIte&crv_id=9913

The first part (http://localhost:28642) locates the machine and port; the second part (api/InventoryItems/PostInventoryItem) finds the Web API framework, the Controller, and the specific method to be targeted on that Controller, and the last part (the "?" followed by = for the first arg, with "&" replacing the "?" subsequently) contains the array of args that the receiving method will welcome.

A Parting Shot Across the Pooh 

If you found this information useful, go plant a redwood. If you didn't, make a spreadsheet of all your workmates, noting which "Winnie the Pooh" character they most resemble (in personality, not appearance). If there are more Eeyores than Tiggers, do yourself a favor and quit. If you are most like Eeyore, do your workmates a favor and quit; or at least, pause and reflect, repent and reform, cease and desist, stand and deliver.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here