我试图用此代码从手持设备(紧凑型框架)调用Web API方法:
// "fullFilePath" is a value such as "Program FilesBlaabc.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);
由于某种原因,紧凑型框架无法调用(休息)Web API方法?显然,客户端(手持/紧凑型框架)编译和运行,它只是拒绝实际遵循所有这些的运行时现实。
我的代码是否需要进行较小的更改才能适应它,还是需要完全不同的钉子?
Web API无法处理您的身体内容。您将其声明为application/x-form-urlencoded
,但实际上是XML格式的,您的方法签名期望它是XMDATACNACTRACTENT序列化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
上。
使用服务器端上的darrel的代码(我正在使用第二个,流),这在客户端上起作用:
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:McMurtryLonesomeDove.XML";
String uri = @"http://localhost:21608/api/inventory/sendxml/ff/gg/42";
SendXMLFile(fullFilePath, uri, 500);
}