问题
I'm successfully passing data between a handheld device (Compacted Framework/Windows CE) and a modern (not "modern" as in Windows 8, but as in 21st Century) server app (Web API). However, after the (successful) passing of data, the client fails with the err msg, "This operation cannot be performed after the request has been submitted"
Which operation is it complaining about? Here's my client code:
public static HttpWebResponse SendXMLFile(string xmlFilepath, string uri)
{
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(xmlFilepath))
{
String line;
while ((line = sr.ReadLine()) != null)
{
sb.AppendLine(line);
}
}
string strData = @sb.ToString();
strData = strData.Replace("\"", "'");
string body = String.Format("\"{0}\"", strData);
HttpWebRequest request = CreateRequestNoCredentials(uri, HttpMethods.POST, body, "application/json");
MessageBox.Show("Made it past the call to CreateRequestNoCredentials()");
try
{
using (var response = (HttpWebResponse)request.GetResponse())
{
MessageBox.Show(string.Format("ReadResponse val = {0}", RESTfulMethods.ReadResponse(response)));
return response;
}
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Msg = {0}; StackTrace = {1}", ex.Message, ex.StackTrace));
request.Abort();
return null;
}
}
public static HttpWebRequest CreateRequestNoCredentials(string uri, HttpMethods method, string data, string contentType)
{
//test:
MessageBox.Show(string.Format("In CreateRequestNoCredentials(); data passed in = {0}", data));
WebRequest request = HttpWebRequest.Create(uri);
request.Method = Enum.ToObject(typeof(HttpMethods), method).ToString();
request.ContentType = contentType;
((HttpWebRequest)request).Accept = contentType;
((HttpWebRequest)request).KeepAlive = false;
((HttpWebRequest)request).ProtocolVersion = HttpVersion.Version10;
if (method != HttpMethods.GET && method != HttpMethods.DELETE)
{
Encoding encoding = Encoding.UTF8;
request.ContentLength = encoding.GetByteCount(data);
request.GetRequestStream().Write(
encoding.GetBytes(data), 0, (int)request.ContentLength);
request.GetRequestStream().Close();
}
else
{
// If we're doing a GET or DELETE don't bother with this
request.ContentLength = 0;
}
// Finally, return the newly created request to the caller.
return request as HttpWebRequest;
}
It may be that the code following:
MessageBox.Show("Made it past the call to CreateRequestNoCredentials()");
...is unnecessary, but I'm apparently not even getting there, as I never see that message; I just see the aforementioned error, and then "Error An unexpected error has occurred in Bla.exe Select Quite and then restart this program, or select Details for more information."
Details are: "Error Bla.exe ObjectDisposedException at System.Threading.WaitHandle.CheckResultInternal(Boolean r) at...(etc.)"
And then, "Application Bla.exe encountered a serious error and must shut down."
So what's the trip-up?
UPDATE
I don't understand the leadthumb response to this question.
An additional odd thing about it all is that, even though I get "encountered a serious error" it doesn't really seem to be as serious as other times the handheld app crashes, in which case I have to often warmboot the device and/or reseat the device in its cradle prior to copying a new version of the .exe over the old. But that is not happening with this "serious" error.
I simplified the code so that it no longer returns a HttpWebResponse, but I still get the same result. YET, what I want to happen works fine: the data is sent to the server app, and it successfully recreates an XML file from the data passed, and then updates a database by inserting a new record based on values passed.
Here's the new, streamlined code:
public static void SendXMLFile(string xmlFilepath, string uri, int timeout) // timeout should be 500
{
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(xmlFilepath))
{
String line;
while ((line = sr.ReadLine()) != null)
{
sb.AppendLine(line);
}
}
string strData = @sb.ToString();
strData = strData.Replace("\"", "'");
string body = String.Format("\"{0}\"", strData);
CreateRequestNoCredentials(uri, HttpMethods.POST, body, "application/json");
}
UPDATE 2
If I catch and ignore the exception this way:
catch (Exception ex)
{
if (ex.Message.Contains("This operation cannot be performed after the request has been submitted"))
{
// just make like Johnny Bench
}
}
...I can run the method without incident; however, when I then close the app, I get the "an unexpected error has occurred in Bla.exe. Select Quit and then restart this program, or select Details for more information."
UPDATE 3
The suggested replacement code gives me, "Cannot implicitly convert type 'byte[]' to 'long'"
Changing it to this:
request.ContentLength = arrData;
...gives me, "Cannot convert type 'byte[]' to 'long'"
So it can't be either im- or explicitly converted to long...then...???
UPDATE 4
Okay, arrData.Length works.
回答1:
You should run your code under the debugger and watch which line it fails on.
GetRequestStream
should not be called more than once. You should consider changing your code to this:
byte[] arrData = Encoding.UTF8.GetBytes(data);
request.ContentLength = arrData.Length;
using (Stream oS = request.GetRequestStream())
{
oS.Write(arrData, 0, arrData.Length);
}
来源:https://stackoverflow.com/questions/22490251/which-operation-cannot-be-performed-after-the-request-has-been-submitted