如何在Web API属性路由注释中表示args(如果有的话),如果不是,它们是如何被发现的?

时间:2014-02-10 23:27:03

标签: c# rest url uri asp.net-web-api-routing

我目前正在使用属性路由,例如:

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

...我正在使用更长的(更多“碎片”或参数),并且在实践中它们工作正常。

但是,我需要重构这个(args masquerading as part of the path considered bad practice),以便客户端传递的URI不是这样的:

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

......而是喜欢这样:

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

目前,我可以获取在“path”信息中传递的args,并将它们从Controller(它们到达的地方)传递到Repository(使用它们来获取所需的精确数据)。

例如,这个Controller方法:

[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);
}

...具有通过URI从分配给方法参数的客户端传递的值。如果有的话,我需要在此代码中更改URI中通过“?=”方法传递的args,以便也分配给方法参数?

我是否可以这样做,将那些args简单地从属性路由注释中剥离出来,如下所示:

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

...或者可能保持原样,仅改变URI的格式(但控制器中没有任何内容)?

更新

我没想到它会起作用,但我绝对可以验证是否保留服务器代码,并用这个爵士代替URI:

"?<argName>=<argVal>"

...不起作用 - 它甚至没有按下我的Controller方法就返回null!

更新2

使用这样的URI:

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

...如果我从路由属性和方法签名中删除所有args,我可以访问Controller:

[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);
}

...但是我现在/如何获得URI中传递的args?

1 个答案:

答案 0 :(得分:1)

用“[FromURI]”注释Controller方法:

[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;
}

......除了第一个“?”之外的其他所有内容在使用“&amp;”

传入的URI中