为什么我使用此代码获得“NotSupportedException”?

时间:2014-03-07 20:01:28

标签: asp.net-web-api httpwebrequest compact-framework bytearray streamreader

我正尝试使用以下代码从手持设备(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)编译和运行,它只是拒绝真正贯彻所有的运行时现实。

我的代码是否需要对其进行少量更改才能适应,或者我是否需要采取完全不同的方法?

2 个答案:

答案 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);
}