Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ static AlternateKeyRepositoryInMemory()
{
// Customers
var names = new[] { "Tom", "Jerry", "Mike", "Ben", "Sam", "Peter" };
_customers = Enumerable.Range(1, 5).Select(e => new Customer
_customers = Enumerable.Range(1, 5).Select((e, i) => new Customer
{
Id = e,
Name = names[e - 1],
SSN = "SSN-" + e + "-" + (100 + e),
SSN = i % 2 == 0 ? "SSN-" + e + "-" + (100 + e) : "SSN-%25-" + e + "-" + (100 + e),
Titles = new string[] { "abc", null, "efg" }
}).ToList();

Expand Down
16 changes: 16 additions & 0 deletions src/Microsoft.AspNetCore.OData/Common/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ namespace Microsoft.AspNetCore.OData.Common
{
internal static class StringExtensions
{
/// <summary>
/// Unescape Uri string for %2F
/// See details at: https://github.com/dotnet/aspnetcore/issues/14170#issuecomment-533342396
/// </summary>
/// <param name="uriString">The Uri string.</param>
/// <returns>Unescaped back slash Uri string.</returns>
public static string UnescapeBackSlashUriString(this string uriString)
{
if (uriString == null)
{
return null;
}

return uriString.Replace("%2f", "%2F").Replace("%2F", "/");
}

/// <summary>
/// Normalize the http method.
/// </summary>
Expand Down
8 changes: 8 additions & 0 deletions src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,14 @@
<returns>a fast getter.</returns>
<remarks>This method is more memory efficient than a dynamically compiled lambda, and about the same speed.</remarks>
</member>
<member name="M:Microsoft.AspNetCore.OData.Common.StringExtensions.UnescapeBackSlashUriString(System.String)">
<summary>
Unescape Uri string for %2F
See details at: https://github.com/dotnet/aspnetcore/issues/14170#issuecomment-533342396
</summary>
<param name="uriString">The Uri string.</param>
<returns>Unescaped back slash Uri string.</returns>
</member>
<member name="M:Microsoft.AspNetCore.OData.Common.StringExtensions.NormalizeHttpMethod(System.String)">
<summary>
Normalize the http method.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,11 @@ public override bool TryTranslate(ODataTemplateTranslateContext context)

IEdmTypeReference edmType = keyProperty.Type;
string strValue = rawValue as string;

string newStrValue = context.GetParameterAliasOrSelf(strValue);
newStrValue = Uri.UnescapeDataString(newStrValue);

// rawValue from Request route values, it's unescaped except the back-slash.
newStrValue = newStrValue.UnescapeBackSlashUriString();
if (newStrValue != strValue)
{
updateValues[templateName] = newStrValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ public void TryTranslateKeySegmentTemplate_WorksWithKeyValue_UsingEscapedString(
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
EdmEntitySet customers = container.AddEntitySet("Customers", customerType);
model.AddElement(container);
RouteValueDictionary routeValueDictionary = new RouteValueDictionary(new { First = "'Zhang'", Last = "'Gan%2Fnng%23%20T'" });
RouteValueDictionary routeValueDictionary = new RouteValueDictionary(new { First = "'Zhang'", Last = "'Gan%2Fnng# T'" });
IDictionary<string, string> keys = new Dictionary<string, string>
{
{ "FirstName", "{first}" },
Expand Down