5

我使用这里的代码尝试从 Compact Framework 客户端调用 Web API 服务器应用程序上的 REST 控制器方法:

public static void SendXMLFile3(string uri, string data)
{
    WebRequest request = WebRequest.Create (uri);
    request.Method = "POST";
    string postData = data;
    byte[] byteArray = Encoding.UTF8.GetBytes (postData);
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = byteArray.Length;
    Stream dataStream = request.GetRequestStream ();
    dataStream.Write (byteArray, 0, byteArray.Length);
    dataStream.Close ();
    WebResponse response = request.GetResponse ();
    MessageBox.Show(((HttpWebResponse) response).StatusDescription);
    dataStream = response.GetResponseStream ();
    StreamReader reader = new StreamReader (dataStream);
    string responseFromServer = reader.ReadToEnd();
    MessageBox.Show(responseFromServer);
    reader.Close ();
    dataStream.Close ();
    response.Close ();
}

...我之前尝试过这段代码,我从“Microsoft .NET Compact Framework”一书中得到:

public static void SendXMLFile2(string uri, string data)
{
    WebRequest req = WebRequest.Create(uri);
    req.Method = "Post";
    req.ContentType = "text/plain; charset=utf-8";
    byte[] encodedBytes = Encoding.UTF8.GetBytes(data);
    req.ContentLength = encodedBytes.Length;

    Stream requestStream = req.GetRequestStream();
    requestStream.Write(encodedBytes, 0, encodedBytes.Length);
    requestStream.Close();

    WebResponse result = req.GetResponse();
    MessageBox.Show(result.ToString());
}

...但我得到“400 - 错误请求”的新(以及旧)代码。

我最初的尝试也不起作用,结果相同(400):

public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
    HttpWebRequest myHttpWebRequest=(HttpWebRequest)WebRequest.Create(uri);
    myHttpWebRequest.AllowWriteStreamBuffering=false;
    string postData = "<Command><DSD><line_id>1</line_id><invoice_no>david_dsd</invoice_no>. . .</DSD></Command>"; // TODO: if this works, replace it with the real data
    myHttpWebRequest.Method="POST";
    UTF8Encoding encodedData = new UTF8Encoding();
    byte[]  byteArray=encodedData.GetBytes(postData);
    myHttpWebRequest.ContentType = "application/xml";
    myHttpWebRequest.ContentLength=byteArray.Length;
    Stream newStream=myHttpWebRequest.GetRequestStream();
    newStream.Write(byteArray,0,byteArray.Length);
    newStream.Close();
    HttpWebResponse myHttpWebResponse=(HttpWebResponse)myHttpWebRequest.GetResponse();
    return myHttpWebResponse.StatusDescription;
}

还有更多关于我在这里尝试过的大量变化,我已经达到了我的帖子长度限制。

更新

请注意,服务器代码不知道/不在乎文件是 XML:

[HttpPost]
[Route("api/inventory/sendXML/{userId}/{pwd}/{filename}")]
public async Task SendInventoryXML(String userId, String pwd, String fileName)
{
    Task task = Request.Content.ReadAsStreamAsync().ContinueWith(t =>
    {
        var stream = t.Result;
        using (FileStream fileStream = File.Create(String.Format(@"C:\HDP\{0}.xml", fileName), (int)stream.Length))
        {
            byte[] bytesInStream = new byte[stream.Length];
            stream.Read(bytesInStream, 0, (int)bytesInStream.Length);
            fileStream.Write(bytesInStream, 0, bytesInStream.Length);
        }
    });
}

更新 2

我试着让 Charles 看看它是否会接收本地 HTTP 流量,但它也对这种情况充耳不闻(就像 Fiddler,无论如何都没有特殊的服务)。这是 Charles 在收到“400 - Bad Request”错误后的样子:

在此处输入图像描述

更新 3

我在某个地方找到了这个建议,让 Fiddler 显示本地 HTTP 流量:

Tools--> Fiddler Options. Choose Connections tab. Check the 'USe PAC Script' option.

...但它不起作用 - 在收到“400(错误请求)”消息时,我仍然看不到 HTTP 流量。

更新 4

我现在也在 Fiddler 2 中看到“400(错误请求)”;为了得到它,我在 Postman 中输入以下任何内容(从 CE/CF/手持应用程序调用时,在 Fiddler 中看不到这个):

http://SHANNON2:21608/api/inventory/sendXML/su/su/blablee // Hostname
http://SHANNON2.:21608/api/inventory/sendXML/su/su/blablee // Hostname with Fiddler-fooler appended "."
http://192.168.125.50:21608/api/inventory/sendXML/su/su/blablee // IP Address

(如果我用“localhost”替换主机名或 IP 地址,Fiddler 不会捕获任何内容)

注意:对于 Postman 中的这些 URL,我选择了“Post”(而不是 GET 等),并附加了一个 XML 文件。

Fiddler 中的 Inspectors.Headers 显示:

POST /api/inventory/sendXML/su/su/blablee HTTP/1.1

尽管我认为这是一次小小的调试胜利,但我仍然不明白为什么会出现“400”错误。

Fiddler 在 Inspectors.WebView 窗格中告诉我:

Bad Request - Invalid Hostname

--------------------------------------------------------------------------------

HTTP Error 400. The request hostname is invalid.

这个怎么可能?当我从 Postman 运行它时,我在服务器中打断点 - 如果主机名无效,为什么会到达它?

更新 5

测试来自 Fiddler Composer 和 Postman 的调用,我可以到达服务器代码中的断点的唯一方法是使用“localhost” - 用 PC 的 IPAddress (192.168.125.50) 或 HostName (SHANON2) 替换它不会到达断点。虽然“有趣”,但从手持设备调用“localhost”显然不是一种选择。

更新 6

相关的新问题在这里

更新 7

饼干的关键是在命令提示符下添加以下内容:

netsh http add urlacl url=http://shannon2:80/ user=everyone

...或这个:

netsh http add urlacl url=http://shannon2:8080/ user=everyone

有关详细信息,请参阅此处的更新 5

4

2 回答 2

14

添加我的观察,如果您在从 Postman 调用 API 时遇到问题Bad Request - Invalid Hostname 。像这样的东西。

在此处输入图像描述

考虑在标头中添加主机,它将起作用。

在此处输入图像描述

在有人无法查看图像后更新:如果图像没有加载,那么基本上你必须这样做:

基本上,您必须添加Content-LengthHost。Postman 自动计算发送请求的时间。这些可以通过auto-generated headers在 Postman 中取消隐藏在 postman 中启用。或者你可以自己设置。

于 2021-03-09T06:15:41.937 回答
0

饼干的关键是在命令提示符下添加以下内容:

netsh http add urlacl url=http://shannon2:80/ user=everyone

...或这个:

netsh http add urlacl url=http://shannon2:8080/ user=everyone

有关详细信息,请参阅此处的更新 5

于 2015-09-09T20:09:17.400 回答