简体   繁体   中英

Why would the same exact code crash in one app, and work in the other?

I am trying to call a Web API Rest method in an app from a client app. I have two client apps - with one, it works, with the other, it doesn't.

The code to call the REST method is identical. It is the same exact server code, of course.

In the failing client app, it fails on this line:

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

...and the code is exactly the same in the two apps, up to the point of failure, except that the failing one is in an event handler, and the working one is not. Well, another (related) difference, besides the test code being in an event handler, and the "real" code being in a separate method, is that the separate method is also in a separate class. Why this would make a difference, I don't know, but I'm kind of grasping at straws here. Here it is:

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

Failing method's definition:

private void buttonGetInvItemsInBlocks_Click(object sender, EventArgs e)

Working method's definition:

public static List<HHSUtils.InventoryItem> GetBatchOfInventoryItems()

On the one that fails, F10 on the last line goes straight to the Exception block (goto considered harmful - no kidding!), but the exception shows me nothing - hovering over this line:

catch (Exception ex)

...I see only, " Exception | System.Exception base {object} | object "

Both clients are built in Visual Studio 2008 and target .NET 3.5; the server is VS 2013, .NET 4.5.1

Here's a clue, I guess: the failing code has target device set to "Windows CE Device" (it deploys to a handheld device, which I control via "Remote Display Control for Windows CE")

Is anybody in touch with their inner Columbo here?

UPDATE

I changed the code from this:

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

...to this:

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

...and it makes no difference - it still jumps straight from that line to the catch block, with no useful data in the exception displayed.

In my test app, I changed the code to use the "more better" way (using); it works either way, whereas the other app works neither way. IOW: using using is good, but it makes no real difference in this case.

UPDATE 2

In response to JayC's answer, I tried all the following "connection strings" - all with the exact same result:

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

UPDATE 3

In response to Roman Gruber's comment about CAS: Wikipedia has a disambiguation page for CAS ( http://en.wikipedia.org/wiki/Cas_(disambiguation) ), but none of the proferred possibilities seem sensible for this context.

The main article, OTOH, has several CAS acronyms in the Computing section. To which of the following are you referring:

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

?

UPDATE 4

Okay, I added the code suggested by a couple of cats:

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

...and here's what I see when the breakpoint reaches the catch:

在此处输入图片说明

And here's the err msg shown:

"The remote server returned an error: (400) Bad Request. Status code == Bad Request"

I think the problem is in the "connection string"; as can be seen in Update 2, I've tried everything I can think of, and nothing works to connect the device to the desktop.

The app that fails deploys to a hand held device, and yet the uri is set to localhost??

You might want to use a host name that resolves to the actual computer hosting the service.

Edit: I know nothing about Windows CE devices, but it seems that there ought to be easier ways to get more explicit exception information from a device that's deployed to a device. I suspect that's your major issue that needs to be solved, if it happens that your immediate issue happen to be solved by what I mentioned above. I would hope it's something trivial like a debug="True" that could be set in an app.config file, but I'd have to research that.

Just a long shot: is there any difference in threading between both apps? If I understand correctly, the failing app is calling the networking code from main thread (from a button event handler). Android would cause your app to crash if you did this (to keep main thread from blocking). But I don't know if Windows CE has a similar system ...

I'll try this as an answer to clarify my notes from the questions:

1.: CAS = Code Access Security - sorry, I assumed the acronym common enough in the .NET environment.

2.: Authenticate the request with the server:

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

But: I just realized something else... the previous answers and/or questions mislead me a bit and the scrollbar in your sample code didn't help either. It's the "WebRequest.Create" method that throws the exception?? That doesn't yet access ANY network at all. It can neither be the host name/ip address nor anything credentials related in this case. It could still be related to the CAS. But more likely, it's a malformed URI...

Try adding a

MessageBox.Show(formatargready_uri);

before calling WebRequest.Create and look at the URL your app produces on the device. URI-parsing might be "lightweight" there too. Next, I'd recommend using a messagebox inside the catch-block too:

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

3.: Ad network connectivity: All you are indicating is, that you can see the device from your PC, but can the device see the network? Open the web browser on the device and try to access any page on the network to verify...

Have you tried running the application on the CE device w/oa debugger? Just curious if the failure is only happening in the debug environment or not.

Also, Roman Gruber asked a good question and I didn't see a response:

you can see the device from your PC, but can the device see the network? Open the web browser on the device and try to access any page on the network to verify...

I had to add this to C:\\Users\\clay\\Documents\\IISExpress\\config\\applicationhost.config:

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

...and use this "connection string" in my code:

http://shannon2:28642/api/InventoryItems

Now I can connect; I think I was very close (so close, and yet so far away) before, but it had to be this exact combination to work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM