我第一次收到“无法连接到远程服务器”,但后来记得我无法使用手持设备中的“localhost”。我把它换成了机器的名字,如下:
String uri = String.Format(@"http://PLATYPUS:21608/api/inventory/sendXML/woodrow/gus/{0}", fileName);
//I reckon I could also use the IP address in place of the machine name, but probably would make no difference
...现在我明白了,“远程服务器返回错误:(400)错误请求”
相同的基本代码(如下所示)可以在VS 2013中创建的“常规”(C#桌面)应用程序中正常运行。从手持设备中,使用在VS 2003中创建的此代码,我得到了(“400”)错误味精。为什么会这样?
public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.ContentType = "application/xml";
request.Method = "POST";
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(xmlFilepath))
{
String line;
while ((line = sr.ReadLine()) != null)
{
sb.Append(line);
sb.Append("\r\n");
}
byte[] postBytes = Encoding.UTF8.GetBytes(sb.ToString());
if (timeout < 0)
{
request.Timeout = timeout;
}
request.ContentLength = postBytes.Length;
request.KeepAlive = false;
request.ContentType = "application/x-www-form-urlencoded"; // not "text/xml" correct?
try
{
Stream requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
return response.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
request.Abort();
return string.Empty;
}
}
}
此代码与VS 2013应用程序中的代码略有不同,具体如下:
(a)高于/不高于:
sb.Append(line);
sb.Append("\r\n");
下面/工作:
sb.AppendLine(line);
(b)高于/无效:
request.Timeout = timeout;
下面/工作:
request.ReadWriteTimeout = timeout;
request.Timeout = timeout;
(c)高于/无效:
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
return response.ToString();
下面/工作:
using (var response = (HttpWebResponse)request.GetResponse())
{
return response.ToString();
}
VS 2013代码有效:
public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.ContentType = "application/xml";
request.Method = "POST";
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(xmlFilepath))
{
String line;
while ((line = sr.ReadLine()) != null)
{
sb.AppendLine(line);
}
byte[] postBytes = Encoding.UTF8.GetBytes(sb.ToString());
if (timeout < 0)
{
request.ReadWriteTimeout = timeout;
request.Timeout = timeout;
}
request.ContentLength = postBytes.Length;
request.KeepAlive = false;
request.ContentType = "application/x-www-form-urlencoded"; // not "text/xml" correct?
try
{
Stream requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
using (var response = (HttpWebResponse)request.GetResponse())
{
return response.ToString();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
request.Abort();
return string.Empty;
}
}
}
工作代码(没有错误信息,文件保存到硬盘驱动器)将此传递给SendXMLFile():
xmlFilepath == "C:\\HoldingTank\\Bla123456789.xml"
uri == http://localhost:21608/api/inventory/sendXML/woodrow/gus/Bla123456789
timeout == 500
失败的代码(错误信息,文件被创建并保存,但它是空的)通过:
xmlFilepath == "Bla123456789.xml"
uri == http://SHANNON2:21608/api/inventory/sendXML/woodrow/gus/Bla123456789
timeout == 500
(在将该字符串传递给URI上的服务器之前,“。xml”将从xmlFilePath中删除)
关于xmlFilePath中的文件是否存在于失败代码中,我有这段代码:
public static bool WriteIt2( string fileName, string data, long fsize )
{
bool retVal = false;
long bytRd = 0;
string the_Msg = "";
if (File.Exists(fileName))
File.Delete(fileName);
using (FileStream fs = File.Create(@fileName))
{
Byte[] info = new UTF8Encoding(true).GetBytes(data);
fs.Write(info, 0, info.Length);
fs.Flush();
}
if (!File.Exists(fileName))
{
MessageBox.Show(String.Format("{0} does not seem to exist", fileName));
}
else
{
MessageBox.Show(String.Format("{0} DOES seem to exist", fileName));
}
string justFileName = Path.GetFileNameWithoutExtension(fileName);
String uri = String.Format(@"http://PLATYPUS:21608/api/inventory/sendXML/woodrow/gus/{0}", fileName);
. . .
......我确实看到了“...似乎存在”的肯定信息。
文件名是否需要附加“\”(或其他内容)?
文件写入(FileStream)代码是错误的吗?
我尝试使用稍微不同的FileStream代码:
Byte[] info = Encoding.ASCII.GetBytes(data);
using (FileStream fileTest = File.Open(fileName, FileMode.CreateNew))
{
fileTest.Write(info, 0, info.Length);
fileTest.Flush();
}
. . .
...但仍然会得到相同的“400”错误。
还使用UTF8字节数组而不是ASCII字节数组:
Byte[] info = Encoding.UTF8.GetBytes(data);
...仍然得到同样的错误...
我意识到我在这里做个嘘声:
string justFileName = Path.GetFileNameWithoutExtension(fileName);
. . .
SendXMLFile(fileName, uri, 500);
...所以改为:
SendXMLFile(justFileName, uri, 500);
...现在我收到了“找不到文件”例外。
如何通过File.Exists测试然后找不到?
好的,真的很疯狂,因为我将文件复制到手持设备,进入.exe / .dll所在的文件夹,并将其名称分配给“justFileName”;它仍然说无法找到该文件。
好吧,小提琴手,我来了......
好的,这是我在Fiddler看到的服务器正在运行,然后我尝试从手持设备发送文件:
在尝试发送文件失败/中止之前,Fiddler中出现的情况并不多,而且Fiddler中显示的内容似乎没有太大帮助。
我想知道它是否甚至无法从掌上电脑发送任何Http流量?因为我得到“文件未找到”,所以很有可能是真的 - 为什么它会尝试发送它,如果它找不到它?
至于可能的标题差异(仍然没有看到任何与我在Fiddler中的HTTP流量相关的内容),我想我会认为我可能会收到来自Fiddler的报告,如果这是一个问题,因为我得到了这是由于雅虎广告表现糟糕(显然):
我修复了找不到文件的问题,但这让我回到了“400”错误。还有Odder,我在服务器代码上有一个断点(在“String saveLoc =”行上),但它没有到达...... ???
[Route("api/inventory/sendXML/{userId}/{pwd}/{filename}")]
public async void SendInventoryXML(String userId, String pwd, String fileName)
{
XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());
String saveLoc = String.Format(@"C:\HDP\{0}.xml", fileName); // this line has a breakpoint on it, but Rip Van Winkle is not getting poked.
doc.Save(saveLoc);
}
所以从服务器返回的错误发生在之前到那条(断点)线...... ???
为了理解为什么没有达到服务器方法并得到“error(400)”消息,我添加了一堆调试字符串来查看HttpWebRequest的值,如下所示:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
. . .
request.ContentLength = postBytes.Length;
String str;
if (null != request.Address)
{
String str = String.Format("request.Address == {0}", request.Address.ToString());
MessageBox.Show(str);
}
if (null != request.Connection)
{
str = String.Format("connection == {0}", request.Connection.ToString());
MessageBox.Show(str);
}
. . .
if (null != request.ContentLength.ToString())
{
str = String.Format("contentLength == {0}", request.ContentLength.ToString());
MessageBox.Show(str);
}
我为以下“请求”(HttpWebRequest)属性添加了这些调试字符串:
Address
Connection
ContentType
Expect
MediaType
Referer // Referrer (don't fear the spell-checker)
RequestUri
TransferEncoding
UserAgent
ContentLength
唯一显示(不为空)的是:
Address
ContentType
RequestUri
ContentLength
所以其他人都是空的 - 这可能是一个问题吗?
为了充分披露,显示的值为:
Address == http://PLATYPUS:21608/api/Inventory/sendXML/gus/woodrow/INV_0000003_08272014175010
ContentType == application/xml
RequestUri == [same as Address]
ContentLength == 11457215
注意:在显示这四个值之后,我仍然得到“400”错误消息...
应该这样:
request.KeepAlive = false;
...设置为true(或者完全省略,因为默认情况下它显然是真的?
请参阅更新2 here。