HttpWebRequest的长URI解决方法吗?(HttpWebRequest long URI

2019-08-20 06:39发布

我遇到HttpWebRequest的一个问题是,如果URI是超过2048个字符长的请求失败,并返回404错误,即使服务器是完全能够服务的URI,长期的请求。 我知道这是由于引起如果通过的HttpWebRequest提交错误相同的URI时,直接粘贴到浏览器地址栏工作正常。

我目前的解决办法是允许用户设置一个兼容性标志地说,它是安全的,作为一个POST请求发送参数,而不是在的情况下URI就太长了,但因为我使用的协议是REST风格,这是不理想和GET应该用于查询。 再加上没有机制保障,该协议的其他实现者将接受POST方法查询

有没有在.net另一个类具有同等功能的HttpWebRequest不从,我可以使用URI长度限制受苦?
我知道WebClient的,但我真的不希望使用它作为我需要能够完全控制其Web客户端限制有能力做的HTTP标头。

编辑

由于Shoban问它:

http://localhost/BBCDemo/sparql/?query=PREFIX+rdf%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0D%0APREFIX+rdfs%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0D%0APREFIX+xsd%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema%23%3E%0D%0APREFIX+skos%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23%3E%0D%0APREFIX+dc%3A+%3Chttp%3A%2F%2Fpurl.org%2Fdc%2Felements%2F1.1%2F%3E%0D%0APREFIX+po%3A+%3Chttp%3A%2F%2Fpurl.org%2Fontology%2Fpo%2F%3E%0D%0APREFIX+timeline%3A+%3Chttp%3A%2F%2Fpurl.org%2FNET%2Fc4dm%2Ftimeline.owl%23%3E%0D%0ASELECT+*+WHERE+{%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+dc%3Atitle+%3Ftitle+.%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Ashort_synopsis+%3Fsynopsis-short+.%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Amedium_synopsis+%3Fsynopsis-med+.%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Along_synopsis+%3Fsynopsis-long+.%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Amasterbrand+%3Fchannel+.%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Agenre+%3Fgenre+.%0D%0A++++%3Fchannel+dc%3Atitle+%3Fchanneltitle+.%0D%0A++++OPTIONAL+{%0D%0A++++++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Abrand+%3Fbrand+.%0D%0A++++++++%3Fbrand+dc%3Atitle+%3Fbrandtitle+.%0D%0A++++}%0D%0A++++OPTIONAL+{%0D%0A++++++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Aversion+%3Fver+.%0D%0A++++++++%3Fver+po%3Atime+%3Finterval+.%0D%0A++++++++%3Finterval+timeline%3Astart+%3Fstart+.%0D%0A++++++++%3Finterval+timeline%3Aend+%3Fend+.%0D%0A++++}%0D%0A}&default-graph-uri=&timeout=30000

这是下面的编码在查询字符串:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX po: <http://purl.org/ontology/po/>
PREFIX timeline: <http://purl.org/NET/c4dm/timeline.owl#>
SELECT * WHERE {
  <http://www.bbc.co.uk/programmes/b00n4d6y#programme> dc:title ?title .
  <http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:short_synopsis ?synopsis-short .
  <http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:medium_synopsis ?synopsis-med .
  <http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:long_synopsis ?synopsis-long .
  <http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:masterbrand ?channel .
  <http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:genre ?genre .
  ?channel dc:title ?channeltitle .
  OPTIONAL {
    <http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:brand ?brand .
    ?brand dc:title ?brandtitle .
  }
  OPTIONAL {
    <http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:version ?ver .
    ?ver po:time ?interval .
    ?interval timeline:start ?start .
    ?interval timeline:end ?end .
  }

}

Answer 1:

我使用的协议是REST风格和GET应该用于查询。

没有理由POST不能也可用于查询; 对于很长的请求数据,你必须这样做,因为超长的URI不是全局的支持,从来没有。 这是一个领域,HTTP不辜负REST理想。

究其原因POST一般不会在一个纯HTML级采用的是停止浏览器提示重载,推动如。 书签。 但对于HttpWebRequest的你没有任何的这些问题,所以,尽管它张贴。 Web应用程序应该使用一个参数或URI路径部分区分查询写请求,不只是请求方法。 (当然从GET方法的写入请求还是应该被拒绝。)



Answer 2:

我不认为HttpWebRequest的是与你谈论大小的GET网址居然不兼容。 我这样说是基于两点:

  1. 在我自己的工作中,我使用的HttpWebRequest发送HTTP GET超过2048个字符无故障请求更长的时间。 我不知道我什么时间最长的有,但我们谈论10000个字符。 (这主要是一个Web应用程序和Tomcat下运行的Solr的实例之间)。

  2. .NET确实有GET URL长度的一些限制,但我知道的那些较2048个字符高得多。 举例来说,我今天学到从我的分析器,WebRequest.Create(字符串URL)调用Uri类的构造函数 ,并有书面文件抛出UriFormatException如果“uriString中的长度超过65534个字符。”

我不知道您的问题可能是,如果它不是HttpWebRequest的本身。 你知道在什么情况下您的Web服务将返回HTTP 404(即“未找到”)? (我假设404是从您的Web服务的到来,而不是伪造.NET的深处里面。)我还需要仔细检查,你粘贴到浏览器的地址实际上是属该同一个由.NET发送; 作为费罗兹建议,你应该使用这个网络嗅探工具。 如果两个地址是相同的,那么也许下一个比较HTTP标头的.NET情况和浏览器之间的情况如何变化。 (顺便说一句,我个人觉得小提琴手比为Wireshark的沿着这些线路HTTP调试任务更加得心应手一点。)

又见这个有点相关的问题: 从pasteing一个网址到地址栏如何HttpWebRequest的不同(功能)?



Answer 3:

下面是它构造一个片段HttpWebRequest直到异常得到投掷实例有越来越大的URL值:

using System.Net;

...

StringBuilder url = new StringBuilder("http://example.com?p=");
try
{
    for (int i = 1; i < Int32.MaxValue; i++)
    {
        url.Append("0");
        HttpWebRequest request = HttpWebRequest.CreateHttp(url.ToString());
    }
}
catch (Exception ex)
{
    Console.Out.WriteLine("Error occurred at url length: " + url.Length);
    Console.Out.WriteLine(ex.GetType().ToString() + ": " + ex.Message);
    return;
}
Console.Out.WriteLine("Completed without error!");

在我的机器(在LINQPad运行.NET 4.5),这个片段输出:

Error occurred at url length: 65520
System.UriFormatException: Invalid URI: The Uri string is too long.


Answer 4:

您的查询字符串按照RFC3986是错误的。 “{”和“}”字符不以URI允许的。



文章来源: HttpWebRequest long URI workaround?