#URIの作成について
WebApiでURIにidを埋め込みたい場合に、id部分を+で連結するのを避ける方法を検討していた。
System.UriのベースURIと相対URIを設定すれば簡単にできると勘違いしていた。
例えば、"http://localhost:9999/api/5"とかの場合、以下の実装で問題ないはずだった。
var uri = new Uri(new Uri(@"http://localhost:9999/api"), "/5");
Debug.Print(uri.AbsoluteUri);
結果:"http://localhost:9999/5"
"/api"の部分が抜けている...
#仕様の確認
MSのドキュメント を読むと、ベースURIの末尾の"/"と相対URIの先頭に"/"があるかで動作が変わるとのこと。
このコンストラクターは、baseUri と relativeUriを組み合わせることによって、Uri インスタンスを作成します。 relativeUri が絶対 URI (スキーム、ホスト名、および必要に応じてポート番号を含む) の場合、Uri インスタンスは relativeUriのみを使用して作成されます。
baseUri に相対部分 (/apiなど) がある場合、baseUri の相対部分が構築された Uriに保持される場合は、相対部分をスラッシュ (/api/など) で終了する必要があります。
さらに、relativeUri がスラッシュで始まる場合は、baseUri の任意の相対部分に置き換えられます。
#動作確認
いくつかのパターンを試してみた。
// 1. http://localhost:9999/api/5
Debug.Print(new Uri(new Uri(@"http://localhost:9999/api/"), "5").AbsoluteUri);
// 2. http://localhost:9999/5
Debug.Print(new Uri(new Uri(@"http://localhost:9999/api"), "5").AbsoluteUri);
// 3. http://localhost:9999/5
Debug.Print(new Uri(new Uri(@"http://localhost:9999/api/"), "/5").AbsoluteUri);
// 4. http://localhost:9999/api/5
Debug.Print(new Uri(new Uri(@"http://localhost:9999/"), "/api/5").AbsoluteUri);
ベースURIと相対URIの定義次第だけど、4のようにすると、ベースURIの末尾"/"、相対URIの先頭"/"の有無は気にしなくて良くなる。
// 5. http://localhost:9999/api/5
Debug.Print(new Uri(new Uri(@"http://localhost:9999/"), "api/5").AbsoluteUri);
// 6. http://localhost:9999/api/5
Debug.Print(new Uri(new Uri(@"http://localhost:9999"), "/api/5").AbsoluteUri);
#まとめ
ベースURIの末尾に"/"がない場合、ベースURIに含まれる相対部分が相対URIに置き換わる。
ベースURIの先頭に"/"がある場合、ベースURIに含まれる相対部分が相対URIに置き換わる。
#補足
私のプロジェクトの場合、ベースURIと相対URIは詳細な形式は不明であり、末尾"/"、先頭"/"の不明はわからない状態だった。
結局、ベースURIの末尾"/"がなければ"/"を追加し、相対URIの先頭に"/"があれば削除してSystem.Uriクラスを使用したが、正直+連結で十分だった。