Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit af29d77

Browse files
committed
Add UrlWithTrailingSlash
1 parent 4df4569 commit af29d77

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

src/ServiceStack.Text/StringExtensions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,16 @@ public static string ToRot13(this string value)
224224
return new string(array);
225225
}
226226

227+
private static char[] UrlPathDelims = new[] {'?', '#'};
228+
229+
public static string UrlWithTrailingSlash(this string url)
230+
{
231+
var endPos = url?.IndexOfAny(UrlPathDelims) ?? -1;
232+
return endPos >= 0
233+
? url.Substring(0, endPos).WithTrailingSlash() + url.Substring(endPos)
234+
: url.WithTrailingSlash();
235+
}
236+
227237
public static string WithTrailingSlash(this string path)
228238
{
229239
if (path == null)

tests/ServiceStack.Text.Tests/StringExtensionsTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,5 +362,39 @@ public void Does_ReplaceAll_from_Start()
362362
Assert.That("/images".ReplaceAll("/",""), Is.EqualTo("images"));
363363
}
364364

365+
[TestCase("", ExpectedResult = "/")]
366+
[TestCase("/", ExpectedResult = "/")]
367+
[TestCase("?p1=asdf", ExpectedResult = "/?p1=asdf")]
368+
[TestCase("/page", ExpectedResult = "/page/")]
369+
[TestCase("/page/", ExpectedResult = "/page/")]
370+
[TestCase("/page?p1=asdf", ExpectedResult = "/page/?p1=asdf")]
371+
[TestCase("/page?p1=asdf&p2=asdf", ExpectedResult = "/page/?p1=asdf&p2=asdf")]
372+
[TestCase("/page/?p1=asdf&p2=asdf", ExpectedResult = "/page/?p1=asdf&p2=asdf")]
373+
374+
[TestCase("#here", ExpectedResult = "/#here")]
375+
[TestCase("?p1=asdf#here", ExpectedResult = "/?p1=asdf#here")]
376+
[TestCase("/page#here", ExpectedResult = "/page/#here")]
377+
[TestCase("/page/#here", ExpectedResult = "/page/#here")]
378+
[TestCase("/page?p1=asdf#here", ExpectedResult = "/page/?p1=asdf#here")]
379+
[TestCase("/page?p1=asdf&p2=asdf#here", ExpectedResult = "/page/?p1=asdf&p2=asdf#here")]
380+
[TestCase("/page/?p1=asdf&p2=asdf#here", ExpectedResult = "/page/?p1=asdf&p2=asdf#here")]
381+
382+
[TestCase("domain.com", ExpectedResult = "domain.com/")]
383+
[TestCase("domain.com/", ExpectedResult = "domain.com/")]
384+
[TestCase("domain.com?p1=asdf", ExpectedResult = "domain.com/?p1=asdf")]
385+
[TestCase("domain.com/page?p1=asdf", ExpectedResult = "domain.com/page/?p1=asdf")]
386+
[TestCase("domain.com/page?p1=asdf&p2=asdf", ExpectedResult = "domain.com/page/?p1=asdf&p2=asdf")]
387+
[TestCase("domain.com/page/?p1=asdf&p2=asdf", ExpectedResult = "domain.com/page/?p1=asdf&p2=asdf")]
388+
389+
[TestCase("domain.com#here", ExpectedResult = "domain.com/#here")]
390+
[TestCase("domain.com/#here", ExpectedResult = "domain.com/#here")]
391+
[TestCase("domain.com?p1=asdf#here", ExpectedResult = "domain.com/?p1=asdf#here")]
392+
[TestCase("domain.com/page?p1=asdf#here", ExpectedResult = "domain.com/page/?p1=asdf#here")]
393+
[TestCase("domain.com/page?p1=asdf&p2=asdf#here", ExpectedResult = "domain.com/page/?p1=asdf&p2=asdf#here")]
394+
[TestCase("domain.com/page/?p1=asdf&p2=asdf#here", ExpectedResult = "domain.com/page/?p1=asdf&p2=asdf#here")]
395+
public string Does_UrlWithTrailingSlash(string url)
396+
{
397+
return url.UrlWithTrailingSlash();
398+
}
365399
}
366400
}

0 commit comments

Comments
 (0)