0

我正在尝试从客户端应用程序调用应用程序中的 Web API Rest 方法。我有两个客户端应用程序 - 一个可以工作,另一个不能。

调用 REST 方法的代码是相同的。当然,它完全相同的服务器代码。

在失败的客户端应用程序中,它在这一行失败:

var webResponse = (HttpWebResponse)webRequest.GetResponse();

...并且两个应用程序中的代码完全相同,直到出现故障点,除了失败的应用程序在事件处理程序中,而工作的应用程序不在。好吧,除了测试代码在事件处理程序中和“真实”代码在单独的方法中之外,另一个(相关的)区别是,单独的方法也在单独的类中。为什么这会有所作为,我不知道,但我在这里有点抓住稻草。这里是:

Cursor.Current = Cursors.WaitCursor;
try
{
    // Cannot start with String.Empty or " "; they both fail for some reason - Controller method is not even called.
    string lastIDFetched = "0";
    const int RECORDS_TO_FETCH = 100;
    bool moreRecordsExist = true;

    try
    {
        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); 
            // GET is the default method/verb, but it's here for clarity
            webRequest.Method = "GET";
            var webResponse = (HttpWebResponse)webRequest.GetResponse();// <-- this throws an exception when there is no longer any data left

失败方法的定义:

private void buttonGetInvItemsInBlocks_Click(object sender, EventArgs e)

工作方法定义:

public static List<HHSUtils.InventoryItem> GetBatchOfInventoryItems()

在失败的那个上,最后一行的 F10 直接进入 Exception 块(goto 被认为是有害的 - 不开玩笑!),但异常什么也没显示 - 悬停在这条线上:

catch (Exception ex)

...我只看到,“ Exception | System.Exception base {object} | object

两个客户端均内置于 Visual Studio 2008 并针对 .NET 3.5;服务器是 VS 2013,.NET 4.5.1

我猜这是一条线索:失败的代码将目标设备设置为“Windows CE 设备”(它部署到手持设备,我通过“Windows CE 的远程显示控制”进行控制)

有人在这里与他们的内部哥伦布保持联系吗?

更新

我从这里更改了代码:

var webResponse = (HttpWebResponse)webRequest.GetResponse();

...对此:

using (var webResponse = (HttpWebResponse)webRequest.GetResponse())

...并且没有区别 - 它仍然从该行直接跳转到 catch 块,在显示的异常中没有有用的数据。

在我的测试应用程序中,我更改了代码以使用“更好”的方式(使用);它以任何一种方式工作,而另一个应用程序则不能。IOW:使用 using 很好,但在这种情况下并没有真正的区别。

更新 2

为了回应 JayC 的回答,我尝试了以下所有“连接字符串”——结果完全相同:

string uri = string.Format("http://localhost:28642/api/InventoryItems/{0}/{1}", lastIDFetched, RECORDS_TO_FETCH); // Fails on "using" line below with no usable exception data
//string uri = string.Format("http://192.112.263.38:28642/api/InventoryItems/{0}/{1}", lastIDFetched, RECORDS_TO_FETCH); <-- same failure
//string uri = string.Format("http://192.112.263.38/api/InventoryItems/{0}/{1}", lastIDFetched, RECORDS_TO_FETCH); <-- same failure
//string uri = string.Format("http://192.112.263.38:80/api/InventoryItems/{0}/{1}", lastIDFetched, RECORDS_TO_FETCH); <-- same failure
//string uri = string.Format("http://192.112.263.38:777/api/InventoryItems/{0}/{1}", lastIDFetched, RECORDS_TO_FETCH); <-- same failure
//string uri = string.Format("http://192.112.263.38:28642/api/inventoryItems/{0}/{1}", lastIDFetched, RECORDS_TO_FETCH); <-- same failure
//string uri = string.Format("http://192.112.263.38/api/inventoryItems/{0}/{1}", lastIDFetched, RECORDS_TO_FETCH); <-- same failure
//string uri = string.Format("http://192.112.263.38:80/api/inventoryItems/{0}/{1}", lastIDFetched, RECORDS_TO_FETCH); <-- same failure
//string uri = string.Format("http://192.112.263.38:777/api/inventoryItems/{0}/{1}", lastIDFetched, RECORDS_TO_FETCH); <-- same failure

更新 3

作为对 Roman Gruber 对 CAS 的评论的回应:维基百科有一个 CAS 的消歧页面(http://en.wikipedia.org/wiki/Cas_(disambiguation)),但在这种情况下,所提供的可能性似乎都不合理。

主要文章 OTOH 在计算部分有几个 CAS 首字母缩略词。您指的是以下哪一项:

Central Authentication Service, a single sign-on protocol
Channel Associated Signaling, a type of communication signaling
Code Access Security in the Microsoft .NET framework

?

更新 4

好的,我添加了几只猫建议的代码:

catch (WebException webex)
{
    HttpWebResponse hwr = (HttpWebResponse) webex.Response;
    HttpStatusCode hsc = hwr.StatusCode;
    MessageBox.Show(string.Format("{0} Status code == {1}", webex.Message, hsc.ToString()));
}

...这就是我在断点到达捕获点时看到的内容:

在此处输入图像描述

这是显示的错误消息:

“远程服务器返回错误:(400) 错误请求。状态码 == 错误请求”

我认为问题出在“连接字符串”上;从更新 2 中可以看出,我已经尝试了所有我能想到的方法,但无法将设备连接到桌面。

4

5 回答 5

2

失败的应用程序部署到手持设备,但 uri 设置为 localhost?

您可能希望使用解析为托管服务的实际计算机的主机名。

编辑:我对 Windows CE 设备一无所知,但似乎应该有更简单的方法从部署到设备的设备中获取更明确的异常信息。我怀疑这是您需要解决的主要问题,如果碰巧您的直接问题恰好被我上面提到的解决了。我希望这是debug="True" 可以在 app.config 文件中设置的微不足道的东西,但我必须对此进行研究。

于 2013-11-15T18:22:40.530 回答
1

只是一个长镜头:两个应用程序之间的线程有什么区别吗?如果我理解正确,失败的应用程序正在从主线程(从按钮事件处理程序)调用网络代码。如果您这样做,Android 会导致您的应用程序崩溃(以防止主线程阻塞)。但是不知道Windows CE有没有类似的系统...

于 2013-11-18T15:10:40.043 回答
1

我将尝试将此作为答案,以澄清我对问题的注释:

1.: CAS = Code Access Security - 抱歉,我假设首字母缩略词在 .NET 环境中足够常见。

2.:向服务器验证请求:

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Credentials = new NetworkCredential("username", "password");

但是:我刚刚意识到其他事情......以前的答案和/或问题有点误导我,并且示例代码中的滚动条也没有帮助。引发异常的是“WebRequest.Create”方法?那根本还没有访问任何网络。在这种情况下,它既不能是主机名/IP 地址,也不能是任何相关的凭据。它仍然可能与CAS有关。但更有可能的是,它是一个格式错误的 URI……

尝试添加一个

MessageBox.Show(formatargready_uri);

在调用 WebRequest.Create 之前查看您的应用在设备上生成的 URL。那里的 URI 解析也可能是“轻量级的”。接下来,我建议在 catch-block 中也使用一个消息框:

catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

3.:广告网络连接性:您的意思是,您可以从 PC 上看到设备,但设备可以看到网络吗?打开设备上的网络浏览器并尝试访问网络上的任何页面以验证...

于 2013-11-18T20:50:27.767 回答
1

您是否尝试过在带有 oa 调试器的 CE 设备上运行该应用程序?只是好奇故障是否仅发生在调试环境中。

此外,Roman Gruber 提出了一个很好的问题,但我没有看到回复:

您可以从 PC 中看到设备,但设备可以看到网络吗? 打开设备上的网络浏览器并尝试访问网络上的任何页面以验证...

于 2013-11-22T14:40:31.083 回答
0

我必须将它添加到 C:\Users\clay\Documents\IISExpress\config\applicationhost.config:

<binding protocol="http" bindingInformation="*:28642:shannon2" />

...并在我的代码中使用这个“连接字符串”:

http://shannon2:28642/api/InventoryItems

现在我可以连接了;我想我以前非常接近(如此接近,但又如此遥远),但它必须是这种精确的组合才能起作用。

于 2013-11-26T19:55:53.260 回答