Encoding 为什么HttpWebRequest正文val在“0”之后为空;穿越卢比孔;?
我正在尝试将XML文件的内容从手持设备(Compact Framework/Windows CE)发送到我的服务器应用程序中的Web API方法,如(客户端代码): …serialNum和siteNum参数与预期一致(包含有效的预期值),但正文(stringifiedXML)为空。为什么? 更新 我在客户端中也添加了以下内容:Encoding 为什么HttpWebRequest正文val在“0”之后为空;穿越卢比孔;?,encoding,asp.net-web-api,httpwebrequest,fiddler,frombodyattribute,Encoding,Asp.net Web Api,Httpwebrequest,Fiddler,Frombodyattribute,我正在尝试将XML文件的内容从手持设备(Compact Framework/Windows CE)发送到我的服务器应用程序中的Web API方法,如(客户端代码): …serialNum和siteNum参数与预期一致(包含有效的预期值),但正文(stringifiedXML)为空。为什么? 更新 我在客户端中也添加了以下内容: request.ContentLength = postBytes.Length; // Did the sb get into the byte array? Mess
request.ContentLength = postBytes.Length;
// Did the sb get into the byte array?
MessageBox.Show(request.ContentLength.ToString());
…字节数组确实包含数据,如图“112”(XML文件非常小)
更新2
现在,我添加了另一个调试消息:
try
{
Stream requestStream = request.GetRequestStream();
// now test this:
MessageBox.Show(string.Format("requestStream length is {0}", requestStream.Length.ToString()));
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
using (var response = (HttpWebResponse)request.GetResponse())
{
return response.ToString();
}
}
catch (Exception ex)
{
MessageBox.Show("SendXMLFile exception " + ex.Message);
request.Abort();
return string.Empty;
}
…我甚至没有看到“requestStream length is”消息;相反,我看到,“SendXMLFileException不支持Exception”
更新3
我想这是山楂效应或类似效应的一个例子。一旦我注释掉了debug(MessageBox.Show())语句,我就回到了服务器应用程序中,但是[FromBody]val为null
然后,客户端收到消息“无法从传输连接读取数据”
更新4
stringifiedXML在此处仍然为空:
public async void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML, string serialNum, string siteNum)
{
string beginningInvoiceNum = string.Empty;
string endingInvoiceNum = string.Empty;
XDocument doc = XDocument.Parse(stringifiedXML);
…即使在我根据类似的响应修改了客户端中的代码之后:
我试图获得堆栈跟踪,如下所示:
catch (Exception ex)
{
MessageBox.Show(string.Format("Msg = {0}; StackTrace = {1)", ex.Message, ex.StackTrace));
request.Abort();
return string.Empty;
}
…但现在我只看到,“请求提交后无法执行此操作。”
更新6
我将方法签名更改为:
public static HttpWebResponse SendXMLFile(string xmlFilepath, string uri)
try
{
using (var response = (HttpWebResponse)request.GetResponse())
{
return response;
}
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Msg = {0}; StackTrace = {1)", ex.Message, ex.StackTrace));
request.Abort();
return null;
}
…以及与此对应的代码:
public static HttpWebResponse SendXMLFile(string xmlFilepath, string uri)
try
{
using (var response = (HttpWebResponse)request.GetResponse())
{
return response;
}
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Msg = {0}; StackTrace = {1)", ex.Message, ex.StackTrace));
request.Abort();
return null;
}
…但这并没有什么区别(而且我看不到“StackTrave=”消息,所以它一定是失败了)
更新7
我将两个调试字符串放入:
0)
1) 在SendXMLFile()中:
…我看到:
…但在第二个服务器有机会向我展示血淋淋的详细信息之前,服务器接收到空的body值,然后崩溃,然后客户端发出相同的“提交请求后无法执行此操作”投诉
更新8
作为对建议的回应,“我怀疑如果在CreateRequest调用后删除KeepAlive和ProtocolVersion的设置,异常将消失。”我更改了以下代码:
HttpWebRequest request = CreateRequestNoCredentials(uri, HttpMethods.POST, strData, "application/xml");
//test:
MessageBox.Show(string.Format("After calling CreateRequestNoCredentials(), request contentLen = {0}, headers = {1}, requestUri = {2}",
request.ContentLength, request.Headers, request.RequestUri));
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
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;
if (method != HttpMethods.GET && method != HttpMethods.DELETE)
{
Encoding encoding = Encoding.UTF8;
request.ContentLength = encoding.GetByteCount(data);
request.ContentType = contentType;
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;
}
……为此:
HttpWebRequest request = CreateRequestNoCredentials(uri, HttpMethods.POST, strData, "application/xml");
//test:
MessageBox.Show(string.Format("After calling CreateRequestNoCredentials(), request contentLen = {0}, headers = {1}, requestUri = {2}",
request.ContentLength, request.Headers, request.RequestUri));
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;
// moved from elsewhere to here:
((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.ContentType = contentType;
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;
}
string strData = @sb.ToString(); // GetDataFromXMLFile();
string body = String.Format("\"{0}\"", strData);
HttpWebRequest request = CreateRequestNoCredentials(uri, HttpMethods.POST, body, "application/json");
…但我仍然收到相同的错误消息(“在提交请求后无法执行此操作”),stringifiedXML在到达服务器时仍然为null
更新9
以下是我通过Fiddler 2发送我理解为应该发送的内容时得到的信息(如果您没有视觉超能力,请右键单击图像并在新选项卡中打开):
…但我不知道我在看什么…有用吗?失败了吗?“body==0”列让我暂停/让我认为它失败了,然而“204”似乎意味着“服务器成功地处理了请求,但没有返回任何内容”
更新10
这是修复uri后的Fiddler尖叫镜头,我确实在服务器应用程序中到达了断点,并发送了良好的数据:
更新11
更改此代码时:
string strData = sb.ToString();
HttpWebRequest request = CreateRequestNoCredentials(uri, HttpMethods.POST, strData, "application/xml");
public async void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML, string serialNum, string siteNum)
{
XDocument doc = XDocument.Parse(await Request.Content.ReadAsStringAsync());
……为此:
HttpWebRequest request = CreateRequestNoCredentials(uri, HttpMethods.POST, strData, "application/xml");
//test:
MessageBox.Show(string.Format("After calling CreateRequestNoCredentials(), request contentLen = {0}, headers = {1}, requestUri = {2}",
request.ContentLength, request.Headers, request.RequestUri));
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;
// moved from elsewhere to here:
((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.ContentType = contentType;
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;
}
string strData = @sb.ToString(); // GetDataFromXMLFile();
string body = String.Format("\"{0}\"", strData);
HttpWebRequest request = CreateRequestNoCredentials(uri, HttpMethods.POST, body, "application/json");
…我现在在stringifiedXML中得到这个:
…所以我现在得到了:“System.Xml.XmlException没有被用户代码处理
HResult=-2146232000
Message=发生意外的文件结尾。第1行,位置15…”
无论如何,这是一个进步
更新12
根据Fiddle中作为“Request Body”传递的字符串的确切组成/格式,结果会有很大的不同
作为请求机构:
<?xml version="1.0"?><LocateAndLaunch><Tasks></Tasks><Locations></Locations></LocateAndLaunch>
"<?xml version=1.0?><LocateAndLaunch><Tasks></Tasks><Locations></Locations></LocateAndLaunch>"
"<?xml version="1.0"?><LocateAndLaunch><Tasks></Tasks><Locations></Locations></LocateAndLaunch>"
"<?xml version=\"1.0\"?><LocateAndLaunch><Tasks></Tasks><Locations></Locations></LocateAndLaunch>"
……或者:
…XDocument doc=XDocument.Load(wait Request.Content.ReadAsStreamAsync())
…这将作为传入的stringifiedXML:
XDocument doc = XDocument.Parse(stringifiedXML);
“某些任务某些位置”
…我得到一个例外:
“System.Xml.XmlException未由用户代码处理
HResult=-2146232000
消息=缺少根元素。“
使用此代码(相同的stringifiedXML):
…我得到,“System.InvalidOperationException未由用户代码处理
HResult=-2146233079
Message=序列不包含任何元素
Source=System.Core
堆栈跟踪:
在System.Linq.Enumerable.First[TSource](IEnumerable`1 source)处
位于c:\HandheldServer\HandheldServer中的HandheldServer.Controllers.DeliveryItemsController.d_u2.MoveNext()
\Controllers\DeliveryItemsController.cs:第109行
内部异常:“
根据我解析传入字符串的方式,我会得到“根元素丢失”或“序列不包含元素”
什么是Deuce McAlistair MacLean Virginia Weeper?!?“
”不是根元素吗?不是“一些任务”和“一些位置”元素吗?对于这样的操作方法
public async void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML,
string serialNum, string siteNum)
{}
请求消息必须是这样的。我在这里使用JSON
POST http://localhost:port/api/values/PostArgsAndXMLFileAsStr?serialNum=1&siteNum=2 HTTP/1.1
Content-Type: application/json
Host: localhost:port
Content-Length: 94
"<?xml version=1.0?><LocateAndLaunch><Tasks></Tasks><Locations></Locations></LocateAndLaunch>"
在更改客户端代码之前,请使用Fiddler发送类似于上述内容的帖子,以确保其在web API端工作。之后,更改客户端以确保其输出的请求仅与Fiddler的工作请求相同。堆栈跟踪是什么?此处没有足够的信息。首先,请说出“serialNum”和“siteNum“args与预期的一样。我不知道它们从何而来。它们是否以某种方式来自请求?此外,返回response.ToString()
不会给您任何有用的信息。返回response.GetResponseStream().ToString()也不会给您任何有用的信息
。如果要返回文本,必须从响应流中创建一个StreamReader
,并读取数据。查看StreamReader.ReadToEnd
方法,该方法将读取并返回字符串中的全部内容。显示协议冲突异常的完整堆栈跟踪,并告诉我们发生在哪一行。更好的是,你的代码可以单独识别问题。你可以考虑获取小提琴手并查看从客户机流出的数据。如果POST数据在请求中(正如我猜想的那样)。,则问题出在服务器上。当然,您必须将更改还原到客户端,或者找出如何破坏它。可能是因为您正在设置请求的属性而引发异常
XDocument doc = XDocument.Parse(stringifiedXML);
public async void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML,
string serialNum, string siteNum)
{}
POST http://localhost:port/api/values/PostArgsAndXMLFileAsStr?serialNum=1&siteNum=2 HTTP/1.1
Content-Type: application/json
Host: localhost:port
Content-Length: 94
"<?xml version=1.0?><LocateAndLaunch><Tasks></Tasks><Locations></Locations></LocateAndLaunch>"
string content = @"<?xml version=1.0?><LocateAndLaunch><Tasks></Tasks><Locations></Locations></LocateAndLaunch>";
string body = String.Format("\"{0}\"", content);