我正尝试使用以下代码从手持设备(Compact Framework)调用Web API方法:
// "fullFilePath" is a value such as "\Program Files\Bla\abc.xml"
// "uri" is something like "http://localhost:28642/api/ControllerName/PostArgsAndXMLFile?serialNum=8675309&siteNum=42"
SendXMLFile(fullFilePath, uri, 500);
. . .
public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
uri = uri.Replace('\\', '/');
if (!uri.StartsWith("/"))
{
uri = "/" + uri;
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
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()中的某个地方,它失败了“ NotSupportedException ”但是......由于它在手持设备上运行,我无法设置断点它并逐步完成;我可以在整个(MessageBox.Show())中撒上一堆调试语句,但我宁愿不这样做。
服务器代码甚至从未到达我在下面的“XDocument doc =”行中放置的断点:
[Route("api/ControllerName/PostArgsAndXMLFile")]
public void PostArgsAndFile([FromBody] string stringifiedXML, string serialNum, string siteNum)
{
XDocument doc = XDocument.Parse(stringifiedXML);
由于某种原因,Compact框架是否无法调用(RESTful)Web API方法?显然,客户端(手持/ Compact Framework)编译和运行,它只是拒绝真正贯彻所有的运行时现实。
我的代码是否需要对其进行少量更改才能适应,或者我是否需要采取完全不同的方法?
答案 0 :(得分:2)
Web API无法处理您的正文内容。您将其声明为application/x-form-urlencoded
,但它实际上是XML格式的,并且您的方法签名期望它是XMLDataContract序列化string
。
而不是使用参数stringifiedXML
,而只是读取方法中的主体..
[Route("api/ControllerName/PostArgsAndXMLFile")]
public async void PostArgsAndFile(string serialNum, string siteNum)
{
XDocument doc = XDocument.Parse(await Request.Content.ReadAsStringAsync());
}
或更好的事件,直接使用流。
[Route("api/ControllerName/PostArgsAndXMLFile")]
public async void PostArgsAndFile(string serialNum, string siteNum)
{
XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());
}
这样,您可以将客户端上的ContentType恢复为application/xml
。
答案 1 :(得分:0)
在服务器端使用Darrel的代码(我正在使用第二个代码,Stream),这适用于客户端:
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";
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;
}
}
}
可以这样称呼:
private void buttonNose_Click(object sender, EventArgs e)
{
String fullFilePath = @"C:\McMurtry\LonesomeDove.XML";
String uri = @"http://localhost:21608/api/inventory/sendxml/ff/gg/42";
SendXMLFile(fullFilePath, uri, 500);
}