/// <inheritdoc/> internal static string SelectActionImpl(ODataPath odataPath, IWebApiControllerContext controllerContext, IWebApiActionMap actionMap) { if (odataPath.PathTemplate == "~/singleton") { SingletonSegment singletonSegment = (SingletonSegment)odataPath.Segments[0]; string httpMethodName = GetActionNamePrefix(controllerContext.Request.GetRequestMethodOrPreflightMethod()); if (httpMethodName != null) { // e.g. Try Get{SingletonName} first, then fallback on Get action name return(actionMap.FindMatchingAction( httpMethodName + singletonSegment.Singleton.Name, httpMethodName)); } } else if (odataPath.PathTemplate == "~/singleton/cast") { SingletonSegment singletonSegment = (SingletonSegment)odataPath.Segments[0]; IEdmEntityType entityType = (IEdmEntityType)odataPath.EdmType; string httpMethodName = GetActionNamePrefix(controllerContext.Request.GetRequestMethodOrPreflightMethod()); if (httpMethodName != null) { // e.g. Try Get{SingletonName}From{EntityTypeName} first, then fallback on Get action name return(actionMap.FindMatchingAction( httpMethodName + singletonSegment.Singleton.Name + "From" + entityType.Name, httpMethodName + "From" + entityType.Name)); } } return(null); }
/// <inheritdoc/> internal static string SelectActionImpl(ODataPath odataPath, IWebApiControllerContext controllerContext, IWebApiActionMap actionMap) { string prefix; TypeSegment cast; IEdmProperty property = GetProperty(odataPath, controllerContext.Request.Method, out prefix, out cast); IEdmEntityType declaringType = property == null ? null : property.DeclaringType as IEdmEntityType; if (declaringType != null) { string actionName; if (cast == null) { actionName = actionMap.FindMatchingAction( prefix + property.Name + "From" + declaringType.Name, prefix + property.Name); } else { IEdmComplexType typeCast; if (cast.EdmType.TypeKind == EdmTypeKind.Collection) { typeCast = ((IEdmCollectionType)cast.EdmType).ElementType.AsComplex().ComplexDefinition(); } else { typeCast = (IEdmComplexType)cast.EdmType; } // for example: GetCityOfSubAddressFromVipCustomer or GetCityOfSubAddress actionName = actionMap.FindMatchingAction( prefix + property.Name + "Of" + typeCast.Name + "From" + declaringType.Name, prefix + property.Name + "Of" + typeCast.Name); } if (actionName != null) { if (odataPath.PathTemplate.StartsWith("~/entityset/key", StringComparison.Ordinal)) { KeySegment keyValueSegment = (KeySegment)odataPath.Segments[1]; controllerContext.AddKeyValueToRouteData(keyValueSegment); } return(actionName); } } return(null); }
private static string FindRefActionName(IWebApiActionMap actionMap, IEdmNavigationProperty navigationProperty, IEdmEntityType declaringType, ODataRequestMethod method) { string actionNamePrefix; switch (method) { case ODataRequestMethod.Delete: actionNamePrefix = DeleteRefActionNamePrefix; break; case ODataRequestMethod.Get: actionNamePrefix = GetRefActionNamePrefix; break; default: actionNamePrefix = CreateRefActionNamePrefix; break; } // Examples: CreateRefToOrdersFromCustomer, CreateRefToOrders, CreateRef. return(actionMap.FindMatchingAction( actionNamePrefix + "To" + navigationProperty.Name + "From" + declaringType.Name, actionNamePrefix + "To" + navigationProperty.Name, actionNamePrefix)); }
/// <summary> /// Selects the action for OData requests. /// </summary> /// <param name="odataPath">The OData path.</param> /// <param name="controllerContext">The controller context.</param> /// <param name="actionMap">The action map.</param> /// <returns> /// <c>null</c> if the request isn't handled by this convention; otherwise, the name of the selected action /// </returns> internal static string SelectActionImpl(ODataPath odataPath, IWebApiControllerContext controllerContext, IWebApiActionMap actionMap) { ODataRequestMethod method = controllerContext.Request.GetRequestMethodOrPreflightMethod(); if (method != ODataRequestMethod.Get) { // [EnableNestedPaths] only supports GET requests return(null); } // unsupported path segments if (odataPath.PathTemplate.EndsWith("$ref")) { return(null); } ODataPathSegment firstSegment = odataPath.Segments.FirstOrDefault(); string sourceName; if (firstSegment is EntitySetSegment entitySetSegment) { sourceName = entitySetSegment.EntitySet.Name; } else if (firstSegment is SingletonSegment singletonSegment) { sourceName = singletonSegment.Singleton.Name; } else { // this only supports paths starting with an entity set or singleton return(null); } // if we did not find a matching action amongst the conventional user-defined methods // then let's check if the controller has a Get method with [EnableNestedPaths] attribute // which should be used to catch any nested GET request string action = actionMap.FindMatchingAction("Get" + sourceName, "Get"); if (action == null) { return(null); } IWebApiActionDescriptor descriptor = actionMap.GetActionDescriptor(action); if (descriptor == null) { return(null); } if (!descriptor.GetCustomAttributes <EnableNestedPathsAttribute>(/* inherit */ true).Any()) { return(null); } return(descriptor.ActionName); }
/// <inheritdoc/> internal static string SelectActionImpl(ODataPath odataPath, IWebApiControllerContext controllerContext, IWebApiActionMap actionMap) { if (odataPath.PathTemplate == "~/entityset/key" || odataPath.PathTemplate == "~/entityset/key/cast" || odataPath.PathTemplate == "~/entityset/cast/key") { string httpMethodName; switch (controllerContext.Request.GetRequestMethodOrPreflightMethod()) { case ODataRequestMethod.Get: httpMethodName = "Get"; break; case ODataRequestMethod.Put: httpMethodName = "Put"; break; case ODataRequestMethod.Patch: case ODataRequestMethod.Merge: httpMethodName = "Patch"; break; case ODataRequestMethod.Delete: httpMethodName = "Delete"; break; default: return(null); } Contract.Assert(httpMethodName != null); IEdmEntityType entityType = (IEdmEntityType)odataPath.EdmType; // e.g. Try GetCustomer first, then fallback on Get action name string actionName = actionMap.FindMatchingAction( httpMethodName + entityType.Name, httpMethodName); if (actionName != null) { KeySegment keySegment = (KeySegment)odataPath.Segments.First(d => d is KeySegment); controllerContext.AddKeyValueToRouteData(keySegment); return(actionName); } } return(null); }
private static string SelectAction(OperationImportSegment operationImportSegment, IWebApiActionMap actionMap) { if (operationImportSegment == null) { return(null); } IEdmOperationImport operationImport = operationImportSegment.OperationImports.FirstOrDefault(); if (operationImport == null) { return(null); } return(actionMap.FindMatchingAction(operationImport.Name, "Invoke" + operationImport.Name)); }
public static string SelectAction(this IEdmOperation operation, IWebApiActionMap actionMap, bool isCollection) { Contract.Assert(actionMap != null); if (operation == null) { return(null); } // The binding parameter is the first parameter by convention IEdmOperationParameter bindingParameter = operation.Parameters.FirstOrDefault(); if (operation.IsBound && bindingParameter != null) { IEdmEntityType entityType = null; if (!isCollection) { entityType = bindingParameter.Type.Definition as IEdmEntityType; } else { IEdmCollectionType bindingParameterType = bindingParameter.Type.Definition as IEdmCollectionType; if (bindingParameterType != null) { entityType = bindingParameterType.ElementType.Definition as IEdmEntityType; } } if (entityType == null) { return(null); } string targetActionName = isCollection ? operation.Name + "OnCollectionOf" + entityType.Name : operation.Name + "On" + entityType.Name; return(actionMap.FindMatchingAction(targetActionName, operation.Name)); } return(null); }
/// <inheritdoc/> internal static string SelectActionImpl(ODataPath odataPath, IWebApiControllerContext controllerContext, IWebApiActionMap actionMap) { ODataRequestMethod method = controllerContext.Request.GetRequestMethodOrPreflightMethod(); string actionNamePrefix = GetActionMethodPrefix(method); if (actionNamePrefix == null) { return(null); } if (odataPath.PathTemplate == "~/entityset/key/navigation" || odataPath.PathTemplate == "~/entityset/key/navigation/$count" || odataPath.PathTemplate == "~/entityset/key/cast/navigation" || odataPath.PathTemplate == "~/entityset/key/cast/navigation/$count" || odataPath.PathTemplate == "~/singleton/navigation" || odataPath.PathTemplate == "~/singleton/navigation/$count" || odataPath.PathTemplate == "~/singleton/cast/navigation" || odataPath.PathTemplate == "~/singleton/cast/navigation/$count") { NavigationPropertySegment navigationSegment = (odataPath.Segments.Last() as NavigationPropertySegment) ?? odataPath.Segments[odataPath.Segments.Count - 2] as NavigationPropertySegment; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; // It is not valid to *Post* to any non-collection valued navigation property. if (navigationProperty.TargetMultiplicity() != EdmMultiplicity.Many && ODataRequestMethod.Post == method) { return(null); } // It is not valid to *Put/Patch" to any collection-valued navigation property. if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many && (ODataRequestMethod.Put == method || ODataRequestMethod.Patch == method)) { return(null); } // *Get* is the only supported method for $count request. if (odataPath.Segments.Last() is CountSegment && ODataRequestMethod.Get != method) { return(null); } if (declaringType != null) { // e.g. Try GetNavigationPropertyFromDeclaringType first, then fallback on GetNavigationProperty action name string actionName = actionMap.FindMatchingAction( actionNamePrefix + navigationProperty.Name + "From" + declaringType.Name, actionNamePrefix + navigationProperty.Name); if (actionName != null) { if (odataPath.PathTemplate.StartsWith("~/entityset/key", StringComparison.Ordinal)) { KeySegment keyValueSegment = (KeySegment)odataPath.Segments[1]; controllerContext.AddKeyValueToRouteData(keyValueSegment); } return(actionName); } } } return(null); }
internal static string SelectActionImpl(ODataPath odataPath, IWebApiControllerContext controllerContext, IWebApiActionMap actionMap) { string actionName = null; DynamicPathSegment dynamicPropertSegment = null; switch (odataPath.PathTemplate) { case "~/entityset/key/dynamicproperty": case "~/entityset/key/cast/dynamicproperty": case "~/singleton/dynamicproperty": case "~/singleton/cast/dynamicproperty": dynamicPropertSegment = odataPath.Segments.Last() as DynamicPathSegment; if (dynamicPropertSegment == null) { return(null); } if (ODataRequestMethod.Get == controllerContext.Request.Method) { string actionNamePrefix = String.Format(CultureInfo.InvariantCulture, "Get{0}", ActionName); actionName = actionMap.FindMatchingAction(actionNamePrefix); } break; case "~/entityset/key/property/dynamicproperty": case "~/entityset/key/cast/property/dynamicproperty": case "~/singleton/property/dynamicproperty": case "~/singleton/cast/property/dynamicproperty": dynamicPropertSegment = odataPath.Segments.Last() as DynamicPathSegment; if (dynamicPropertSegment == null) { return(null); } PropertySegment propertyAccessSegment = odataPath.Segments[odataPath.Segments.Count - 2] as PropertySegment; if (propertyAccessSegment == null) { return(null); } EdmComplexType complexType = propertyAccessSegment.Property.Type.Definition as EdmComplexType; if (complexType == null) { return(null); } if (ODataRequestMethod.Get == controllerContext.Request.Method) { string actionNamePrefix = String.Format(CultureInfo.InvariantCulture, "Get{0}", ActionName); actionName = actionMap.FindMatchingAction(actionNamePrefix + "From" + propertyAccessSegment.Property.Name); } break; default: break; } if (actionName != null) { if (odataPath.PathTemplate.StartsWith("~/entityset/key", StringComparison.Ordinal)) { KeySegment keyValueSegment = (KeySegment)odataPath.Segments[1]; controllerContext.AddKeyValueToRouteData(keyValueSegment); } controllerContext.RouteData.Add(ODataRouteConstants.DynamicProperty, dynamicPropertSegment.Identifier); var key = ODataParameterValue.ParameterValuePrefix + ODataRouteConstants.DynamicProperty; var value = new ODataParameterValue(dynamicPropertSegment.Identifier, EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(typeof(string))); controllerContext.RouteData.Add(key, value); controllerContext.Request.Context.RoutingConventionsStore.Add(key, value); return(actionName); } return(null); }
/// <summary> /// Selects the action for OData requests. /// </summary> /// <param name="odataPath">The OData path.</param> /// <param name="controllerContext">The controller context.</param> /// <param name="actionMap">The action map.</param> /// <returns> /// <c>null</c> if the request isn't handled by this convention; otherwise, the name of the selected action /// </returns> internal static string SelectActionImpl(ODataPath odataPath, IWebApiControllerContext controllerContext, IWebApiActionMap actionMap) { if (odataPath.PathTemplate == "~/entityset") { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; if (ODataRequestMethod.Get == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { // e.g. Try GetCustomers first, then fall back to Get action name return(actionMap.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (ODataRequestMethod.Post == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { // e.g. Try PostCustomer first, then fall back to Post action name return(actionMap.FindMatchingAction( "Post" + entitySet.EntityType().Name, "Post")); } } else if (odataPath.PathTemplate == "~/entityset/$count" && ODataRequestMethod.Get == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; // e.g. Try GetCustomers first, then fall back to Get action name return(actionMap.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (odataPath.PathTemplate == "~/entityset/cast") { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; IEdmCollectionType collectionType = (IEdmCollectionType)odataPath.EdmType; IEdmEntityType entityType = (IEdmEntityType)collectionType.ElementType.Definition; if (ODataRequestMethod.Get == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer return(actionMap.FindMatchingAction( "Get" + entitySet.Name + "From" + entityType.Name, "GetFrom" + entityType.Name)); } else if (ODataRequestMethod.Post == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { // e.g. Try PostCustomerFromSpecialCustomer first, then fall back to PostFromSpecialCustomer return(actionMap.FindMatchingAction( "Post" + entitySet.EntityType().Name + "From" + entityType.Name, "PostFrom" + entityType.Name)); } } else if (odataPath.PathTemplate == "~/entityset/cast/$count" && ODataRequestMethod.Get == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; IEdmCollectionType collectionType = (IEdmCollectionType)odataPath.Segments[1].EdmType; IEdmEntityType entityType = (IEdmEntityType)collectionType.ElementType.Definition; // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer return(actionMap.FindMatchingAction( "Get" + entitySet.Name + "From" + entityType.Name, "GetFrom" + entityType.Name)); } return(null); }