[c#] Path.Combine per URL?


Answers

Usa 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);
}

Sarà di ritorno:

http://msdn.microsoft.com/en-us/library/system.uri.trycreate.aspx

Question

Path.Combine è utile, ma esiste una funzione simile nel framework .NET per gli URLs ?

Sto cercando una sintassi come questa:

Url.Combine("http://MyUrl.com/", "/Images/Image.jpg")

che restituirebbe:

"http://MyUrl.com/Images/Image.jpg"




Path.Combine("Http://MyUrl.com/", "/Images/Image.jpg").Replace("\\", "/")



Entrambi questi lavori

  Uri final = new Uri(Regex.Replace(baseUrl + "/" + relativePath, "(?<!http:)/{2,}", "/"));

O

  Uri final =new Uri(string.Format("{0}/{1}", baseUrl.ToString().TrimEnd('/'), relativePath.ToString().TrimStart('/')));

vale a dire

Se

baseUrl = " http://tesrurl.test.com/Int18 "

e

relativePath = "To_Folder"

output = http://tesrurl.test.com/Int18/To_Folder

Alcuni errori appariranno per il codice qui sotto

 // if you use below code, some issues will be there in final uri
 Uri final= new Uri(baseUrl ,relativePath );



I have to point out that Path.Combine appears to work for this also directly atleast on .NET4




We use the following simple helper method to join arbitrary number of URL parts together:

public static string JoinUrlParts(params string[] urlParts)
{
    return string.Join("/", urlParts.Where(up => !string.IsNullOrEmpty(up)).ToList().Select(up => up.Trim('/')).ToArray());
}

Note, that it doesn't support '../../something/page.htm'-style relative URL-s!




So che questo è stato risposto, ma un modo semplice per combinarli e assicurarsi che sia sempre corretto è ..

string.Format("{0}/{1}", Url1.Trim('/'), Url2);



Esempio spiritoso, Ryan, per finire con un link alla funzione. Molto bene.

Una raccomandazione Brian: se si avvolge questo codice in una funzione, è possibile che si desideri utilizzare un UriBuilder per racchiudere l'URL di base prima della chiamata TryCreate.

In caso contrario, l'URL di base DEVE includere lo schema (dove UriBuilder assumerà http: //). Solo un pensiero:

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



    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);
    }

Ha i vantaggi di comportarsi esattamente come Path.Combine




In base URLs esempio che hai fornito, assumerò che desideri combinare gli URL relativi al tuo sito.

Sulla base di questa ipotesi proporrò questa soluzione come la risposta più appropriata alla tua domanda che era: "Path.Combine è a portata di mano, esiste una funzione simile nel framework per gli URL?"

Dal momento che c'è una funzione simile nel framework per URL che propongo il corretto è: metodo "VirtualPathUtility.Combine". Ecco il link di riferimento MSDN: VirtualPathUtility.Combine Method

C'è un avvertimento: credo che funzioni solo per gli URL relativi al tuo sito (cioè, non puoi usarlo per generare collegamenti a un altro sito Web. Per esempio var url = VirtualPathUtility.Combine("www.google.com", "accounts/widgets"); ).




Bene, ho solo concatenato due stringhe e uso le espressioni regolari per eseguire la parte di pulizia.

    public class UriTool
    {
        public static Uri Join(string path1, string path2)
        {
            string url = path1 + "/" + path2;
            url = Regex.Replace(url, "(?<!http:)/{2,}", "/");

            return new Uri(url);
        }
    }

Quindi, puoi usare in questo modo:

    string path1 = "http://someaddress.com/something/";
    string path2 = "/another/address.html";
    Uri joinedUri = UriTool.Join(path1, path2);

    // joinedUri.ToString() returns "http://someaddress.com/something/another/address.html"

Spero che possa essere utile per qualcuno!




Cosa ne pensi di questo?

 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);
        }
    }



Ecco il metodo Microsoft (OfficeDev PnP) 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);
    }

Fonte: UrlUtility.Combine




so che sono in ritardo per la festa, ma ho creato questa funzione che renderà la vita più facile

    /// <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;
    }

funziona per URL e percorsi normali

Uso:

    //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



Perché non usare solo quanto segue

System.IO.Path.Combine(rootUrl, subPath).Replace(@"\", "/")



Ci sono già alcune grandi risposte qui. In base al suggerimento di mdsharpe, ecco un metodo di estensione che può essere facilmente utilizzato quando si desidera gestire istanze di Uri:

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('/'))));
    }
}

E esempio di utilizzo:

var url = new Uri("http://example.com/subpath/").Append("/part1/", "part2").AbsoluteUri;

Ciò produrrà http://example.com/subpath/part1/part2




Links