Click here to Skip to main content
15,884,629 members
Articles / Web Development / ASP.NET
Tip/Trick

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

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
12 Feb 2014CPOL2 min read 11K   5  
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:

C#
[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:

C#
[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:

C#
[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 <argname>=<argval> 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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder Across Time & Space
United States United States
I am in the process of morphing from a software developer into a portrayer of Mark Twain. My monologue (or one-man play, entitled "The Adventures of Mark Twain: As Told By Himself" and set in 1896) features Twain giving an overview of his life up till then. The performance includes the relating of interesting experiences and humorous anecdotes from Twain's boyhood and youth, his time as a riverboat pilot, his wild and woolly adventures in the Territory of Nevada and California, and experiences as a writer and world traveler, including recollections of meetings with many of the famous and powerful of the 19th century - royalty, business magnates, fellow authors, as well as intimate glimpses into his home life (his parents, siblings, wife, and children).

Peripatetic and picaresque, I have lived in eight states; specifically, besides my native California (where I was born and where I now again reside) in chronological order: New York, Montana, Alaska, Oklahoma, Wisconsin, Idaho, and Missouri.

I am also a writer of both fiction (for which I use a nom de plume, "Blackbird Crow Raven", as a nod to my Native American heritage - I am "½ Cowboy, ½ Indian") and nonfiction, including a two-volume social and cultural history of the U.S. which covers important events from 1620-2006: http://www.lulu.com/spotlight/blackbirdcraven

Comments and Discussions

 
-- There are no messages in this forum --