public void HasParameter_Returns_BooleanAsExpected() { // Arrange ActionModel action = _methodInfo.BuildActionModel(); // Act & Assert Assert.False(action.HasParameter <int>("key")); Assert.True(action.HasParameter <int>("id")); Assert.False(action.HasParameter <string>("id")); }
public void HasParameter_ThrowsArgumentNull_Action() { // Arrange & Act & Assert ActionModel action = null; ExceptionAssert.ThrowsArgumentNull(() => action.HasParameter <int>("key"), "action"); }
internal static bool ProcessNonNavigationProperty(string httpMethod, ODataControllerActionContext context, ActionModel action, IEdmNavigationSource navigationSource, IEdmEntityType entityType, IEdmStructuredType castType) { // Action parameter should have a (string navigationProperty) parameter if (!action.HasParameter <string>("navigationProperty")) { return(false); } // Let's only handle single-key convention, for composite key, use attribute routing or non-generic navigation. bool hasRelatedKey = action.Parameters.Any(p => p.Name == "relatedKey"); // case sensitive? bool hasRelatedId = action.Parameters.Any(p => p.Name == "relatedId"); IList <ODataSegmentTemplate> segments = new List <ODataSegmentTemplate>(); if (context.EntitySet != null) { segments.Add(new EntitySetSegmentTemplate(context.EntitySet)); segments.Add(KeySegmentTemplate.CreateKeySegment(entityType, context.EntitySet)); } else { segments.Add(new SingletonSegmentTemplate(context.Singleton)); } if (entityType != castType) { segments.Add(new CastSegmentTemplate(castType, entityType, navigationSource)); } if (hasRelatedKey) { segments.Add(new NavigationLinkTemplateSegmentTemplate(entityType, navigationSource) { RelatedKey = "relatedKey" }); } else if (hasRelatedId) { segments.Add(new NavigationLinkTemplateSegmentTemplate(entityType, navigationSource) { RelatedKey = "relatedId" }); } else { segments.Add(new NavigationLinkTemplateSegmentTemplate(entityType, navigationSource)); } ODataPathTemplate template = new ODataPathTemplate(segments); action.AddSelector(httpMethod, context.Prefix, context.Model, template, context.Options?.RouteOptions); return(true); }
/// <inheritdoc /> public bool AppliesToAction(ODataControllerActionContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } Debug.Assert(context.Action != null); ActionModel action = context.Action; string actionMethodName = action.ActionMethod.Name; // Need to refactor the following // for example: CreateRef( with the navigation property parameter) should for all navigation properties // CreateRefToOrdersFromCustomer, CreateRefToOrders, CreateRef. string method = SplitRefActionName(actionMethodName, out string httpMethod, out string property, out string declaring); if (method == null) { return(false); } // Action parameter should have a (string navigationProperty) parameter if (!action.HasParameter <string>("navigationProperty")) { return(false); } IEdmNavigationSource navigationSource; IEdmEntityType entityType; if (context.EntitySet != null) { entityType = context.EntitySet.EntityType(); navigationSource = context.EntitySet; } else { entityType = context.Singleton.EntityType(); navigationSource = context.Singleton; } // For entity set, we should have the key parameter // For Singleton, we should not have the key parameter bool hasODataKeyParameter = action.HasODataKeyParameter(entityType); if ((context.EntitySet != null && !hasODataKeyParameter) || (context.Singleton != null && hasODataKeyParameter)) { return(false); } // Find the navigation property declaring type IEdmStructuredType declaringType = entityType; if (declaring != null) { declaringType = entityType.FindTypeInInheritance(context.Model, declaring); if (declaringType == null) { return(false); } } // Find the navigation property if have IEdmNavigationProperty navigationProperty = null; if (property != null) { navigationProperty = declaringType.DeclaredNavigationProperties().FirstOrDefault(p => p.Name == property); if (navigationProperty == null) { return(false); } } IList <ODataSegmentTemplate> segments = new List <ODataSegmentTemplate>(); if (context.EntitySet != null) { segments.Add(new EntitySetSegmentTemplate(context.EntitySet)); segments.Add(new KeySegmentTemplate(entityType)); } else { segments.Add(new SingletonSegmentTemplate(context.Singleton)); } if (entityType != declaringType) { segments.Add(new CastSegmentTemplate(declaringType, entityType, navigationSource)); } if (navigationProperty != null) { segments.Add(new NavigationSegmentTemplate(navigationProperty)); } else { //TODO: Add the navigation template segment template, // Or add the template for all navigation properties? return(false); } IEdmEntityType navigationPropertyType = navigationProperty.Type.GetElementTypeOrSelf().AsEntity().EntityDefinition(); bool hasNavigationPropertyKeyParameter = action.HasODataKeyParameter(navigationPropertyType, "relatedKey"); if (hasNavigationPropertyKeyParameter) { segments.Add(new KeySegmentTemplate(navigationPropertyType, "relatedKey")); } IEdmNavigationSource targetNavigationSource = navigationSource.FindNavigationTarget(navigationProperty, segments, out _); segments.Add(new RefSegmentTemplate(navigationProperty, targetNavigationSource)); // TODO: support key as segment? ODataPathTemplate template = new ODataPathTemplate(segments); action.AddSelector(httpMethod, context.Prefix, context.Model, template); // processed return(true); }