![](/img/trans.png)
[英]In Web Api, how can I specify two separate routes to one controller with two get methods without using attributes?
[英]How can I call two GET Web API REST methods, the first to get the count of records that the second one will return?
我知道這很麻煩,但是在我現有的Web API客戶端代碼中,我停止讀取記錄的方式是當我對webRequest.GetResponse()的調用在讀取和查找均未崩潰並吃掉異常時崩潰(我正在讀取“塊/ chunk”,這是由於調用Web API REST方法的手持設備的帶寬限制所致。
由於我的良心(可以這么說)困擾着我這樣做(但確實有效!),我想也許我可以先獲得記錄的數量,並利用該知識來阻止閱讀超出世界的邊緣,從而避免異常。
但是,如下所示: 為什么我的Web API路由被重新路由/錯誤地路由? ,嘗試訪問多個GET方法沒有成功-我只能通過消除另一個來獲得所需的GET方法!
我現有的客戶代碼是:
private void buttonGetInvItemsInBlocks_Click(object sender, EventArgs e)
{
string formatargready_uri = "http://localhost:28642/api/inventoryItems/{0}/{1}";
// Cannot start with String.Empty or a blank string (" ") assigned to lastIDFetched; they both fail for some reason - Controller method is not even called. Seems like a bug in Web API to me...
string lastIDFetched = "0";
const int RECORDS_TO_FETCH = 100;
bool moreRecordsExist = true;
try
{
while (moreRecordsExist)
{
formatargready_uri = string.Format("http://localhost:28642/api/InventoryItems/{0}/{1}", lastIDFetched, RECORDS_TO_FETCH);
var webRequest = (HttpWebRequest)WebRequest.Create(formatargready_uri);
webRequest.Method = "GET";
var webResponse = (HttpWebResponse)webRequest.GetResponse(); // <-- this throws an exception when there is no longer any data left
// It will hit this when it's done; when there are no records left, webResponse's content is "[]" and thus a length of 2
if ((webResponse.StatusCode != HttpStatusCode.OK) || (webResponse.ContentLength < 3)) {
moreRecordsExist = false;
}
else // ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 2))
{
var reader = new StreamReader(webResponse.GetResponseStream());
string s = reader.ReadToEnd();
var arr = JsonConvert.DeserializeObject<JArray>(s);
foreach (JObject obj in arr)
{
string id = (string)obj["Id"];
lastIDFetched = id;
int packSize = (Int16)obj["PackSize"];
string description = (string)obj["Description"];
int dept = (Int16)obj["DeptSubdeptNumber"];
int subdept = (Int16)obj["InvSubdepartment"];
string vendorId = (string)obj["InventoryName"];
string vendorItem = (string)obj["VendorItemId"];
double avgCost = (Double)obj["Cost"];
double unitList = (Double)obj["ListPrice"];
inventoryItems.Add(new WebAPIClientUtils.InventoryItem
{
Id = id,
InventoryName = vendorId,
UPC_PLU = vendorId,
VendorItemId = vendorItem,
PackSize = packSize,
Description = description,
Quantity = 0.0,
Cost = avgCost,
Margin = (unitList - avgCost),
ListPrice = unitList,
DeptSubdeptNumber = dept,
InvSubdepartment = subdept
});
// Wrap around on reaching 100 with the progress bar; it's thus sort of a hybrid determinate/indeterminate value that is shown
if (progressBar1.Value >= 100)
{
progressBar1.Value = 0;
}
progressBar1.Value += 1;
}
} // if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
} // while
if (inventoryItems.Count > 0)
{
dataGridViewGETResults.DataSource = inventoryItems;
}
MessageBox.Show(string.Format("{0} results found", inventoryItems.Count));
}
catch (Exception ex)
{
// After all records are read, this exception is thrown, so commented out the message; thus, this is really *expected*, and is not an "exception"
//MessageBox.Show(ex.Message);
}
}
}
...並且Web API REST Controller代碼為:
public class InventoryItemsController : ApiController
{
static readonly IInventoryItemRepository inventoryItemsRepository = new InventoryItemRepository();
public IEnumerable<InventoryItem> GetBatchOfInventoryItemsByStartingID(string ID, int CountToFetch)
{
return inventoryItemsRepository.Get(ID, CountToFetch);
}
}
...和(im?)相關的存儲庫代碼為:
public IEnumerable<InventoryItem> Get(string ID, int CountToFetch)
{
return inventoryItems.Where(i => 0 < String.Compare(i.Id, ID)).Take(CountToFetch);
}
有人會認為我可以有這樣一種方法:
public IEnumerable<InventoryItem> Get()
{
return inventoryItems.Count();
}
...這將由於沒有參數而與其他參數不同而得到認可(即使沒有路由狂喜,昨天我進行的所有attempts靖嘗試也都以失敗告終)。
我發現我可以用以下代碼獲得記錄數:
private int getInvItemsCount()
{
int recCount = 0;
const string uri = "http://localhost:28642/api/InventoryItems";
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Method = "GET";
using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
if (webResponse.StatusCode == HttpStatusCode.OK)
{
var reader = new StreamReader(webResponse.GetResponseStream());
string s = reader.ReadToEnd();
Int32.TryParse(s, out recCount);
}
}
return recCount;
}
private void GetInvItemsInBlocks()
{
Cursor.Current = Cursors.WaitCursor;
try
{
string lastIDFetched = "0";
const int RECORDS_TO_FETCH = 100;
int recordsToFetch = getInvItemsCount();
bool moreRecordsExist = recordsToFetch > 0;
int totalRecordsFetched = 0;
while (moreRecordsExist)
{
string formatargready_uri = string.Format("http://localhost:28642/api/InventoryItems/{0}/{1}", lastIDFetched, RECORDS_TO_FETCH);
var webRequest = (HttpWebRequest)WebRequest.Create(formatargready_uri);
webRequest.Method = "GET";
using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
if (webResponse.StatusCode == HttpStatusCode.OK)
{
var reader = new StreamReader(webResponse.GetResponseStream());
string s = reader.ReadToEnd();
var arr = JsonConvert.DeserializeObject<JArray>(s);
foreach (JObject obj in arr)
{
var id = (string)obj["Id"];
lastIDFetched = id;
int packSize = (Int16)obj["PackSize"];
var description = (string)obj["Description"];
int dept = (Int16)obj["DeptSubdeptNumber"];
int subdept = (Int16)obj["InvSubdepartment"];
var vendorId = (string)obj["InventoryName"];
var vendorItem = (string)obj["VendorItemId"];
var avgCost = (Double)obj["Cost"];
var unitList = (Double)obj["ListPrice"];
inventoryItems.Add(new WebAPIClientUtils.InventoryItem
{
Id = id,
InventoryName = vendorId,
UPC_PLU = vendorId,
VendorItemId = vendorItem,
PackSize = packSize,
Description = description,
Quantity = 0.0,
Cost = avgCost,
Margin = (unitList - avgCost),
ListPrice = unitList,
DeptSubdeptNumber = dept,
InvSubdepartment = subdept
});
if (progressBar1.Value >= 100)
{
progressBar1.Value = 0;
}
progressBar1.Value += 1;
} // foreach
} // if (webResponse.StatusCode == HttpStatusCode.OK)
} // using HttpWebResponse
int recordsFetched = WebAPIClientUtils.WriteRecordsToMockDatabase(inventoryItems, hs);
label1.Text += string.Format("{0} records added to mock database at {1}; ", recordsFetched, DateTime.Now.ToLongTimeString());
totalRecordsFetched += recordsFetched;
moreRecordsExist = (recordsToFetch > (totalRecordsFetched+1));
} // while
if (inventoryItems.Count > 0)
{
dataGridViewGETResults.DataSource = inventoryItems;
}
}
finally
{
Cursor.Current = Cursors.Default;
}
}
倉庫接口:
interface IInventoryItemRepository
{
. . .
int Get();
. . .
}
存儲庫接口實現:
public class InventoryItemRepository : IInventoryItemRepository
{
private readonly List<InventoryItem> inventoryItems = new List<InventoryItem>();
. . .
public int Get()
{
return inventoryItems.Count;
}
. . .
}
控制器:
static readonly IInventoryItemRepository inventoryItemsRepository = new InventoryItemRepository();
public int GetCountOfInventoryItems()
{
return inventoryItemsRepository.Get();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.