[c#] 适用于URL的Path.Combine?


Answers

您使用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);
}

将返回:

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

Question

Path.Combine非常方便,但是.NET框架中是否有类似的功能?

我正在寻找这样的语法:

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

这将返回:

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




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

具有完全像Path.Combine一样的好处




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




这里已经有了一些很好的答案。 基于mdsharpe建议,下面是一个扩展方法,可以在处理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('/'))));
    }
}

和用法示例:

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

这将产生http://example.com/subpath/part1/part2




为什么不使用以下内容。

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



这个怎么样?

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



我知道我迟到了派对,但是我创造了这个让你的生活更轻松的功能

    /// <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以及普通路径

用法:

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



根据您提供的示例URLs ,我假设您要合并与您网站相关的网址。

基于这个假设,我会提出这个解决方案作为对您的问题的最恰当的回应:“Path.Combine很方便,在URL框架中是否有类似的功能 ?”

由于那里在URL的框架中有一个类似的功能 ,我建议正确的是:“VirtualPathUtility.Combine”方法。 以下是MSDN参考链接: VirtualPathUtility.Combine方法

有一点需要注意:我相信这只适用于相对于您网站的网址(也就是说,您不能使用它来生成指向其他网站的链接,例如, var url = VirtualPathUtility.Combine("www.google.com", "accounts/widgets"); )。




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!




我知道这已经得到解答,但将它们合并并确保它始终正确的一种简单方法是..

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



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



例如瑞安,以链接到该函数结束。 做得好。

一个建议Brian:如果你将这些代码封装在一个函数中,你可能希望在TryCreate调用之前使用UriBuilder来封装基本URL。

否则,基本URL必须包含该方案(其中UriBuilder将采用http://)。 只是一个想法:

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



那么,我只是连接两个字符串,并使用正则表达式来执行清理工作。

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

所以,你可以像这样使用:

    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"

希望它对某人有用!




以下是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);
    }

来源: UrlUtility.Combine




这两个工作

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

要么

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

如果

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

relativePath =“To_Folder”

输出= http://tesrurl.test.com/Int18/To_Folder

下面的代码会出现一些错误

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



Related