Path.Combine kullanışlıdır, ancak URL'ler için .NET çerçevesinde benzer bir işlev var mı?
Ben böyle bir sözdizimi arıyorum:
Url.Combine("http://MyUrl.com/", "/Images/Image.jpg")
hangi dönecekti:
"http://MyUrl.com/Images/Image.jpg"
Path.Combine kullanışlıdır, ancak URL'ler için .NET çerçevesinde benzer bir işlev var mı?
Ben böyle bir sözdizimi arıyorum:
Url.Combine("http://MyUrl.com/", "/Images/Image.jpg")
hangi dönecekti:
"http://MyUrl.com/Images/Image.jpg"
Yanıtlar:
Orada üstünde bir Todd Menier en yorumdur o Flurl bir içermektedirUrl.Combine
.
Daha fazla detay:
Url.Combine temelde URL'ler için bir Path.Combine'dir ve parçalar arasında bir ve sadece bir ayırıcı karakter sağlar:
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"
NuGet'te Flurl.Http alın :
PM> Kurulum Paketi Flurl.Http
Veya HTTP özellikleri olmadan bağımsız URL oluşturucu edinin :
PM> Yükleme Paketi Flurl
Flurl
ve hafif bir versiyonunu görürseniz
Uri
bunu sizin için yapması gereken bir kurucuya sahiptir: new Uri(Uri baseUri, string relativeUri)
İşte bir örnek:
Uri baseUri = new Uri("http://www.contoso.com");
Uri myUri = new Uri(baseUri, "catalog/shownew.htm");
Editörden not: Dikkat, bu yöntem beklendiği gibi çalışmıyor. Bazı durumlarda baseUri'nin bir kısmını kesebilir. Yorumlara ve diğer yanıtlara bakın.
Bu uygun bir çözüm olabilir:
public static string Combine(string uri1, string uri2)
{
uri1 = uri1.TrimEnd('/');
uri2 = uri2.TrimStart('/');
return string.Format("{0}/{1}", uri1, uri2);
}
Siz kullanın Uri.TryCreate( ... )
:
Uri result = null;
if (Uri.TryCreate(new Uri("http://msdn.microsoft.com/en-us/library/"), "/en-us/library/system.uri.trycreate.aspx", out result))
{
Console.WriteLine(result);
}
Geri dönücek:
http://msdn.microsoft.com/en-us/library/system.uri.trycreate.aspx
int.TryParse
, DateTime.TryParseExact
) bir if ifadesinde kullanılmasını kolaylaştırmak için bu çıktı parametresi bulunur. Btw, Ryan'ın bu örnekte yaptığı gibi değişkeni başlatmanız gerekmez.
test.com/mydirectory/
ve /helloworld.aspx
sonuçlanacaktır test.com/helloworld.aspx
istediğini görünüşte olmadığı.
Burada zaten bazı harika cevaplar var. Mdsharpe önerisine dayanarak, Uri örnekleriyle uğraşmak istediğinizde kolayca kullanılabilecek bir uzantı yöntemi:
using System;
using System.Linq;
public static class UriExtensions
{
public static Uri Append(this Uri uri, params string[] paths)
{
return new Uri(paths.Aggregate(uri.AbsoluteUri, (current, path) => string.Format("{0}/{1}", current.TrimEnd('/'), path.TrimStart('/'))));
}
}
Ve kullanım örneği:
var url = new Uri("http://example.com/subpath/").Append("/part1/", "part2").AbsoluteUri;
Bu http://example.com/subpath/part1/part2 üretecektir
Ryan Cook'un cevabı peşinde olduğum şeye yakın ve diğer geliştiriciler için daha uygun olabilir. Ancak, dizenin başına http: // ekler ve genel olarak ben sonradan biraz daha biçimlendirme yapar.
Ayrıca, benim kullanım durumlarım için, göreli yolları çözmek önemli değildir.
mdsharp'ın cevabı da iyi bir fikrin tohumunu içerir, ancak gerçek uygulamanın tamamlanması için birkaç ayrıntı daha gerekiyordu. Bu, onu ortadan kaldırmak için bir girişimdir (ve bunu üretimde kullanıyorum):
C #
public string UrlCombine(string url1, string url2)
{
if (url1.Length == 0) {
return url2;
}
if (url2.Length == 0) {
return url1;
}
url1 = url1.TrimEnd('/', '\\');
url2 = url2.TrimStart('/', '\\');
return string.Format("{0}/{1}", url1, url2);
}
VB.NET
Public Function UrlCombine(ByVal url1 As String, ByVal url2 As String) As String
If url1.Length = 0 Then
Return url2
End If
If url2.Length = 0 Then
Return url1
End If
url1 = url1.TrimEnd("/"c, "\"c)
url2 = url2.TrimStart("/"c, "\"c)
Return String.Format("{0}/{1}", url1, url2)
End Function
Bu kod, VB'de olan aşağıdaki testi geçer:
<TestMethod()> Public Sub UrlCombineTest()
Dim target As StringHelpers = New StringHelpers()
Assert.IsTrue(target.UrlCombine("test1", "test2") = "test1/test2")
Assert.IsTrue(target.UrlCombine("test1/", "test2") = "test1/test2")
Assert.IsTrue(target.UrlCombine("test1", "/test2") = "test1/test2")
Assert.IsTrue(target.UrlCombine("test1/", "/test2") = "test1/test2")
Assert.IsTrue(target.UrlCombine("/test1/", "/test2/") = "/test1/test2/")
Assert.IsTrue(target.UrlCombine("", "/test2/") = "/test2/")
Assert.IsTrue(target.UrlCombine("/test1/", "") = "/test1/")
End Sub
ArgumentNullException("url1")
argüman zorunlu ise ne olacak Nothing
? Üzgünüm, sadece seçici olmak ;-). Ters eğik çizginin bir URI'de hiçbir ilgisi olmadığını (ve varsa, kesilmemesi gerektiğini) unutmayın, böylece TrimXXX'inizden kaldırabilirsiniz.
Path.Combine benim için çalışmıyor çünkü "|" gibi karakterler olabilir QueryString argümanlarında ve dolayısıyla bir ArgumentException özelliğine neden olacak URL'de.
İlk Uri(Uri baseUri, string relativeUri)
olarak URI'ler nedeniyle benim için başarısız olan yeni yaklaşımı denedim http://www.mediawiki.org/wiki/Special:SpecialPages
:
new Uri(new Uri("http://www.mediawiki.org/wiki/"), "Special:SpecialPages")
sonra iki nokta üst üste nedeniyle Special: SpecialPages ile sonuçlanır Special
bir şemayı gösterir.
Sonunda mdsharpe / Brian MacKays rotasını kullanmak zorunda kaldım ve birden fazla URI parçası ile çalışmak için biraz daha geliştirdim:
public static string CombineUri(params string[] uriParts)
{
string uri = string.Empty;
if (uriParts != null && uriParts.Length > 0)
{
char[] trims = new char[] { '\\', '/' };
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;
}
Kullanımı: CombineUri("http://www.mediawiki.org/", "wiki", "Special:SpecialPages")
Sağladığınız örnek URL'ye dayanarak, sitenize göre URL'leri birleştirmek istediğinizi varsayacağım.
Bu varsayımı temel alarak, bu çözümü sorunuza en uygun yanıt olarak önereceğim: "Path.Combine kullanışlı, URL'ler çerçevesinde benzer bir işlev var mı?"
Bir olmadığı için benzer işlevi "VirtualPathUtility.Combine" yöntemi: URL'ler için çerçevesinde ben doğru olduğunu öneriyorum. MSDN referans bağlantısı: şöyledir VirtualPathUtility.Combine Method
Bir uyarı var: Bunun yalnızca sitenize göre URL'ler için çalıştığına inanıyorum (yani, başka bir web sitesine bağlantı oluşturmak için kullanamazsınız. Örneğin var url = VirtualPathUtility.Combine("www.google.com", "accounts/widgets");
).
Server.MapPath
birleştirme ve birleştirme kısayolu yapar .
Path.Combine("Http://MyUrl.com/", "/Images/Image.jpg").Replace("\\", "/")
path.Replace(Path.DirectorySeparatorChar, '/');
path.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
Sadece küçük bir uzantı yöntemi bir araya getirdim:
public static string UriCombine (this string val, string append)
{
if (String.IsNullOrEmpty(val)) return append;
if (String.IsNullOrEmpty(append)) return val;
return val.TrimEnd('/') + "/" + append.TrimStart('/');
}
Bu şekilde kullanılabilir:
"www.example.com/".UriCombine("/images").UriCombine("first.jpeg");
Esprili bir örnek olan Ryan, işleve bir bağlantı ile bitiyor. Aferin.
Bir öneri Brian: Bu kodu bir işlevde sararsanız, TryCreate çağrısından önce temel URL'yi sarmak için bir UriBuilder kullanmak isteyebilirsiniz.
Aksi takdirde, temel URL şemayı içermelidir ZORUNLU (burada UriBuilder http: // varsayar). Sadece bir düşünce:
public string CombineUrl(string baseUrl, string relativeUrl) {
UriBuilder baseUri = new UriBuilder(baseUrl);
Uri newUri;
if (Uri.TryCreate(baseUri.Uri, relativeUrl, out newUri))
return newUri.ToString();
else
throw new ArgumentException("Unable to combine specified url values");
}
Onları birleştirmenin ve her zaman doğru olmasını sağlamanın kolay bir yolu:
string.Format("{0}/{1}", Url1.Trim('/'), Url2);
Bir URL'nin birden çok bölümünü birleştirmek biraz zor olabilir. İki parametreli yapıcıyı Uri(baseUri, relativeUri)
veya Uri.TryCreate()
yardımcı program işlevini kullanabilirsiniz .
Bu yöntemler birinci parametrenin kapalı göreli parçalar kesiliyor devam çünkü iki durumda da, hatalı bir sonuç dönen sonunda olabilir baseUri
gibi bir şey yani http://google.com/some/thing
için http://google.com
.
Birden çok parçayı nihai bir URL'de birleştirmek için aşağıdaki iki işlevi kopyalayabilirsiniz:
public static string Combine(params string[] parts)
{
if (parts == null || parts.Length == 0) return string.Empty;
var urlBuilder = new StringBuilder();
foreach (var part in parts)
{
var tempUrl = tryCreateRelativeOrAbsolute(part);
urlBuilder.Append(tempUrl);
}
return VirtualPathUtility.RemoveTrailingSlash(urlBuilder.ToString());
}
private static string tryCreateRelativeOrAbsolute(string s)
{
System.Uri uri;
System.Uri.TryCreate(s, UriKind.RelativeOrAbsolute, out uri);
string tempUrl = VirtualPathUtility.AppendTrailingSlash(uri.ToString());
return tempUrl;
}
Kullanımı göstermek için birim testleri içeren tam kodu https://uricombine.codeplex.com/SourceControl/latest#UriCombine/Uri.cs adresinde bulabilirsiniz.
En yaygın üç vakayı kapsayan birim testlerim var:
UriBuilder
Bu tür şeyler için gerçekten iyi iş buldum :
UriBuilder urlb = new UriBuilder("http", _serverAddress, _webPort, _filePath);
Uri url = urlb.Uri;
return url.AbsoluteUri;
Daha fazla kurucu ve dokümantasyon için UriBuilder Sınıfı - MSDN'ye bakın .
İşte Microsoft'un (OfficeDev PnP) yöntemi UrlUtility.Combine :
const char PATH_DELIMITER = '/';
/// <summary>
/// Combines a path and a relative path.
/// </summary>
/// <param name="path"></param>
/// <param name="relative"></param>
/// <returns></returns>
public static string Combine(string path, string relative)
{
if(relative == null)
relative = String.Empty;
if(path == null)
path = String.Empty;
if(relative.Length == 0 && path.Length == 0)
return String.Empty;
if(relative.Length == 0)
return path;
if(path.Length == 0)
return relative;
path = path.Replace('\\', PATH_DELIMITER);
relative = relative.Replace('\\', PATH_DELIMITER);
return path.TrimEnd(PATH_DELIMITER) + PATH_DELIMITER + relative.TrimStart(PATH_DELIMITER);
}
Kaynak: GitHub
Aşağıdakileri yararlı buluyorum ve aşağıdaki özelliklere sahibim:
params
çok URL segmenti için birden fazla parametre alırSınıf
public static class UrlPath
{
private static string InternalCombine(string source, string dest)
{
if (string.IsNullOrWhiteSpace(source))
throw new ArgumentException("Cannot be null or white space", nameof(source));
if (string.IsNullOrWhiteSpace(dest))
throw new ArgumentException("Cannot be null or white space", nameof(dest));
return $"{source.TrimEnd('/', '\\')}/{dest.TrimStart('/', '\\')}";
}
public static string Combine(string source, params string[] args)
=> args.Aggregate(source, InternalCombine);
}
Testler
UrlPath.Combine("test1", "test2");
UrlPath.Combine("test1//", "test2");
UrlPath.Combine("test1", "/test2");
// Result = test1/test2
UrlPath.Combine(@"test1\/\/\/", @"\/\/\\\\\//test2", @"\/\/\\\\\//test3\") ;
// Result = test1/test2/test3
UrlPath.Combine("/test1/", "/test2/", null);
UrlPath.Combine("", "/test2/");
UrlPath.Combine("/test1/", null);
// Throws an ArgumentException
Genel çözümüm:
public static string Combine(params string[] uriParts)
{
string uri = string.Empty;
if (uriParts != null && uriParts.Any())
{
char[] trims = new char[] { '\\', '/' };
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;
}
Hayatınızı kolaylaştıracak bu işlevi yarattım:
/// <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>
public static string PathCombine(bool IsURL , bool IsRelative , bool IsFixInternal , params string[] parts)
{
if (parts == null || parts.Length == 0) return string.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;
}
URL'ler ve normal yollar için çalışır.
Kullanımı:
// Fixes internal paths
Console.WriteLine(PathCombine(true , true , true , @"\/\/folder 1\/\/\/\\/\folder2\///folder3\\/" , @"/\somefile.ext\/\//\"));
// Result: /folder 1/folder2/folder3/somefile.ext
// Doesn't fix internal paths
Console.WriteLine(PathCombine(true , true , false , @"\/\/folder 1\/\/\/\\/\folder2\///folder3\\/" , @"/\somefile.ext\/\//\"));
//result : /folder 1//////////folder2////folder3/somefile.ext
// Don't worry about URL prefixes when fixing internal paths
Console.WriteLine(PathCombine(true , false , true , @"/\/\/https:/\/\/\lul.com\/\/\/\\/\folder2\///folder3\\/" , @"/\somefile.ext\/\//\"));
// Result: https://lul.com/folder2/folder3/somefile.ext
Console.WriteLine(PathCombine(false , true , true , @"../../../\\..\...\./../somepath" , @"anotherpath"));
// Result: \..\..\..\..\...\.\..\somepath\anotherpath
Neden sadece aşağıdakileri kullanmıyorsunuz?
System.IO.Path.Combine(rootUrl, subPath).Replace(@"\", "/")
[System.IO.Path]::Combine("http://MyUrl.com/","/Images/Image.jpg")
ancak bu sonucu başarısız: /Images/Image.jpg
. Kaldır /
ikinci Alt yol gelen ve çalışır:[System.IO.Path]::Combine("http://MyUrl.com/","Images/Image.jpg")
URL'leri bir URI ile birleştirirken kurallar
Garip davranışlardan kaçınmak için uyulması gereken bir kural vardır:
string.Empty
parça yolu eklemek göreli dizini URL'den de kaldırır!Yukarıdaki kurallara uyarsanız, URL'leri aşağıdaki kodla birleştirebilirsiniz. Durumunuza bağlı olarak, URL'ye birden çok 'dizin' parçası ekleyebilirsiniz ...
var pathParts = new string[] { destinationBaseUrl, destinationFolderUrl, fileName };
var destination = pathParts.Aggregate((left, right) =>
{
if (string.IsNullOrWhiteSpace(right))
return left;
return new Uri(new Uri(left), right).ToString();
});
Eğer ASP.NET Çekirdek (ayrıca Microsoft.Owin mevcuttur) içinde, Flurl gibi bir üçüncü taraf bağımlılık böyle ekleyebilir veya özel bir uzantısı yöntemi oluşturmak istemiyorsanız, kullanabileceğiniz PathString
URI kadar bina amacıyla tasarlanmıştır hangi yolları. Daha sonra bunun bir kombinasyonunu kullanarak tam URI'nizi oluşturabilir Uri
veUriBuilder
.
Bu durumda şöyle olur:
new Uri(new UriBuilder("http", "MyUrl.com").Uri, new PathString("/Images").Add("/Image.jpg").ToString())
Bu, temel URL'deki ayırıcıları belirtmek zorunda kalmadan tüm bileşen parçalarını verir. Ne yazık ki, PathString
gerektirir /
her dize eklenir aksi takdirde aslında bir atar ArgumentException
! Ama en azından URI'nizi belirleyici olarak kolayca birim testine tabi tutulacak şekilde oluşturabilirsiniz.
Yani UriBuilder kullanan herkese benzer başka bir yaklaşımım var.
BaseUrl (yolun bir kısmını içerebilir - örneğin http://mybaseurl.com/dev/ ) javajavajavajavajava olarak bölmek istemedim .
Aşağıdaki kod parçası, + Testler kodunu gösterir.
Dikkat: Bu çözüm ana bilgisayarı indirir ve bir bağlantı noktası ekler. Bu arzu değilse, bir örneğin kaldıraç tarafından bir dize temsilini yazabilir Uri
Mülkiyeti UriBuilder
.
public class Tests
{
public static string CombineUrl (string baseUrl, string path)
{
var uriBuilder = new UriBuilder (baseUrl);
uriBuilder.Path = Path.Combine (uriBuilder.Path, path);
return uriBuilder.ToString();
}
[TestCase("http://MyUrl.com/", "/Images/Image.jpg", "http://myurl.com:80/Images/Image.jpg")]
[TestCase("http://MyUrl.com/basePath", "/Images/Image.jpg", "http://myurl.com:80/Images/Image.jpg")]
[TestCase("http://MyUrl.com/basePath", "Images/Image.jpg", "http://myurl.com:80/basePath/Images/Image.jpg")]
[TestCase("http://MyUrl.com/basePath/", "Images/Image.jpg", "http://myurl.com:80/basePath/Images/Image.jpg")]
public void Test1 (string baseUrl, string path, string expected)
{
var result = CombineUrl (baseUrl, path);
Assert.That (result, Is.EqualTo (expected));
}
}
Windows 10'da .NET Core 2.1 ile test edilmiştir.
Bu neden işe yarıyor?
Path.Combine
Ters eğik çizgiler (en azından Windows'ta) geri dönecek olsa da , UriBuilder bu davayı Setter'da ele alır Path
.
Alındığı https://github.com/dotnet/corefx/blob/master/src/System.Private.Uri/src/System/UriBuilder.cs (çağrısını akla string.Replace
)
[AllowNull]
public string Path
{
get
{
return _path;
}
set
{
if ((value == null) || (value.Length == 0))
{
value = "/";
}
_path = Uri.InternalEscapeString(value.Replace('\\', '/'));
_changed = true;
}
}
Bu en iyi yaklaşım mı?
Kesinlikle bu çözüm kendini çok iyi tanımlamaktadır (en azından benim görüşüme göre). Ama belgelenmemiş güveniyorsun (en azından hızlı bir google arama ile hiçbir şey bulamadım) .NET API "özelliği". Bu, gelecekteki bir sürümle değişebilir.
Doğru dönüştürülmüş olup olmadığını kontrol eden https://github.com/dotnet/corefx/blob/master/src/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs ( Path_Get_Set
) ' de testler vardır \
.
Yan Not:UriBuilder.Uri
uri bir System.Uri
ctor için kullanılacaksa, doğrudan mülkle de çalışılabilir .
Bir astar arayan ve sadece yeni bir yöntem oluşturmadan veya yeni bir kitaplığa başvurmadan veya bir URI değeri oluşturmadan ve bir dizeye dönüştürmek için bir yolun parçalarına katılmak isteyen herkes için, o zaman ...
string urlToImage = String.Join("/", "websiteUrl", "folder1", "folder2", "folder3", "item");
Oldukça basit, ama daha fazlasına ihtiyacınız olduğunu göremiyorum. Eğer '/' değerini ikiye katlamaktan korkuyorsanız daha sonra yapabilirsiniz .Replace("//", "/")
. 'Https: //' içindeki iki katına çıkmış '//' yerine koymaktan korkuyorsanız, bunun yerine bir katılma yapın, katlanan '/' yerine koyun, ardından web sitesi URL'sine katılın (ancak çoğu tarayıcının otomatik olarak doğru biçimde okumak için önündeki 'https:' ile herhangi bir şeyi dönüştürün). Bu şöyle görünecektir:
string urlToImage = String.Join("/","websiteUrl", String.Join("/", "folder1", "folder2", "folder3", "item").Replace("//","/"));
Burada yukarıdakilerin hepsini işleyecek birçok cevap var, ama benim durumumda, sadece bir yerde bir kez ihtiyacım vardı ve buna çok fazla güvenmek zorunda kalmayacağım. Ayrıca, burada neler olduğunu görmek gerçekten çok kolay.
Bkz. Https://docs.microsoft.com/en-us/dotnet/api/system.string.join?view=netframework-4.8
kullanın:
private Uri UriCombine(string path1, string path2, string path3 = "", string path4 = "")
{
string path = System.IO.Path.Combine(path1, path2.TrimStart('\\', '/'), path3.TrimStart('\\', '/'), path4.TrimStart('\\', '/'));
string url = path.Replace('\\','/');
return new Uri(url);
}
Aynı şekilde davranma avantajına sahiptir Path.Combine
.
İşte yaklaşımım ve ben de kendim için kullanacağım:
public static string UrlCombine(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 seperator
if (string.IsNullOrEmpty(part1) || string.IsNullOrEmpty(part2))
{
seperator = string.Empty;
}
// If part1 is not empty,
// remove '/' at last
if (!string.IsNullOrEmpty(part1))
{
newPart1 = part1.TrimEnd('/');
}
// If part2 is not empty,
// remove '/' at first
if (!string.IsNullOrEmpty(part2))
{
newPart2 = part2.TrimStart('/');
}
// Now finally combine
return string.Format("{0}{1}{2}", newPart1, seperator, newPart2);
}
Bunu kullan:
public static class WebPath
{
public static string Combine(params string[] args)
{
var prefixAdjusted = args.Select(x => x.StartsWith("/") && !x.StartsWith("http") ? x.Substring(1) : x);
return string.Join("/", prefixAdjusted);
}
}
Değer için, burada birkaç uzatma yöntemi. Birincisi yolları birleştirecek ve ikincisi URL'ye parametreler ekleyecek.
public static string CombineUrl(this string root, string path, params string[] paths)
{
if (string.IsNullOrWhiteSpace(path))
{
return root;
}
Uri baseUri = new Uri(root);
Uri combinedPaths = new Uri(baseUri, path);
foreach (string extendedPath in paths)
{
combinedPaths = new Uri(combinedPaths, extendedPath);
}
return combinedPaths.AbsoluteUri;
}
public static string AddUrlParams(this string url, Dictionary<string, string> parameters)
{
if (parameters == null || !parameters.Keys.Any())
{
return url;
}
var tempUrl = new StringBuilder($"{url}?");
int count = 0;
foreach (KeyValuePair<string, string> parameter in parameters)
{
if (count > 0)
{
tempUrl.Append("&");
}
tempUrl.Append($"{WebUtility.UrlEncode(parameter.Key)}={WebUtility.UrlEncode(parameter.Value)}");
count++;
}
return tempUrl.ToString();
}
Diğer cevaplarda bulunan, yeni Uri()
veya TryCreate()
kene yapabilirsiniz. Bununla birlikte, üs Uri ile bitmek zorundadır /
ve akraba ile BAŞLAMAK gerekir /
; Aksi takdirde, temel URL'nin son kısmını kaldıracak
Bunun en iyi şekilde bir uzantı yöntemi olarak yapıldığını düşünüyorum, yani
public static Uri Append(this Uri uri, string relativePath)
{
var baseUri = uri.AbsoluteUri.EndsWith('/') ? uri : new Uri(uri.AbsoluteUri + '/');
var relative = relativePath.StartsWith('/') ? relativePath.Substring(1) : relativePath;
return new Uri(baseUri, relative);
}
ve kullanmak için:
var baseUri = new Uri("http://test.com/test/");
var combinedUri = baseUri.Append("/Do/Something");
Performans açısından, bu çok fazla ayrıştırma ve doğrulama yapan Uri sınıfı nedeniyle ihtiyaç duyduğundan daha fazla kaynak tüketir; çok kaba bir profil oluşturma (Debug) yaklaşık 2 saniyede bir milyon işlem gerçekleştirdi. Bu, çoğu senaryo için işe yarayacaktır, ancak daha verimli olmak için, her şeyi dize olarak değiştirmek daha iyidir, bu 1 milyon işlem için 125 milisaniye sürer. yani
public static string Append(this Uri 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 it
var baseUri = absoluteUri.EndsWith('/') ? absoluteUri : absoluteUri + '/';
var relative = relativePath.StartsWith('/') ? relativePath.Substring(1) : relativePath;
return baseUri + relative;
}
Yine de bir URI döndürmek istiyorsanız, 1 milyon işlem için yaklaşık 600 milisaniye sürer.
public static Uri AppendUri(this Uri 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 it
var baseUri = absoluteUri.EndsWith('/') ? absoluteUri : absoluteUri + '/';
var relative = relativePath.StartsWith('/') ? relativePath.Substring(1) : relativePath;
return new Uri(baseUri + relative);
}
Umarım bu yardımcı olur.
Url.Combine
bunu yapan bir yöntem içerir .