此代码正常工作 - 返回与REST查询匹配的单个记录:
Popul8TheGrid("http://localhost:28642/api/subdepartments/1/10");
private void Popul8TheGrid(string URIToPass)
{
try
{
dataGridView1.DataSource = GetRESTData(URIToPass);
}
catch (WebException webex)
{
MessageBox.Show("Eek, a mousey-pooh! ({0})", webex.Message);
}
}
private JArray GetRESTData(string uri)
{
var webRequest = (HttpWebRequest) WebRequest.Create(uri);
var webResponse = (HttpWebResponse) webRequest.GetResponse();
var reader = new StreamReader(webResponse.GetResponseStream());
string s = reader.ReadToEnd();
return JsonConvert.DeserializeObject<JArray>(s);
}
但是,这段代码也应该返回一条记录:
private const string BASE_URI = "http://localhost:28642/api/";
. . .
string URIToPass = string.Format("{0}deliveryitems/{1}", BASE_URI, numericUpDownDeliveryItemId.Value);
Popul8TheGrid(URIToPass);
...失败,“ InvalidCastException未处理... Message =无法将类型为'Newtonsoft.Json.Linq.JObject'的对象强制转换为'Newtonsoft.Json.Linq.JArray'”。
为什么会这样?从第一个(工作)片段返回的数据来自MS Access“数据库”
来自第二个(失败的)片段的数据来自测试数据:
public DeliveryItemRepository()
{
// Just some bogus/test data for now
Add(new DeliveryItem
{
Id = 1, InvoiceNumber = "123", UPC_PLU = "456", VendorItemId = "789", PackSize = 1, Description = "Something", Quantity = 5, Cost = 1.25M,
Margin = 0.25M, ListPrice = 1.50M, DepartmentNumber = 42, Subdepartment = "5"
});
。 。
这是Controller方法;在浏览器中输入URI时,它可以正常工作。
// Enter "http://localhost:28642/api/1"
[Route("api/DeliveryItems/{ID:int}")]
public DeliveryItem GetDeliveryItemById(int ID)
{
return _deliveryItemRepository.GetById(ID);
}
......但为什么那会很重要,我不知道......
有趣的是(也许我很容易被逗乐),这个,OTOH,有效:
MessageBox.Show(GetRESTScalarVal("http://localhost:28642/api/deliveries/1"));
. . .
private string GetRESTScalarVal(string uri)
{
var client = new WebClient();
return client.DownloadString(uri);
}
通过“工作”,我的意思是它返回:
所以DownloadString()甚至会返回一个完整的json“记录”,而我对“Scalar”这个词的使用会产生误导。也许我应该说“单一”,虽然这也可能令人困惑,同样的称谓的数据类型是什么。
关于如何使用单个json“记录”填充数据网格仍然存在问题
奇怪的是,如果我使用不同的Controller方法来获取一条记录,它就会起作用:
private void GetDeliveryItemById()
{
//string uri = string.Format("deliveryitems/{0}", numericUpDownId.Value);
string uri = string.Format("deliveryitems/{0}/1", numericUpDownId.Value);
Popul8TheGrid(uri);
}
注释掉的代码是爆炸的,而另一个,提供的const值为1,工作... kludgy,但它有效。
这个存储库代码可能是一个线索/与为什么它在获取它时不起作用有关,但另有效果的是:
public SiteMapping GetById(int ID)
{
return siteMappings.Find(p => p.Id == ID);
}
public IEnumerable<SiteMapping> GetRange(int ID, int CountToFetch)
{
return siteMappings.Where(i => i.Id >= ID).Take(CountToFetch);
}
如果使用存在的ID调用GetById(),它会起作用;但是,如果传递了一个不存在的,则失败,“用户代码未处理InvalidOperationException ... ... Message = Sequence不包含匹配的元素”
调用GetRange()可以很有效地工作 - 如果传递了一对虚假的vals(没有记录),它只是耸了耸肩,而不是让那个老式的眼睛疯狂地尖叫着。
将其更改为(参见Simon Whitehead的回答here)有效:
public SiteMapping GetById(int ID)
{
var entity = siteMappings.Find(p => p.Id == ID);
return entity == null ? null : entity;
}
因此,尝试通过特定ID找到是脆弱的;试图通过ID + Count找到工作得很好。为什么,我(仍然)不知道...
答案 0 :(得分:0)
这可能有点笨拙,但它有效:
private JArray GetRESTData(string uri)
{
try
{
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
var reader = new StreamReader(webResponse.GetResponseStream());
string s = reader.ReadToEnd();
return JsonConvert.DeserializeObject<JArray>(s);
}
catch // This method crashes if only one json "record" is found - try this:
{
try
{
MessageBox.Show(GetScalarVal(uri));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
return null;
}
private string GetScalarVal(string uri)
{
var client = new WebClient();
return client.DownloadString(uri);
}