Flurl termasuk Url.Combinemetode yang melakukan hal itu.
Todd Menier
2
Sebenarnya, // ditangani oleh perutean situs web atau server dan bukan oleh peramban. Ini akan mengirim apa yang Anda masukkan ke bilah alamat. Itu sebabnya kami mendapat masalah saat kami mengetik htp: // alih-alih http: // Jadi // dapat menyebabkan masalah besar pada beberapa situs. Saya menulis .dll untuk perayap yang menangani situs web tertentu yang melempar 404 jika Anda memiliki // di url.
Url.Combine pada dasarnya adalah Path.Combine untuk URL, memastikan satu dan hanya satu karakter pemisah antara bagian:
var url =Url.Combine("http://MyUrl.com/","/too/","/many/","/slashes/","too","few?","x=1","y=2"// result: "http://www.MyUrl.com/too/many/slashes/too/few?x=1&y=2"
Nah, pertanyaan ini mendapat banyak lalu lintas, dan jawaban dengan 1000+ upvotes sebenarnya tidak berfungsi dalam semua kasus. Bertahun-tahun kemudian, saya benar-benar menggunakan Flurl untuk ini, jadi saya menerima yang ini. Tampaknya berfungsi dalam semua kasus yang saya temui. Jika orang tidak ingin mengambil ketergantungan, saya memposting jawaban yang juga berfungsi dengan baik.
Brian MacKay
dan jika Anda tidak menggunakan Flurldan akan membatalkan
lizzy91
1157
Uri memiliki konstruktor yang harus melakukan ini untuk Anda: new Uri(Uri baseUri, string relativeUri)
Ini sebuah contoh:
Uri baseUri =newUri("http://www.contoso.com");Uri myUri =newUri(baseUri,"catalog/shownew.htm");
Catatan dari editor: Hati-hati, metode ini tidak berfungsi seperti yang diharapkan. Itu dapat memotong bagian baseUri dalam beberapa kasus. Lihat komentar dan jawaban lain.
Saya suka menggunakan kelas Uri, sayangnya itu tidak akan berperilaku seperti Path.Combine seperti yang diminta OP. Misalnya Uri baru (Uri baru (" test.com/mydirectory/" ), "/helloworld.aspx"). ToString () memberi Anda " test.com/helloworld.aspx "; yang akan salah jika kita menginginkan hasil gaya Path.Combine.
Dokter Jones
195
Semuanya ada di garis miring. Jika bagian jalur relatif dimulai dengan garis miring, maka itu berperilaku seperti yang Anda jelaskan. Tetapi, jika Anda membiarkan slash out, maka itu berfungsi seperti yang Anda harapkan (perhatikan slash yang hilang pada parameter kedua): Uri baru (Uri baru (" test.com/mydirectory/" ), "helloworld.aspx" ) .ToString () menghasilkan " test.com/mydirectory/helloworld.aspx ". Path.Combine berperilaku sama. Jika parameter jalur relatif dimulai dengan garis miring, ia hanya mengembalikan jalur relatif dan tidak menggabungkannya.
Joel Beckham
70
Jika baseUri Anda adalah "test.com/mydirectory/mysubdirectory" maka hasilnya adalah "test.com/mydirectory/helloworld.aspx" alih-alih "test.com/mydirectory/mysubdirectory/helloworld.aspx". Perbedaan yang halus adalah kurangnya trailing slash pada parameter pertama. Saya semua menggunakan metode kerangka kerja yang ada, jika saya harus memiliki trailing slash di sana maka saya pikir melakukan partUrl1 + partUrl2 jauh lebih sedikit - saya bisa berpotensi mengejar trailing slash round cukup lama untuk Demi tidak melakukan string concat.
Carl
64
Satu-satunya alasan saya ingin metode gabungan URI adalah agar saya tidak perlu memeriksa slash tambahan. Request.ApplicationPath adalah '/' jika aplikasi Anda di root, tetapi '/ foo' jika tidak.
julukan
24
Saya -1 jawaban ini karena ini tidak menjawab masalah. Ketika Anda ingin menggabungkan url, seperti ketika Anda ingin menggunakan Path.Combine, Anda tidak ingin peduli dengan trailing /. dan dengan ini, kamu harus peduli. Saya lebih suka solusi dari Brian MacKay atau mdsharpe di atas
+1: Meskipun ini tidak menangani jalur relatif-gaya (../../wh whatever.html), saya suka yang ini karena kesederhanaannya. Saya juga akan menambahkan trim untuk karakter '\'.
Brian MacKay
3
Lihat jawaban saya untuk versi yang lebih lengkap dari ini.
Brian MacKay
149
Anda menggunakan Uri.TryCreate( ... ):
Uri result =null;if(Uri.TryCreate(newUri("http://msdn.microsoft.com/en-us/library/"),"/en-us/library/system.uri.trycreate.aspx",out result)){Console.WriteLine(result);}
+1: Ini bagus, meskipun saya memiliki masalah irasional dengan parameter output. ;)
Brian MacKay
10
@Brian: jika ini membantu, semua metode TryXXX ( int.TryParse, DateTime.TryParseExact) memiliki param output ini untuk membuatnya lebih mudah untuk menggunakannya dalam pernyataan-if. Btw, Anda tidak perlu menginisialisasi variabel seperti yang dilakukan Ryan dalam contoh ini.
Abel
41
Jawaban ini mengalami masalah yang sama dengan jawaban Joel : bergabung test.com/mydirectory/dan /helloworld.aspxakan menghasilkan test.com/helloworld.aspxyang tampaknya bukan yang Anda inginkan.
Matt Kocaj
3
Hai, ini gagal untuk mengikuti: if (Uri.TryCreate (Uri baru (" localhost / MyService /" ), "/ Event / SomeMethod? Abc = 123", hasil keluar)) {Console.WriteLine (hasil); } Ini menunjukkan kepada saya hasil sebagai: localhost / Event / SomeMethod? Abc = 123 Catatan: "http: //" diganti dari basis Uri di sini oleh stackoverflow
Faisal Mq
3
@FaisalMq Ini adalah perilaku yang benar, karena Anda melewati parameter kedua relatif-root. Jika Anda mengabaikan parameter leading / pada parameter kedua, Anda akan mendapatkan hasil yang Anda harapkan.
Tom Lint
127
Sudah ada beberapa jawaban bagus di sini. Berdasarkan saran mdsharpe, berikut ini adalah metode ekstensi yang dapat dengan mudah digunakan ketika Anda ingin berurusan dengan instance Uri:
using System;
using System.Linq;publicstaticclassUriExtensions{publicstaticUriAppend(thisUri uri,paramsstring[] paths){returnnewUri(paths.Aggregate(uri.AbsoluteUri,(current, path)=>string.Format("{0}/{1}", current.TrimEnd('/'), path.TrimStart('/'))));}}
Dan contoh penggunaan:
var url =newUri("http://example.com/subpath/").Append("/part1/","part2").AbsoluteUri;
Solusi ini membuatnya sepele untuk menulis UriUtils.Combine ("base url", "part1", "part2", ...) metode statis yang sangat mirip dengan Path.Combine (). Bagus!
angularsen
Untuk mendukung URI relatif, saya harus menggunakan ToString () alih-alih AbsoluteUri dan UriKind.AbsoluteOrRelative dalam konstruktor Uri.
angularsen
Terima kasih atas tip tentang Uris relatif. Sayangnya Uri tidak membuatnya mudah untuk berurusan dengan jalur relatif karena selalu ada beberapa mucking tentang dengan Request.ApplicationPath terlibat. Mungkin Anda juga bisa mencoba menggunakan Uri baru (HttpContext.Current.Request.ApplicationPath) sebagai basis dan cukup panggil Tambahkan di atasnya? Ini akan memberi Anda jalur absolut tetapi harus bekerja di mana saja dalam struktur situs.
Ales Potocnik Hahonina
Bagus. Senang itu membantu orang lain. Sudah menggunakan ini untuk beberapa waktu sekarang dan belum memiliki masalah.
Ales Potocnik Hahonina
Saya juga menambahkan memeriksa apakah ada jalan untuk menambahkan bukan null atau string kosong.
n.podbielski
92
Jawaban Ryan Cook dekat dengan apa yang saya cari dan mungkin lebih cocok untuk pengembang lain. Namun, ia menambahkan http: // ke awal string dan secara umum ia melakukan sedikit lebih banyak format daripada yang saya kejar.
Juga, untuk kasus penggunaan saya, menyelesaikan jalur relatif tidak penting.
Jawaban mdsharp juga mengandung benih ide yang bagus, meskipun implementasi aktual membutuhkan beberapa detail lagi untuk lengkap. Ini adalah upaya untuk menyempurnakannya (dan saya menggunakan ini dalam produksi):
Berbicara tentang perincian: bagaimana dengan wajib ArgumentNullException("url1")jika argumennya Nothing? Maaf, hanya pilih-pilih ;-). Perhatikan bahwa backslash tidak ada hubungannya di URI (dan jika ada, tidak boleh dipangkas), sehingga Anda dapat menghapusnya dari TrimXXX Anda.
Abel
4
Anda dapat menggunakan string params [] dan bergabung secara rekursif untuk memungkinkan lebih dari 2 kombinasi
Jaider
4
Saya yakin berharap ini ada di Perpustakaan Kelas Dasar seperti Path.Combine.
Uriah Blatherwick
1
@ MarkHurd saya mengedit kode lagi, sehingga secara perilaku sama dengan C #, dan secara sintaksis juga sama.
JJS
1
@BrianMacKay saya memecahkannya, markhurd menunjukkan kesalahan saya dan memutar kembali, saya memperbarui lagi ... tepuk tangan
JJS
36
Path.Combine tidak berfungsi untuk saya karena mungkin ada karakter seperti "|" dalam argumen QueryString dan karenanya URL, yang akan menghasilkan ArgumentException.
Saya pertama kali mencoba Uri(Uri baseUri, string relativeUri)pendekatan baru , yang gagal bagi saya karena URI seperti http://www.mediawiki.org/wiki/Special:SpecialPages:
akan menghasilkan Special: SpecialPages, karena titik dua setelah Specialitu menunjukkan skema.
Jadi saya akhirnya harus mengambil rute mdsharpe / Brian MacKays dan mengembangkannya sedikit lebih jauh untuk bekerja dengan beberapa bagian URI:
publicstaticstringCombineUri(paramsstring[] uriParts){string uri =string.Empty;if(uriParts !=null&& uriParts.Length>0){char[] trims =newchar[]{'\\','/'};
uri =(uriParts[0]??string.Empty).TrimEnd(trims);for(int i =1; i < uriParts.Length; i++){
uri =string.Format("{0}/{1}", uri.TrimEnd(trims),(uriParts[i]??string.Empty).TrimStart(trims));}}return uri;}
+1: Sekarang kita berbicara ... Saya akan mencoba ini. Ini bahkan mungkin berakhir dengan jawaban yang baru diterima. Setelah mencoba metode Uri () baru, saya benar-benar tidak menyukainya. Terlalu licik.
Brian MacKay
Inilah yang saya butuhkan! Bukan penggemar harus peduli di mana saya meletakkan garis miring, dll ...
Gromer
+1 untuk bergulir di pemeriksaan nol agar tidak meledak.
NightOwl888
Count () harus Panjang sehingga Anda tidak perlu menyertakan Linq di perpustakaan Anda hanya untuk itu.
PRMan
Ini persis apa yang saya cari.
ThePeter
34
Berdasarkan pada URL contoh Anda berikan, saya akan menganggap Anda ingin menggabungkan URL yang relatif dengan situs Anda.
Berdasarkan asumsi ini saya akan mengusulkan solusi ini sebagai jawaban yang paling tepat untuk pertanyaan Anda yaitu: "Path.Combine berguna, apakah ada fungsi yang sama dalam kerangka kerja untuk URL?"
Karena ada fungsi serupa dalam kerangka kerja untuk URL yang saya usulkan yang benar adalah: "VirtualPathUtility.Combine" metode. Berikut tautan referensi MSDN: Metode VirtualPathUtility.Combine
Ada satu peringatan: Saya percaya ini hanya berfungsi untuk URL relatif ke situs Anda (yaitu, Anda tidak dapat menggunakannya untuk menghasilkan tautan ke situs web lain. Misalnya, var url = VirtualPathUtility.Combine("www.google.com", "accounts/widgets");).
Memberi +1 karena dekat dengan apa yang saya cari, meskipun itu akan ideal jika itu akan berfungsi untuk url lama apa pun. Saya menggandakannya akan mendapatkan jauh lebih elegan dari apa yang diusulkan mdsharpe.
Brian MacKay
2
Peringatan itu benar, tidak dapat bekerja dengan uris absolut dan hasilnya selalu relatif dari akar. Tetapi memiliki manfaat tambahan, memproses tilde, seperti dengan "~ /". Ini membuatnya menjadi jalan pintas untuk Server.MapPathdan menggabungkan.
Untuk mendapatkannya, Anda harus menghapus argumen pertama / dalam kedua yaitu "/ Gambar" - / Path.Combine (" Http://MyUrl.com ", "Images / Image.jpg")
Per G
8
@SliverNinja Itu tidak benar Nilai bidang ini adalah garis miring terbalik ('\') pada UNIX, dan garis miring ('/') pada sistem operasi Windows dan Macintosh. Saat menggunakan Mono di sistem Linux, Anda akan mendapatkan separator yang salah.
user247702
6
Semua kalian yang geeking di Pemisah Direktori lupa bahwa string bisa berasal dari OS yang berbeda dari yang ada sekarang. Cukup ganti backslash dengan garis miring dan Anda tertutup.
Contoh cerdas, Ryan, untuk mengakhiri dengan tautan ke fungsi. Sudah selesai dilakukan dengan baik.
Satu rekomendasi Brian: jika Anda membungkus kode ini dalam suatu fungsi, Anda mungkin ingin menggunakan UriBuilder untuk membungkus URL dasar sebelum panggilan TryCreate.
Jika tidak, URL dasar HARUS menyertakan skema (di mana UriBuilder akan menganggap http: //). Hanya pemikiran saja:
+1, meskipun ini sangat mirip dengan jawaban mdsharpe, yang saya tingkatkan dalam jawaban saya. Versi ini berfungsi dengan baik kecuali Url2 dimulai dengan / atau \, atau Url1 secara tidak sengaja berakhir pada \, atau salah satunya kosong! :)
Brian MacKay
9
Menggabungkan beberapa bagian dari URL bisa sedikit rumit. Anda dapat menggunakan konstruktor dua parameter Uri(baseUri, relativeUri), atau Anda dapat menggunakan Uri.TryCreate()fungsi utilitas.
Dalam kedua kasus, Anda mungkin berakhir kembali hasil yang salah karena metode ini terus truncating bagian relatif off dari parameter pertama baseUri, yaitu dari sesuatu seperti http://google.com/some/thinguntuk http://google.com.
Agar dapat menggabungkan beberapa bagian menjadi URL akhir, Anda dapat menyalin dua fungsi di bawah ini:
publicstaticstringCombine(paramsstring[] parts){if(parts ==null|| parts.Length==0)returnstring.Empty;var urlBuilder =newStringBuilder();foreach(var part in parts){var tempUrl = tryCreateRelativeOrAbsolute(part);
urlBuilder.Append(tempUrl);}returnVirtualPathUtility.RemoveTrailingSlash(urlBuilder.ToString());}privatestaticstring tryCreateRelativeOrAbsolute(string s){System.Uri uri;System.Uri.TryCreate(s,UriKind.RelativeOrAbsolute,out uri);string tempUrl =VirtualPathUtility.AppendTrailingSlash(uri.ToString());return tempUrl;}
Terlihat bagus untukku. Meskipun Anda bisa mengganti I loop dengan loop foreach untuk kejelasan yang lebih baik.
Chris Marisic
Terimakasih Chris. Saya baru saja mengubah kode saya untuk menggunakan Foreach.
Believe2014
1
+1 untuk semua upaya ekstra. Saya perlu mempertahankan pertanyaan ini sedikit untuk beberapa jawaban yang lebih tinggi, Anda telah melemparkan tantangan. ;)
Brian MacKay
Maaf, tapi tidak cukup. Berfungsi dalam beberapa kasus yang Anda tunjukkan tetapi tidak dapat digunakan dalam kombinasi al. Misalnya, titik dua di jalan akan menyebabkan kerusakan.
Gábor
Bisakah Anda memberi contoh tentang apa yang Anda maksud? Saya akan dengan senang hati memperbaiki masalah ini dan membantu pengguna berikutnya.
Believe2014
7
Saya menemukan UriBuilderbekerja dengan sangat baik untuk hal semacam ini:
@BrianMacKay Setuju bahwa itu terlihat seperti itu, tetapi berasal dari kelas UrlUtility dan digunakan dalam konteks menggabungkan URL
2
Diedit untuk memperjelas kelasnya
Hati-hati saat menggunakan Kelas ini, seluruh kelas berisi artefak khusus SharePoint.
Harry Berry
4
Saya menemukan hal-hal berikut yang bermanfaat dan memiliki fitur-fitur berikut:
Membuang ruang nol atau putih
Mengambil beberapa paramsparameter untuk beberapa segmen Url
melempar pada nol atau kosong
Kelas
publicstaticclassUrlPath{privatestaticstringInternalCombine(string source,string dest){if(string.IsNullOrWhiteSpace(source))thrownewArgumentException("Cannot be null or white space", nameof(source));if(string.IsNullOrWhiteSpace(dest))thrownewArgumentException("Cannot be null or white space", nameof(dest));return $"{source.TrimEnd('/', '\\')}/{dest.TrimStart('/', '\\')}";}publicstaticstringCombine(string source,paramsstring[] args)=> args.Aggregate(source,InternalCombine);}
Tes
UrlPath.Combine("test1","test2");UrlPath.Combine("test1//","test2");UrlPath.Combine("test1","/test2");// Result = test1/test2UrlPath.Combine(@"test1\/\/\/",@"\/\/\\\\\//test2",@"\/\/\\\\\//test3\");// Result = test1/test2/test3UrlPath.Combine("/test1/","/test2/",null);UrlPath.Combine("","/test2/");UrlPath.Combine("/test1/",null);// Throws an ArgumentException
Beberapa masalah dengan tes: // Hasil = test1 / test2 / test3 \ untuk yang ke-4 dan yang terakhir dari tes melempar memberikan ArgumentNullException bukannya ArgumentException
Moriya
3
Solusi umum saya:
publicstaticstringCombine(paramsstring[] uriParts){string uri =string.Empty;if(uriParts !=null&& uriParts.Any()){char[] trims =newchar[]{'\\','/'};
uri =(uriParts[0]??string.Empty).TrimEnd(trims);for(int i =1; i < uriParts.Length; i++){
uri =string.Format("{0}/{1}", uri.TrimEnd(trims),(uriParts[i]??string.Empty).TrimStart(trims));}}return uri;}
Metode pembantu ini sangat fleksibel dan bekerja dengan baik dalam banyak kasus penggunaan yang berbeda. Terima kasih!
Shiva
3
Saya membuat fungsi ini yang akan membuat hidup Anda lebih mudah:
/// <summary>/// The ultimate Path combiner of all time/// </summary>/// <param name="IsURL">/// true - if the paths are Internet URLs, false - if the paths are local URLs, this is very important as this will be used to decide which separator will be used./// </param>/// <param name="IsRelative">Just adds the separator at the beginning</param>/// <param name="IsFixInternal">Fix the paths from within (by removing duplicate separators and correcting the separators)</param>/// <param name="parts">The paths to combine</param>/// <returns>the combined path</returns>publicstaticstringPathCombine(boolIsURL,boolIsRelative,boolIsFixInternal,paramsstring[] parts){if(parts ==null|| parts.Length==0)returnstring.Empty;char separator =IsURL?'/':'\\';if(parts.Length==1&&IsFixInternal){string validsingle;if(IsURL){
validsingle = parts[0].Replace('\\','/');}else{
validsingle = parts[0].Replace('/','\\');}
validsingle = validsingle.Trim(separator);return(IsRelative? separator.ToString():string.Empty)+ validsingle;}string final = parts
.Aggregate((string first ,string second)=>{string validfirst;string validsecond;if(IsURL){
validfirst = first.Replace('\\','/');
validsecond = second.Replace('\\','/');}else{
validfirst = first.Replace('/','\\');
validsecond = second.Replace('/','\\');}var prefix =string.Empty;if(IsFixInternal){if(IsURL){if(validfirst.Contains("://")){var tofix = validfirst.Substring(validfirst.IndexOf("://")+3);
prefix = validfirst.Replace(tofix ,string.Empty).TrimStart(separator);var tofixlist = tofix.Split(new[]{ separator },StringSplitOptions.RemoveEmptyEntries);
validfirst = separator +string.Join(separator.ToString(), tofixlist);}else{var firstlist = validfirst.Split(new[]{ separator },StringSplitOptions.RemoveEmptyEntries);
validfirst =string.Join(separator.ToString(), firstlist);}var secondlist = validsecond.Split(new[]{ separator },StringSplitOptions.RemoveEmptyEntries);
validsecond =string.Join(separator.ToString(), secondlist);}else{var firstlist = validfirst.Split(new[]{ separator },StringSplitOptions.RemoveEmptyEntries);var secondlist = validsecond.Split(new[]{ separator },StringSplitOptions.RemoveEmptyEntries);
validfirst =string.Join(separator.ToString(), firstlist);
validsecond =string.Join(separator.ToString(), secondlist);}}return prefix + validfirst.Trim(separator)+ separator + validsecond.Trim(separator);});return(IsRelative? separator.ToString():string.Empty)+ final;}
Saya sedang mencari versi PowerShell ini yang akan menjadi: [System.IO.Path]::Combine("http://MyUrl.com/","/Images/Image.jpg")namun ini gagal dengan hasil: /Images/Image.jpg. Hapus /dari subPath kedua dan berfungsi:[System.IO.Path]::Combine("http://MyUrl.com/","Images/Image.jpg")
Underverse
Ide bagus, tetapi gagal, ketika salah satu parameternya nol.
pholpar
2
Aturan saat menggabungkan URL dengan URI
Untuk menghindari perilaku aneh ada satu aturan yang harus diikuti:
Path (direktori) harus diakhiri dengan '/'. Jika path berakhir tanpa '/', bagian terakhir diperlakukan seperti nama file, dan itu akan disatukan ketika mencoba untuk menggabungkan dengan bagian URL berikutnya.
Ada satu pengecualian: alamat URL dasar (tanpa info direktori) tidak perlu diakhiri dengan '/'
bagian jalur tidak boleh dimulai dengan '/'. Jika dimulai dengan '/', setiap informasi relatif yang ada dari URL dihapus ... menambahkan string.Emptyjalur bagian juga akan menghapus direktori relatif dari URL!
Jika Anda mengikuti aturan di atas, Anda dapat menggabungkan URL dengan kode di bawah ini. Bergantung pada situasi Anda, Anda dapat menambahkan beberapa bagian 'direktori' ke URL ...
Jika Anda tidak ingin menambahkan ketergantungan pihak ketiga seperti Flurl atau membuat metode ekstensi kustom, di ASP.NET Core (juga tersedia di Microsoft.Owin), Anda dapat menggunakan PathStringyang dimaksudkan untuk tujuan membangun URI jalan. Anda kemudian dapat membuat URI lengkap menggunakan kombinasi ini, Uridan UriBuilder.
Ini memberi Anda semua bagian konstituen tanpa harus menentukan pemisah di URL dasar. Sayangnya, PathStringmengharuskan yang /diawali dengan masing-masing string kalau tidak itu sebenarnya melempar ArgumentException! Tetapi setidaknya Anda dapat membangun URI Anda secara deterministik dengan cara yang mudah diuji unit.
Hati-hati: Solusi ini menurunkan host dan menambahkan port. Jika ini tidak diinginkan, seseorang dapat menulis representasi string dengan misalnya memanfaatkan UriProperti UriBuilder.
Tentu saja solusi ini cukup menggambarkan diri (setidaknya menurut saya). Tetapi Anda mengandalkan "fitur" tidak berdokumen (setidaknya saya tidak menemukan apa-apa dengan pencarian google cepat) dari. NET API. Ini dapat berubah dengan rilis di masa mendatang jadi harap tutupi Metode dengan Tes.
Ini adalah pendekatan yang sangat andal. Acungan jempol untuk unit test !!
aggsol
2
Bagi siapa saja yang mencari satu-liner dan hanya ingin bergabung dengan bagian dari jalan tanpa membuat metode baru atau referensi perpustakaan baru atau membangun nilai URI dan mengonversinya menjadi string, maka ...
Ini cukup mendasar, tetapi saya tidak melihat apa lagi yang Anda butuhkan. Jika Anda takut dua kali lipat '/' maka Anda bisa melakukan .Replace("//", "/")sesudahnya. Jika Anda takut mengganti '//' yang dilipatgandakan dalam 'https: //', alih-alih lakukan satu bergabung, ganti '/' yang digandakan, kemudian bergabunglah dengan url situs web (namun saya cukup yakin sebagian besar browser akan secara otomatis konversikan apa pun dengan 'https:' di depannya untuk membaca dalam format yang benar). Ini akan terlihat seperti:
Ada banyak jawaban di sini yang akan menangani semua hal di atas, tetapi dalam kasus saya, saya hanya membutuhkannya sekali di satu lokasi dan tidak perlu terlalu bergantung padanya. Juga, sangat mudah untuk melihat apa yang sedang terjadi di sini.
Inilah pendekatan saya dan saya akan menggunakannya untuk diri saya juga:
publicstaticstringUrlCombine(string part1,string part2){string newPart1 =string.Empty;string newPart2 =string.Empty;string seperator ="/";// If either part1 or part 2 is empty,// we don't need to combine with seperatorif(string.IsNullOrEmpty(part1)||string.IsNullOrEmpty(part2)){
seperator =string.Empty;}// If part1 is not empty,// remove '/' at lastif(!string.IsNullOrEmpty(part1)){
newPart1 = part1.TrimEnd('/');}// If part2 is not empty,// remove '/' at firstif(!string.IsNullOrEmpty(part2)){
newPart2 = part2.TrimStart('/');}// Now finally combinereturnstring.Format("{0}{1}{2}", newPart1, seperator, newPart2);}
Ini hanya dapat diterima untuk kasus Anda. Ada beberapa kasus yang dapat merusak kode Anda. Juga, Anda tidak melakukan pengkodean yang benar dari bagian-bagian jalan. Ini bisa menjadi kerentanan besar ketika datang ke serangan scripting lintas situs.
Believe2014
Saya setuju dengan poin Anda. Kode seharusnya melakukan penggabungan sederhana dari dua bagian url.
Sentuhan yang bagus dengan 'WebPath'. :) Kode mungkin padat tapi tidak perlu - sulit bagi saya untuk melirik ini dan berkata, ya, itu sempurna. Itu membuat saya ingin melihat unit test. Mungkin itu hanya aku!
Brian MacKay
1
x.StartsWith ("/") &&! x.StartsWith ("http") - mengapa http memeriksa? apa yang kamu dapatkan?
penguat
Anda tidak ingin mencoba menghapus garis miring jika dimulai dengan http.
Martin Murphy
@BrianMacKay, saya tidak yakin dua liner menjamin tes unit tetapi jika Anda ingin merasa bebas untuk memberikan satu. Ini tidak seperti saya menerima tambalan atau apa pun, tetapi merasa bebas untuk mengedit saran.
Martin Murphy
1
Saya menemukan bahwa Urikonstruktor membalik '\' ke '/'. Jadi Anda juga bisa menggunakan Path.Combine, dengan Urikonstruktor.
Uri baseUri =newUri("http://MyUrl.com");string path =Path.Combine("Images","Image.jpg");Uri myUri =newUri(baseUri, path);
Seperti yang ditemukan di jawaban lain, baik yang baru Uri()atau TryCreate()dapat melakukan centang. Namun, basis Uri harus diakhiri dengan /dan relatif harus TIDAK mulai dengan /; jika tidak, ia akan menghapus bagian akhir dari Url dasar
Saya pikir ini paling baik dilakukan sebagai metode ekstensi, yaitu
var baseUri =newUri("http://test.com/test/");var combinedUri = baseUri.Append("/Do/Something");
Dalam hal kinerja, ini menghabiskan lebih banyak sumber daya daripada yang dibutuhkan, karena kelas Uri yang melakukan banyak parsing dan validasi; profil yang sangat kasar (Debug) melakukan sejuta operasi dalam waktu sekitar 2 detik. Ini akan berfungsi untuk sebagian besar skenario, namun agar lebih efisien, lebih baik memanipulasi segala sesuatu sebagai string, ini membutuhkan 125 milidetik untuk 1 juta operasi. Yaitu
publicstaticstringAppend(thisUri uri,string relativePath){//avoid the use of Uri as it's not needed, and adds a bit of overhead.var absoluteUri = uri.AbsoluteUri;//a calculated property, better cache itvar baseUri = absoluteUri.EndsWith('/')? absoluteUri : absoluteUri +'/';var relative = relativePath.StartsWith('/')? relativePath.Substring(1): relativePath;return baseUri + relative;}
Dan jika Anda masih ingin mengembalikan URI, dibutuhkan sekitar 600 milidetik untuk 1 juta operasi.
publicstaticUriAppendUri(thisUri uri,string relativePath){//avoid the use of Uri as it's not needed, and adds a bit of overhead.var absoluteUri = uri.AbsoluteUri;//a calculated property, better cache itvar baseUri = absoluteUri.EndsWith('/')? absoluteUri : absoluteUri +'/';var relative = relativePath.StartsWith('/')? relativePath.Substring(1): relativePath;returnnewUri(baseUri + relative);}
Url.Combine
metode yang melakukan hal itu.Jawaban:
Ada komentar Todd Menier di atas bahwa Flurl termasuk a
Url.Combine
.Keterangan lebih lanjut:
Dapatkan Flurl.Http di NuGet :
PM> Instal-Paket Flurl.Http
Atau dapatkan pembuat URL yang berdiri sendiri tanpa fitur HTTP:
PM> Paket Instalasi Flurl
sumber
Flurl
dan akan membatalkanUri
memiliki konstruktor yang harus melakukan ini untuk Anda:new Uri(Uri baseUri, string relativeUri)
Ini sebuah contoh:
Catatan dari editor: Hati-hati, metode ini tidak berfungsi seperti yang diharapkan. Itu dapat memotong bagian baseUri dalam beberapa kasus. Lihat komentar dan jawaban lain.
sumber
Ini mungkin solusi sederhana yang sesuai:
sumber
Anda menggunakan
Uri.TryCreate( ... )
:Akan kembali:
sumber
int.TryParse
,DateTime.TryParseExact
) memiliki param output ini untuk membuatnya lebih mudah untuk menggunakannya dalam pernyataan-if. Btw, Anda tidak perlu menginisialisasi variabel seperti yang dilakukan Ryan dalam contoh ini.test.com/mydirectory/
dan/helloworld.aspx
akan menghasilkantest.com/helloworld.aspx
yang tampaknya bukan yang Anda inginkan.Sudah ada beberapa jawaban bagus di sini. Berdasarkan saran mdsharpe, berikut ini adalah metode ekstensi yang dapat dengan mudah digunakan ketika Anda ingin berurusan dengan instance Uri:
Dan contoh penggunaan:
Ini akan menghasilkan http://example.com/subpath/part1/part2
sumber
Jawaban Ryan Cook dekat dengan apa yang saya cari dan mungkin lebih cocok untuk pengembang lain. Namun, ia menambahkan http: // ke awal string dan secara umum ia melakukan sedikit lebih banyak format daripada yang saya kejar.
Juga, untuk kasus penggunaan saya, menyelesaikan jalur relatif tidak penting.
Jawaban mdsharp juga mengandung benih ide yang bagus, meskipun implementasi aktual membutuhkan beberapa detail lagi untuk lengkap. Ini adalah upaya untuk menyempurnakannya (dan saya menggunakan ini dalam produksi):
C #
VB.NET
Kode ini lolos tes berikut, yang kebetulan berada di VB:
sumber
ArgumentNullException("url1")
jika argumennyaNothing
? Maaf, hanya pilih-pilih ;-). Perhatikan bahwa backslash tidak ada hubungannya di URI (dan jika ada, tidak boleh dipangkas), sehingga Anda dapat menghapusnya dari TrimXXX Anda.Path.Combine tidak berfungsi untuk saya karena mungkin ada karakter seperti "|" dalam argumen QueryString dan karenanya URL, yang akan menghasilkan ArgumentException.
Saya pertama kali mencoba
Uri(Uri baseUri, string relativeUri)
pendekatan baru , yang gagal bagi saya karena URI sepertihttp://www.mediawiki.org/wiki/Special:SpecialPages
:akan menghasilkan Special: SpecialPages, karena titik dua setelah
Special
itu menunjukkan skema.Jadi saya akhirnya harus mengambil rute mdsharpe / Brian MacKays dan mengembangkannya sedikit lebih jauh untuk bekerja dengan beberapa bagian URI:
Pemakaian:
CombineUri("http://www.mediawiki.org/", "wiki", "Special:SpecialPages")
sumber
Berdasarkan pada URL contoh Anda berikan, saya akan menganggap Anda ingin menggabungkan URL yang relatif dengan situs Anda.
Berdasarkan asumsi ini saya akan mengusulkan solusi ini sebagai jawaban yang paling tepat untuk pertanyaan Anda yaitu: "Path.Combine berguna, apakah ada fungsi yang sama dalam kerangka kerja untuk URL?"
Karena ada fungsi serupa dalam kerangka kerja untuk URL yang saya usulkan yang benar adalah: "VirtualPathUtility.Combine" metode. Berikut tautan referensi MSDN: Metode VirtualPathUtility.Combine
Ada satu peringatan: Saya percaya ini hanya berfungsi untuk URL relatif ke situs Anda (yaitu, Anda tidak dapat menggunakannya untuk menghasilkan tautan ke situs web lain. Misalnya,
var url = VirtualPathUtility.Combine("www.google.com", "accounts/widgets");
).sumber
Server.MapPath
dan menggabungkan.sumber
path.Replace(Path.DirectorySeparatorChar, '/');
path.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
Saya hanya mengumpulkan metode ekstensi kecil:
Dapat digunakan seperti ini:
sumber
Contoh cerdas, Ryan, untuk mengakhiri dengan tautan ke fungsi. Sudah selesai dilakukan dengan baik.
Satu rekomendasi Brian: jika Anda membungkus kode ini dalam suatu fungsi, Anda mungkin ingin menggunakan UriBuilder untuk membungkus URL dasar sebelum panggilan TryCreate.
Jika tidak, URL dasar HARUS menyertakan skema (di mana UriBuilder akan menganggap http: //). Hanya pemikiran saja:
sumber
Cara mudah untuk menggabungkannya dan memastikan selalu benar adalah:
sumber
Menggabungkan beberapa bagian dari URL bisa sedikit rumit. Anda dapat menggunakan konstruktor dua parameter
Uri(baseUri, relativeUri)
, atau Anda dapat menggunakanUri.TryCreate()
fungsi utilitas.Dalam kedua kasus, Anda mungkin berakhir kembali hasil yang salah karena metode ini terus truncating bagian relatif off dari parameter pertama
baseUri
, yaitu dari sesuatu sepertihttp://google.com/some/thing
untukhttp://google.com
.Agar dapat menggabungkan beberapa bagian menjadi URL akhir, Anda dapat menyalin dua fungsi di bawah ini:
Kode lengkap dengan tes unit untuk menunjukkan penggunaan dapat ditemukan di https://uricombine.codeplex.com/SourceControl/latest#UriCombine/Uri.cs
Saya memiliki unit test untuk mencakup tiga kasus paling umum:
sumber
Saya menemukan
UriBuilder
bekerja dengan sangat baik untuk hal semacam ini:Lihat Kelas UriBuilder - MSDN untuk lebih banyak konstruktor dan dokumentasi.
sumber
Berikut ini UrlUtility.Combine metode Microsoft (OfficeDev PnP) :
Sumber: GitHub
sumber
Saya menemukan hal-hal berikut yang bermanfaat dan memiliki fitur-fitur berikut:
params
parameter untuk beberapa segmen UrlKelas
Tes
sumber
Solusi umum saya:
sumber
Saya membuat fungsi ini yang akan membuat hidup Anda lebih mudah:
Ini berfungsi untuk URL dan juga jalur normal.
Pemakaian:
sumber
Mengapa tidak menggunakan saja yang berikut ini.
sumber
[System.IO.Path]::Combine("http://MyUrl.com/","/Images/Image.jpg")
namun ini gagal dengan hasil:/Images/Image.jpg
. Hapus/
dari subPath kedua dan berfungsi:[System.IO.Path]::Combine("http://MyUrl.com/","Images/Image.jpg")
Aturan saat menggabungkan URL dengan URI
Untuk menghindari perilaku aneh ada satu aturan yang harus diikuti:
string.Empty
jalur bagian juga akan menghapus direktori relatif dari URL!Jika Anda mengikuti aturan di atas, Anda dapat menggabungkan URL dengan kode di bawah ini. Bergantung pada situasi Anda, Anda dapat menambahkan beberapa bagian 'direktori' ke URL ...
sumber
Jika Anda tidak ingin menambahkan ketergantungan pihak ketiga seperti Flurl atau membuat metode ekstensi kustom, di ASP.NET Core (juga tersedia di Microsoft.Owin), Anda dapat menggunakan
PathString
yang dimaksudkan untuk tujuan membangun URI jalan. Anda kemudian dapat membuat URI lengkap menggunakan kombinasi ini,Uri
danUriBuilder
.Dalam hal ini, itu akan menjadi:
Ini memberi Anda semua bagian konstituen tanpa harus menentukan pemisah di URL dasar. Sayangnya,
PathString
mengharuskan yang/
diawali dengan masing-masing string kalau tidak itu sebenarnya melemparArgumentException
! Tetapi setidaknya Anda dapat membangun URI Anda secara deterministik dengan cara yang mudah diuji unit.sumber
Jadi saya punya pendekatan lain, mirip dengan semua orang yang menggunakan UriBuilder.
Saya tidak ingin membagi BaseUrl saya (yang dapat berisi bagian dari jalan - misalnya http://mybaseurl.com/dev/ ) seperti yang dilakukan javajavajavajavajavajava .
Cuplikan berikut menunjukkan kode + Tes.
Hati-hati: Solusi ini menurunkan host dan menambahkan port. Jika ini tidak diinginkan, seseorang dapat menulis representasi string dengan misalnya memanfaatkan
Uri
PropertiUriBuilder
.Diuji dengan .NET Core 2.1 pada Windows 10.
Mengapa ini bekerja?
Meskipun
Path.Combine
akan mengembalikan garis miring terbalik (pada Windows minimal), UriBuilder menangani kasus ini di Setter ofPath
.Diambil dari https://github.com/dotnet/corefx/blob/master/src/System.Private.Uri/src/System/UriBuilder.cs (ingat panggilan untuk
string.Replace
)Apakah ini pendekatan terbaik?
Tentu saja solusi ini cukup menggambarkan diri (setidaknya menurut saya). Tetapi Anda mengandalkan "fitur" tidak berdokumen (setidaknya saya tidak menemukan apa-apa dengan pencarian google cepat) dari. NET API. Ini dapat berubah dengan rilis di masa mendatang jadi harap tutupi Metode dengan Tes.
Ada tes di https://github.com/dotnet/corefx/blob/master/src/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs (
Path_Get_Set
) yang memeriksa, jika diperiksa dengan\
benar.Catatan Sisi: Seseorang juga dapat bekerja dengan
UriBuilder.Uri
properti secara langsung, jika uri akan digunakan untukSystem.Uri
aktor.sumber
Bagi siapa saja yang mencari satu-liner dan hanya ingin bergabung dengan bagian dari jalan tanpa membuat metode baru atau referensi perpustakaan baru atau membangun nilai URI dan mengonversinya menjadi string, maka ...
Ini cukup mendasar, tetapi saya tidak melihat apa lagi yang Anda butuhkan. Jika Anda takut dua kali lipat '/' maka Anda bisa melakukan
.Replace("//", "/")
sesudahnya. Jika Anda takut mengganti '//' yang dilipatgandakan dalam 'https: //', alih-alih lakukan satu bergabung, ganti '/' yang digandakan, kemudian bergabunglah dengan url situs web (namun saya cukup yakin sebagian besar browser akan secara otomatis konversikan apa pun dengan 'https:' di depannya untuk membaca dalam format yang benar). Ini akan terlihat seperti:Ada banyak jawaban di sini yang akan menangani semua hal di atas, tetapi dalam kasus saya, saya hanya membutuhkannya sekali di satu lokasi dan tidak perlu terlalu bergantung padanya. Juga, sangat mudah untuk melihat apa yang sedang terjadi di sini.
Lihat: https://docs.microsoft.com/en-us/dotnet/api/system.string.join?view=netframework-4.8
sumber
Menggunakan:
Ini memiliki manfaat berperilaku persis seperti
Path.Combine
.sumber
Inilah pendekatan saya dan saya akan menggunakannya untuk diri saya juga:
sumber
Gunakan ini:
sumber
Saya menemukan bahwa
Uri
konstruktor membalik '\' ke '/'. Jadi Anda juga bisa menggunakanPath.Combine
, denganUri
konstruktor.sumber
Untuk apa nilainya, berikut beberapa metode ekstensi. Yang pertama akan menggabungkan jalur dan yang kedua menambahkan parameter ke URL.
sumber
Seperti yang ditemukan di jawaban lain, baik yang baru
Uri()
atauTryCreate()
dapat melakukan centang. Namun, basis Uri harus diakhiri dengan/
dan relatif harus TIDAK mulai dengan/
; jika tidak, ia akan menghapus bagian akhir dari Url dasarSaya pikir ini paling baik dilakukan sebagai metode ekstensi, yaitu
dan untuk menggunakannya:
Dalam hal kinerja, ini menghabiskan lebih banyak sumber daya daripada yang dibutuhkan, karena kelas Uri yang melakukan banyak parsing dan validasi; profil yang sangat kasar (Debug) melakukan sejuta operasi dalam waktu sekitar 2 detik. Ini akan berfungsi untuk sebagian besar skenario, namun agar lebih efisien, lebih baik memanipulasi segala sesuatu sebagai string, ini membutuhkan 125 milidetik untuk 1 juta operasi. Yaitu
Dan jika Anda masih ingin mengembalikan URI, dibutuhkan sekitar 600 milidetik untuk 1 juta operasi.
Saya harap ini membantu.
sumber
Saya pikir ini akan memberi Anda lebih banyak fleksibilitas karena Anda dapat menangani sebanyak mungkin segmen jalur yang Anda inginkan:
sumber