WebException(状态:协议错误)

3

我正在使用 WebClient 类在 C# 中调用一个 URL。以下是代码:

    public string SendWebRequest(string requestUrl)
    {
        using (var client = new WebClient())
        {
            string responseText = client.DownloadString(requestUrl);
            return responseText;
        } 
    }

这段代码出现了以下异常细节:-

System.Net.WebException: The remote server returned an error: (1201).
   at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request)
   at System.Net.WebClient.DownloadString(Uri address)
   at System.Net.WebClient.DownloadString(String address)

Exception Status: ProtocolError

URL已经成功地到达服务器。服务器上预期的操作(更新数据库)正常进行。服务器正确地发送响应。但是,WebClient未能处理响应。

我也尝试使用HttpWebRequest类,但没有成功。

最初,在请求时出现了类似的问题。当我按照以下方式修改了我的app.config后,问题得到了解决:

    <settings>
        <httpWebRequest useUnsafeHeaderParsing = "true"/>
    </settings>

我不能在这个论坛上发布URL,而且在网络外也无法访问。

如果我将相同的URL复制到浏览器地址栏中,它可以正常工作并返回预期的响应。

那么Windows应用程序可能有什么问题呢?

编辑1

我实现了答案中的建议。我还实现了接受答案中此问题的建议。现在,我的函数如下所示:-

    public string SendWebRequest(string requestUrl)
    {
        using (var client = new WebClient())
        {
            client.Headers.Add("Accept", "text/plain");
            client.Headers.Add("Accept-Language", "en-US");
            client.Headers.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
            client.Headers["Content-Type"] = "text/plain;charset=UTF-8";
            string responseText = client.DownloadString(requestUrl);
            return responseText;
        } 
    }

它仍然没有解决问题。现在响应是空字符串(""),而不是"Success"。这不是服务器的错误,已经确认。

如果我删除app.config中的配置,它会抛出其他异常。

System.Net.WebException: The server committed a protocol violation. Section=ResponseStatusLine
   at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request)
   at System.Net.WebClient.DownloadString(Uri address)
   at System.Net.WebClient.DownloadString(String address)

你需要发送适当的请求头(例如Accept),以及服务器可能需要的任何其他头部(例如User-Agent)。 - Matias Cicero
问题不在服务器上,而是客户端收到响应时无法解析它。在我看来,这是客户端的问题。 - Amit Joshi
2个回答

4

尝试更改您的Web客户端标头。似乎您的响应与标头类型不兼容。 我建议您向客户端添加一个Accept标头client.Headers.Add("Accept", "application/json");,假设您正在等待Json。


如果你要返回纯文本,则尝试使用以下代码:client.Headers.Add("Accept", "text/plain"); - Sameh Awad
@A_J 你能用Fiddler检查一下吗?也许问题出在你的Http响应上。如果你能在这里发布Fiddler看到的响应,可能会有所帮助。 - Sameh Awad
我不确定您从Fiddler中具体要求什么。请看以下是否有帮助;否则请让我知道。**响应字节(按Content-Type计算)-------------- :101 ???????:10 - Amit Joshi
来自 Fiddler 的响应头:-`HTTP/1.1 1201 服务器: Apache-Coyote/1.1 内容长度: 10 日期: Tue, 27 Sep 2016 11:10:23 GMT成功` - Amit Joshi
响应认证:未出现代理身份验证标头。未出现WWW-Authenticate标头。 - Amit Joshi
@A_J 如果你只是返回 SUCCESS,那么为什么 Content-Length 是 10 而不是 7?还要在 Fiddler 的响应头中检查 Content-Type 是否有与之一起发送的字符集。类似 Content-Type: text/plain; charset=UTF-8。 - Sameh Awad

4

您的服务器返回了HTTP 1201,这不是标准状态码

当遇到非成功状态码(或在您的情况下无法识别的状态码)时,WebClient将失败并引发异常。

如果可以,请使用新的HttpClient类:

public async Task<string> SendWebRequest(string requestUrl)
{
    using (HttpClient client = new HttpClient())
    using (HttpResponseMessage response = await client.GetAsync(requestUrl))
         return await response.Content.ReadAsStringAsync();
}

如果必须同步进行:

public string SendWebRequest(string requestUrl)
{
    using (HttpClient client = new HttpClient())
    using (HttpResponseMessage response = client.GetAsync(requestUrl).GetAwaiter().GetResult())
         return response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
}

我正在同步地进行这个操作。我遇到了以下异常:- mscorlib.dll 中的未处理类型为 System.ArgumentOutOfRangeException 的异常,位于 HttpResponseMessage response = client.GetAsync(requestUrl).GetAwaiter().GetResult() 行。 - Amit Joshi
@A_J 看起来是服务器的问题,不是客户端的问题。客户端代码没问题。 - Matias Cicero
HttpClient 销毁是不好的实践,请修复 @MatiasCicero - georgiosd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接