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
8 changes: 5 additions & 3 deletions src/Microsoft.AspNetCore.OData/Edm/EdmModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -392,21 +392,23 @@ public static bool IsEnumOrCollectionEnum(this IEdmTypeReference edmType)
/// <param name="structuralType">The starting structural type.</param>
/// <param name="model">The Edm model.</param>
/// <param name="typeName">The searching type name.</param>
/// <param name="caseInsensitive">If true, performs case insensitive search</param>
/// <returns>The found type.</returns>
public static IEdmStructuredType FindTypeInInheritance(this IEdmStructuredType structuralType, IEdmModel model, string typeName)
public static IEdmStructuredType FindTypeInInheritance(this IEdmStructuredType structuralType, IEdmModel model, string typeName, bool caseInsensitive = false)
{
StringComparison typeStringComparison = caseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
IEdmStructuredType baseType = structuralType;
while (baseType != null)
{
if (GetName(baseType) == typeName)
if (GetName(baseType).Equals(typeName, typeStringComparison))
{
return baseType;
}

baseType = baseType.BaseType;
}

return model.FindAllDerivedTypes(structuralType).FirstOrDefault(c => GetName(c) == typeName);
return model.FindAllDerivedTypes(structuralType).FirstOrDefault(c => GetName(c).Equals(typeName, typeStringComparison));
}

private static string GetName(IEdmStructuredType type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2271,13 +2271,14 @@
<param name="edmType"></param>
<returns></returns>
</member>
<member name="M:Microsoft.AspNetCore.OData.Edm.EdmModelExtensions.FindTypeInInheritance(Microsoft.OData.Edm.IEdmStructuredType,Microsoft.OData.Edm.IEdmModel,System.String)">
<member name="M:Microsoft.AspNetCore.OData.Edm.EdmModelExtensions.FindTypeInInheritance(Microsoft.OData.Edm.IEdmStructuredType,Microsoft.OData.Edm.IEdmModel,System.String,System.Boolean)">
<summary>
Find the given type in a structured type inheritance, include itself.
</summary>
<param name="structuralType">The starting structural type.</param>
<param name="model">The Edm model.</param>
<param name="typeName">The searching type name.</param>
<param name="caseInsensitive">If true, performs case insensitive search</param>
<returns>The found type.</returns>
</member>
<member name="M:Microsoft.AspNetCore.OData.Edm.EdmModelExtensions.GetAvailableActions(Microsoft.OData.Edm.IEdmModel,Microsoft.OData.Edm.IEdmEntityType)">
Expand Down Expand Up @@ -12855,6 +12856,11 @@
Initializes a new instance of the <see cref="T:Microsoft.AspNetCore.OData.Routing.ODataRouteOptions" /> class.
</summary>
</member>
<member name="P:Microsoft.AspNetCore.OData.Routing.ODataRouteOptions.EnableActionNameCaseInsensitive">
<summary>
Gets/sets a value indicating whether to enable case insensitive for the action name in conventional routing.
</summary>
</member>
<member name="P:Microsoft.AspNetCore.OData.Routing.ODataRouteOptions.EnableControllerNameCaseInsensitive">
<summary>
Gets/sets a value indicating whether to enable case insensitive for the controller name in conventional routing.
Expand Down
2 changes: 2 additions & 0 deletions src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,8 @@ Microsoft.AspNetCore.OData.Routing.ODataPathSegmentHandler.PathLiteral.get -> st
Microsoft.AspNetCore.OData.Routing.ODataPathSegmentTranslator
Microsoft.AspNetCore.OData.Routing.ODataPathSegmentTranslator.ODataPathSegmentTranslator() -> void
Microsoft.AspNetCore.OData.Routing.ODataRouteOptions
Microsoft.AspNetCore.OData.Routing.ODataRouteOptions.EnableActionNameCaseInsensitive.get -> bool
Microsoft.AspNetCore.OData.Routing.ODataRouteOptions.EnableActionNameCaseInsensitive.set -> void
Microsoft.AspNetCore.OData.Routing.ODataRouteOptions.EnableControllerNameCaseInsensitive.get -> bool
Microsoft.AspNetCore.OData.Routing.ODataRouteOptions.EnableControllerNameCaseInsensitive.set -> void
Microsoft.AspNetCore.OData.Routing.ODataRouteOptions.EnableKeyAsSegment.get -> bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public virtual bool AppliesToAction(ODataControllerActionContext context)
IEdmStructuredType castType = null;
if (castTypeName != null)
{
castType = entityType.FindTypeInInheritance(context.Model, castTypeName);
castType = entityType.FindTypeInInheritance(context.Model, castTypeName, context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true);
if (castType == null)
{
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public virtual bool AppliesToAction(ODataControllerActionContext context)
return false;
}

IEdmStructuredType castType = entityType.FindTypeInInheritance(context.Model, castTypeName);
IEdmStructuredType castType = entityType.FindTypeInInheritance(context.Model, castTypeName, context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true);
if (castType == null)
{
return false;
Expand All @@ -100,7 +100,9 @@ public virtual bool AppliesToAction(ODataControllerActionContext context)
private static bool ProcessEntitySetAction(string actionName, IEdmEntitySet entitySet, IEdmStructuredType castType,
ODataControllerActionContext context, ActionModel action)
{
if (actionName == "Get" || actionName == $"Get{entitySet.Name}")
StringComparison actionNameComparison = context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;

if (actionName.Equals("Get", actionNameComparison) || actionName.Equals($"Get{entitySet.Name}", actionNameComparison))
{
IEdmCollectionType castCollectionType = null;
if (castType != null)
Expand Down Expand Up @@ -141,7 +143,7 @@ private static bool ProcessEntitySetAction(string actionName, IEdmEntitySet enti
action.AddSelector("Get", context.Prefix, context.Model, template, context.Options?.RouteOptions);
return true;
}
else if (actionName == "Post" || actionName == $"Post{entitySet.EntityType().Name}")
else if (actionName.Equals("Post", actionNameComparison) || actionName.Equals($"Post{entitySet.EntityType().Name}", actionNameComparison))
{
// POST ~/Customers
IList<ODataSegmentTemplate> segments = new List<ODataSegmentTemplate>
Expand All @@ -159,7 +161,7 @@ private static bool ProcessEntitySetAction(string actionName, IEdmEntitySet enti
action.AddSelector("Post", context.Prefix, context.Model, template, context.Options?.RouteOptions);
return true;
}
else if (actionName == "Patch" || actionName == $"Patch{entitySet.Name}")
else if (actionName.Equals("Patch", actionNameComparison) || actionName.Equals($"Patch{entitySet.Name}", actionNameComparison))
{
// PATCH ~/Patch , ~/PatchCustomers
IList<ODataSegmentTemplate> segments = new List<ODataSegmentTemplate>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ protected void ProcessOperations(ODataControllerActionContext context, IEdmEntit
return;
}

castTypeFromActionName = entityType.FindTypeInInheritance(context.Model, cast) as IEdmEntityType;
castTypeFromActionName = entityType.FindTypeInInheritance(context.Model, cast, context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true) as IEdmEntityType;
if (castTypeFromActionName == null)
{
return;
Expand All @@ -88,7 +88,8 @@ protected void ProcessOperations(ODataControllerActionContext context, IEdmEntit

// TODO: refactor here
// If we have multiple same function defined, we should match the best one?
IEnumerable<IEdmOperation> candidates = context.Model.SchemaElements.OfType<IEdmOperation>().Where(f => f.IsBound && f.Name == operationName);
StringComparison actionNameComparison = context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
IEnumerable<IEdmOperation> candidates = context.Model.SchemaElements.OfType<IEdmOperation>().Where(f => f.IsBound && f.Name.Equals(operationName, actionNameComparison));
foreach (IEdmOperation edmOperation in candidates)
{
IEdmOperationParameter bindingParameter = edmOperation.Parameters.FirstOrDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public bool AppliesToAction(ODataControllerActionContext context)
string singletonName = context.Singleton.Name;

string actionMethodName = action.ActionName;
if (IsSupportedActionName(actionMethodName, singletonName, out string httpMethod))
if (IsSupportedActionName(context, actionMethodName, singletonName, out string httpMethod))
{
// ~/Me
ODataPathTemplate template = new ODataPathTemplate(new SingletonSegmentTemplate(context.Singleton));
Expand All @@ -66,7 +66,7 @@ public bool AppliesToAction(ODataControllerActionContext context)
}

string actionPrefix = actionMethodName.Substring(0, index);
if (IsSupportedActionName(actionPrefix, singletonName, out httpMethod))
if (IsSupportedActionName(context, actionPrefix, singletonName, out httpMethod))
{
string castTypeName = actionMethodName.Substring(index + 4);
if (castTypeName.Length == 0)
Expand All @@ -78,7 +78,7 @@ public bool AppliesToAction(ODataControllerActionContext context)
IEdmEntityType entityType = context.Singleton.EntityType();

// Shall we cast to base type and the type itself? I think yes.
IEdmStructuredType castType = entityType.FindTypeInInheritance(context.Model, castTypeName);
IEdmStructuredType castType = entityType.FindTypeInInheritance(context.Model, castTypeName, context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true);
if (castType != null)
{
// ~/Me/Namespace.TypeCast
Expand All @@ -94,19 +94,20 @@ public bool AppliesToAction(ODataControllerActionContext context)
return false;
}

private static bool IsSupportedActionName(string actionName, string singletonName, out string httpMethod)
private static bool IsSupportedActionName(ODataControllerActionContext context, string actionName, string singletonName, out string httpMethod)
{
if (actionName == "Get" || actionName == $"Get{singletonName}")
StringComparison actionNameComparison = context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
if (actionName.Equals("Get", actionNameComparison) || actionName.Equals($"Get{singletonName}", actionNameComparison))
{
httpMethod = "Get";
return true;
}
else if (actionName == "Put" || actionName == $"Put{singletonName}")
else if (actionName.Equals("Put", actionNameComparison) || actionName.Equals($"Put{singletonName}", actionNameComparison))
{
httpMethod = "Put";
return true;
}
else if (actionName == "Patch" || actionName == $"Patch{singletonName}")
else if (actionName.Equals("Patch", actionNameComparison) || actionName.Equals($"Patch{singletonName}", actionNameComparison))
{
httpMethod = "Patch";
return true;
Expand Down
5 changes: 5 additions & 0 deletions src/Microsoft.AspNetCore.OData/Routing/ODataRouteOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ public ODataRouteOptions()
_enableUnqualifiedOperationCall = true;
}

/// <summary>
/// Gets/sets a value indicating whether to enable case insensitive for the action name in conventional routing.
/// </summary>
public bool EnableActionNameCaseInsensitive { get; set; } = false;

/// <summary>
/// Gets/sets a value indicating whether to enable case insensitive for the controller name in conventional routing.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1760,6 +1760,7 @@ public class Microsoft.AspNetCore.OData.Routing.ODataPathSegmentTranslator : Mic
public class Microsoft.AspNetCore.OData.Routing.ODataRouteOptions {
public ODataRouteOptions ()

bool EnableActionNameCaseInsensitive { public get; public set; }
bool EnableControllerNameCaseInsensitive { public get; public set; }
bool EnableKeyAsSegment { public get; public set; }
bool EnableKeyInParenthesis { public get; public set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1760,6 +1760,7 @@ public class Microsoft.AspNetCore.OData.Routing.ODataPathSegmentTranslator : Mic
public class Microsoft.AspNetCore.OData.Routing.ODataRouteOptions {
public ODataRouteOptions ()

bool EnableActionNameCaseInsensitive { public get; public set; }
bool EnableControllerNameCaseInsensitive { public get; public set; }
bool EnableKeyAsSegment { public get; public set; }
bool EnableKeyInParenthesis { public get; public set; }
Expand Down
Loading