diff --git a/src/Microsoft.AspNetCore.Http.Abstractions/PathString.cs b/src/Microsoft.AspNetCore.Http.Abstractions/PathString.cs
index b82d4442..2a5960b6 100644
--- a/src/Microsoft.AspNetCore.Http.Abstractions/PathString.cs
+++ b/src/Microsoft.AspNetCore.Http.Abstractions/PathString.cs
@@ -443,25 +443,35 @@ public override int GetHashCode()
///
///
public static implicit operator PathString(string s)
- {
- return new PathString(s);
- }
+ => ConvertFromString(s);
///
/// Implicitly calls ToString().
///
///
public static implicit operator string(PathString path)
- {
- return path.ToString();
- }
+ => path.ToString();
+
+ internal static PathString ConvertFromString(string s)
+ => string.IsNullOrEmpty(s) ? new PathString(s) : FromUriComponent(s);
}
internal class PathStringConverter : TypeConverter
{
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ => sourceType == typeof(string)
+ ? true
+ : base.CanConvertFrom(context, sourceType);
+
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
- {
- return new PathString((string)value);
- }
+ => value is string
+ ? PathString.ConvertFromString((string)value)
+ : base.ConvertFrom(context, culture, value);
+
+ public override object ConvertTo(ITypeDescriptorContext context,
+ CultureInfo culture, object value, Type destinationType)
+ => destinationType == typeof(string)
+ ? value.ToString()
+ : base.ConvertTo(context, culture, value, destinationType);
}
}
diff --git a/test/Microsoft.AspNetCore.Http.Abstractions.Tests/PathStringTests.cs b/test/Microsoft.AspNetCore.Http.Abstractions.Tests/PathStringTests.cs
index 365a9de3..ad070afa 100644
--- a/test/Microsoft.AspNetCore.Http.Abstractions.Tests/PathStringTests.cs
+++ b/test/Microsoft.AspNetCore.Http.Abstractions.Tests/PathStringTests.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@@ -208,11 +208,27 @@ public void ToUriComponentEscapeCorrectly(string category, string input, string
}
[Fact]
- public void PathStringConvertsFromString()
+ public void PathStringConvertsOnlyToAndFromString()
{
var converter = TypeDescriptor.GetConverter(typeof(PathString));
PathString result = (PathString)converter.ConvertFromInvariantString("/foo");
Assert.Equal("/foo", result.ToString());
+ Assert.Equal("/foo", converter.ConvertTo(result, typeof(string)));
+ Assert.True(converter.CanConvertFrom(typeof(string)));
+ Assert.False(converter.CanConvertFrom(typeof(int)));
+ Assert.False(converter.CanConvertFrom(typeof(bool)));
+ Assert.True(converter.CanConvertTo(typeof(string)));
+ Assert.False(converter.CanConvertTo(typeof(int)));
+ Assert.False(converter.CanConvertTo(typeof(bool)));
+ }
+
+ [Fact]
+ public void PathStringStaysEqualAfterAssignments()
+ {
+ PathString p1 = "/?";
+ string s1 = p1;
+ PathString p2 = s1;
+ Assert.Equal(p1, p2);
}
}
}