11

HttpWebRequestで、URIが2048文字を超えると、サーバーがその長さのURIでリクエストを完全に処理できるにもかかわらず、リクエストが失敗し、404エラーが返されるという問題が発生しました。HttpWebRequestを介して送信された場合にエラーを引き起こす同じURIは、ブラウザーのアドレスバーに直接貼り付けると正常に機能するため、これを知っています。

私の現在の回避策は、URIが長すぎる場合に、代わりにPOSTリクエストとしてパラメーターを送信しても安全であるとユーザーが互換性フラグを設定できるようにすることですが、使用しているプロトコルはRESTfulであるため、これは理想的ではありません。クエリにはGETを使用する必要があります。さらに、プロトコルの他の実装者がPOSTされたクエリを受け入れるという保証はありません

.Netに、使用できるURIの長さの制限を受けないHttpWebRequestと同等の機能を持つ別のクラスはありますか?
私はWebClientを知っていますが、WebClientが実行する機能を制限している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 .
  }

}

4

4 に答える 4

6

私が使用しているプロトコルはRESTfulであり、クエリにはGETを使用する必要があります。

POSTをクエリにも使用できない理由はありません。非常に長いURIはグローバルにサポートされておらず、サポートされたことがないため、非常に長いリクエストデータの場合は必要です。これは、HTTPがRESTの理想に沿っていない領域の1つです。

POSTが一般的にプレーンHTMLレベルで使用されない理由は、ブラウザがリロードを要求するのを停止し、たとえば、プロモートするためです。ブックマーク。ただし、HttpWebRequestの場合、これらの懸念はどちらもありません。そのため、先に進んでPOSTしてください。Webアプリケーションは、パラメーターまたはURIパス部分を使用して、要求メソッドだけでなく、書き込み要求とクエリを区別する必要があります。(もちろん、GETメソッドからの書き込み要求は引き続き拒否する必要があります。)

于 2009-10-19T10:20:24.437 に答える
3

HttpWebRequestは、実際には、あなたが話しているサイズのGETURLと互換性がないと思います。私はこれを2つのことに基づいて言います:

  1. 私自身の仕事では、HttpWebRequestを使用して、2048文字を超えるHTTPGETリクエストを問題なく送信しています。私の最長のキャラクターが何であるかはわかりませんが、10,000人以上のキャラクターを話しています。(これは主に、WebアプリケーションとTomcatで実行されているSolrのインスタンスの間です。)

  2. .NETにはGETURLの長さにいくつかの制限がありますが、私が知っているものは2048文字よりはるかに長いです。たとえば、今日、プロファイラーからWebRequest.Create(string url)がUriクラスコンストラクターを呼び出すことを学びました。これは、「uriStringの長さが65534文字を超える」場合にUriFormatExceptionをスローすることが文書化されています。

HttpWebRequest自体ではない場合、問題がどこにあるのかわかりません。WebサービスがHTTP404を返す(つまり「見つからない」)条件を知っていますか?(404は、.NETの奥深くに偽造されるのではなく、Webサービスからのものであると思います。)また、ブラウザーに貼り付けているアドレスが実際に同じアドレスであることを再確認したいと思います。 .NETによって送信されます。ferozeが示唆しているように、これにはネットワークスニッフィングツールを使用する必要があります。2つのアドレスが同じである場合は、次に、.NETの場合とブラウザの場合でHTTPヘッダーがどのように異なるかを比較します。(ちなみに、私は個人的に、これらの線に沿ったHTTPデバッグタスクのためにFiddlerがwiresharkよりも少し便利だと思っています。)

このやや関連性のある質問も参照してください。HttpWebRequestは、URLをアドレスバーに貼り付けることと(機能的に)どのように異なりますか?

于 2010-02-27T02:44:30.257 に答える
2

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!");

私のマシン(.Net 4.5を実行しているLINQPad)では、このスニペットは次のように出力します。

Error occurred at url length: 65520
System.UriFormatException: Invalid URI: The Uri string is too long.
于 2015-09-18T15:38:54.853 に答える
0

RFC3986によると、クエリ文字列が間違っています。'{'および'}'文字はURIで許可されていません。

于 2010-10-17T21:17:42.017 に答える