/// <summary> /// Selects the controller for OData requests. /// </summary> /// <param name="odataPath">The OData path.</param> /// <param name="request">The request.</param> /// <returns> /// <c>null</c> if the request isn't handled by this convention; otherwise, the name of the selected controller /// </returns> public virtual string SelectController(ODataPath odataPath, HttpRequestMessage request) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (request == null) { throw Error.ArgumentNull("request"); } // entity set EntitySetPathSegment entitySetSegment = odataPath.Segments.FirstOrDefault() as EntitySetPathSegment; if (entitySetSegment != null) { return(entitySetSegment.EntitySetName); } // singleton SingletonPathSegment singletonSegment = odataPath.Segments.FirstOrDefault() as SingletonPathSegment; if (singletonSegment != null) { return(singletonSegment.SingletonName); } return(null); }
public static HttpResponseMessage PostResponse <TEntity, TKey>(ApiController controller, TEntity createdEntity, TKey entityKey) { HttpResponseMessage response = null; HttpRequestMessage request = controller.Request; if (RequestPrefersReturnNoContent(request)) { response = request.CreateResponse(HttpStatusCode.NoContent); response.Headers.Add(PreferenceAppliedHeaderName, ReturnNoContentHeaderValue); } else { response = request.CreateResponse(HttpStatusCode.Created, createdEntity); } ODataPath odataPath = request.ODataProperties().Path; if (odataPath == null) { throw Error.InvalidOperation(SRResources.LocationHeaderMissingODataPath); } EntitySetPathSegment entitySetSegment = odataPath.Segments.FirstOrDefault() as EntitySetPathSegment; if (entitySetSegment == null) { throw Error.InvalidOperation(SRResources.LocationHeaderDoesNotStartWithEntitySet); } UrlHelper urlHelper = controller.Url ?? new UrlHelper(request); response.Headers.Location = new Uri(urlHelper.CreateODataLink(entitySetSegment, new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(entityKey, ODataVersion.V3)))); return(response); }
public static ODataQueryOptions <T> BuildIt <T>(IEdmModel iedmModel, HttpRequestMessage message) { EntitySetPathSegment segment = new EntitySetPathSegment(typeof(T).Name); ODataPath path = new ODataPath(new ODataPathSegment[] { segment }); ODataQueryContext oDataQueryContext = new ODataQueryContext(iedmModel, typeof(T), path); ODataQueryOptions <T> opts = new ODataQueryOptions <T>(oDataQueryContext, message); return(opts); }
/// <inheritdoc/> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } string prefix; ComplexCastPathSegment 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 { // for example: GetCityOfSubAddressFromVipCustomer or GetCityOfSubAddress actionName = actionMap.FindMatchingAction( prefix + property.Name + "Of" + cast.CastType.Name + "From" + declaringType.Name, prefix + property.Name + "Of" + cast.CastType.Name); } if (actionName != null) { if (odataPath.PathTemplate.StartsWith("~/entityset/key", StringComparison.Ordinal)) { EntitySetPathSegment entitySetPathSegment = (EntitySetPathSegment)odataPath.Segments.First(); IEdmEntityType edmEntityType = entitySetPathSegment.EntitySetBase.EntityType(); KeyValuePathSegment keyValueSegment = (KeyValuePathSegment)odataPath.Segments[1]; controllerContext.AddKeyValueToRouteData(keyValueSegment, edmEntityType, ODataRouteConstants.Key); } return(actionName); } } return(null); }
/// <inheritdoc/> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } if (controllerContext.Request.Method == HttpMethod.Post) { switch (odataPath.PathTemplate) { case "~/entityset/key/cast/action": case "~/entityset/key/action": string actionName = GetAction(odataPath).SelectAction(actionMap, isCollection: false); if (actionName != null) { EntitySetPathSegment entitySetPathSegment = (EntitySetPathSegment)odataPath.Segments.First(); IEdmEntityType edmEntityType = entitySetPathSegment.EntitySetBase.EntityType(); KeyValuePathSegment keyValueSegment = (KeyValuePathSegment)odataPath.Segments[1]; controllerContext.AddKeyValueToRouteData(keyValueSegment, edmEntityType, ODataRouteConstants.Key); } return(actionName); case "~/entityset/cast/action": case "~/entityset/action": return(GetAction(odataPath).SelectAction(actionMap, isCollection: true)); case "~/singleton/action": case "~/singleton/cast/action": return(GetAction(odataPath).SelectAction(actionMap, isCollection: false)); } } return(null); }
/// <summary> /// Selects the controller for OData requests. /// </summary> /// <param name="odataPath">The OData path.</param> /// <param name="request">The request.</param> /// <returns> /// <c>null</c> if the request isn't handled by this convention; otherwise, the name of the selected controller /// </returns> public string SelectController(ODataPath odataPath, HttpRequestMessage request) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (request == null) { throw Error.ArgumentNull("request"); } if (odataPath.PathTemplate.StartsWith("~/entityset", StringComparison.Ordinal)) { EntitySetPathSegment entitySetSegment = odataPath.Segments[0] as EntitySetPathSegment; return(entitySetSegment.EntitySet.Name); } return(null); }
/// <summary> /// Selects the controller for OData requests. /// </summary> /// <param name="odataPath">The OData path.</param> /// <param name="request">The request.</param> /// <returns> /// <c>null</c> if the request isn't handled by this convention; otherwise, the name of the selected controller /// </returns> public string SelectController(ODataPath odataPath, HttpRequestMessage request) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (request == null) { throw Error.ArgumentNull("request"); } EntitySetPathSegment entitySetSegment = odataPath.Segments.FirstOrDefault() as EntitySetPathSegment; if (entitySetSegment != null) { return(entitySetSegment.EntitySet.Name); } 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> public virtual string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } if (odataPath.PathTemplate == "~/entityset") { EntitySetPathSegment entitySetSegment = odataPath.Segments[0] as EntitySetPathSegment; IEdmEntitySet entitySet = entitySetSegment.EntitySet; HttpMethod httpMethod = controllerContext.Request.Method; if (httpMethod == HttpMethod.Get) { // e.g. Try GetCustomers first, then fallback on Get action name return(actionMap.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (httpMethod == HttpMethod.Post) { // e.g. Try PostCustomer first, then fallback on Post action name return(actionMap.FindMatchingAction( "Post" + entitySet.ElementType.Name, "Post")); } } return(null); }
public static void HasNavigationPropertyLink <TEntity, TValue>( this EntitySetConfiguration <TEntity> entitySet, NavigationPropertyConfiguration navigationProperty, Expression <Func <TEntity, TValue> > foreignKeyProperty, string targetEntitySetName) where TEntity : class { Arg.NotNull(entitySet, nameof(entitySet)); Arg.NotNull(navigationProperty, nameof(navigationProperty)); Arg.NotNull(foreignKeyProperty, nameof(foreignKeyProperty)); Arg.NotNullOrEmpty(targetEntitySetName, nameof(targetEntitySetName)); var foreignKeyPropertyName = foreignKeyProperty.GetPropertyName(); entitySet.HasNavigationPropertyLink( navigationProperty, (context, property) => { var entity = context.EdmObject; object value; if (!entity.TryGetPropertyValue(foreignKeyPropertyName, out value)) { return(null); } if (value == null) { return(null); } var entitySetPath = new EntitySetPathSegment(targetEntitySetName); var keyValuePath = new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V4)); var url = new Uri(context.Url.CreateODataLink(entitySetPath, keyValuePath)); return(url); }, false); }
/// <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> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } if (odataPath.PathTemplate == "~/entityset") { EntitySetPathSegment entitySetSegment = (EntitySetPathSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySetBase; HttpMethod httpMethod = controllerContext.Request.Method; if (httpMethod == HttpMethod.Get) { // e.g. Try GetCustomers first, then fall back to Get action name return(actionMap.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (httpMethod == HttpMethod.Post) { // 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/cast") { EntitySetPathSegment entitySetSegment = (EntitySetPathSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySetBase; IEdmCollectionType collectionType = (IEdmCollectionType)odataPath.EdmType; IEdmEntityType entityType = (IEdmEntityType)collectionType.ElementType.Definition; HttpMethod httpMethod = controllerContext.Request.Method; if (httpMethod == HttpMethod.Get) { // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer return(actionMap.FindMatchingAction( "Get" + entitySet.Name + "From" + entityType.Name, "GetFrom" + entityType.Name)); } else if (httpMethod == HttpMethod.Post) { // e.g. Try PostCustomerFromSpecialCustomer first, then fall back to PostFromSpecialCustomer return(actionMap.FindMatchingAction( "Post" + entitySet.EntityType().Name + "From" + entityType.Name, "PostFrom" + entityType.Name)); } } return(null); }
/// <inheritdoc/> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } if (controllerContext.Request.Method == HttpMethod.Get) { string actionName = null; BoundFunctionPathSegment function = null; switch (odataPath.PathTemplate) { case "~/entityset/key/cast/function": case "~/entityset/key/function": function = odataPath.Segments.Last() as BoundFunctionPathSegment; actionName = GetFunction(function).SelectAction(actionMap, isCollection: false); if (actionName != null) { EntitySetPathSegment entitySetPathSegment = (EntitySetPathSegment)odataPath.Segments.First(); IEdmEntityType edmEntityType = entitySetPathSegment.EntitySetBase.EntityType(); KeyValuePathSegment keyValueSegment = (KeyValuePathSegment)odataPath.Segments[1]; controllerContext.AddKeyValueToRouteData(keyValueSegment, edmEntityType, ODataRouteConstants.Key); } break; case "~/entityset/key/cast/function/$count": case "~/entityset/key/function/$count": function = odataPath.Segments[odataPath.Segments.Count - 2] as BoundFunctionPathSegment; actionName = GetFunction(function).SelectAction(actionMap, isCollection: false); if (actionName != null) { EntitySetPathSegment entitySetPathSegment = (EntitySetPathSegment)odataPath.Segments.First(); IEdmEntityType edmEntityType = entitySetPathSegment.EntitySetBase.EntityType(); KeyValuePathSegment keyValueSegment = (KeyValuePathSegment)odataPath.Segments[1]; controllerContext.AddKeyValueToRouteData(keyValueSegment, edmEntityType, ODataRouteConstants.Key); } break; case "~/entityset/cast/function": case "~/entityset/function": function = odataPath.Segments.Last() as BoundFunctionPathSegment; actionName = GetFunction(function).SelectAction(actionMap, isCollection: true); break; case "~/entityset/cast/function/$count": case "~/entityset/function/$count": function = odataPath.Segments[odataPath.Segments.Count - 2] as BoundFunctionPathSegment; actionName = GetFunction(function).SelectAction(actionMap, isCollection: true); break; case "~/singleton/function": case "~/singleton/cast/function": function = odataPath.Segments.Last() as BoundFunctionPathSegment; actionName = GetFunction(function).SelectAction(actionMap, isCollection: false); break; case "~/singleton/function/$count": case "~/singleton/cast/function/$count": function = odataPath.Segments[odataPath.Segments.Count - 2] as BoundFunctionPathSegment; actionName = GetFunction(function).SelectAction(actionMap, isCollection: false); break; } if (actionName != null) { controllerContext.AddFunctionParameterToRouteData(function); return(actionName); } } return(null); }
/// <inheritdoc/> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } HttpMethod method = controllerContext.Request.Method; 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") { NavigationPathSegment navigationSegment = (odataPath.Segments.Last() as NavigationPathSegment) ?? odataPath.Segments[odataPath.Segments.Count - 2] as NavigationPathSegment; 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 && method == HttpMethod.Post) { return(null); } // It is not valid to *Put/Patch" to any collection-valued navigation property. if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many && (method == HttpMethod.Put || "PATCH" == method.Method.ToUpperInvariant())) { return(null); } // *Get* is the only supported method for $count request. if (odataPath.Segments.Last() is CountPathSegment && method != HttpMethod.Get) { 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)) { EntitySetPathSegment entitySetPathSegment = (EntitySetPathSegment)odataPath.Segments.First(); IEdmEntityType edmEntityType = entitySetPathSegment.EntitySetBase.EntityType(); KeyValuePathSegment keyValueSegment = (KeyValuePathSegment)odataPath.Segments[1]; controllerContext.AddKeyValueToRouteData(keyValueSegment, edmEntityType, ODataRouteConstants.Key); } return(actionName); } } } return(null); }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } string actionName = null; DynamicPropertyPathSegment dynamicPropertSegment = null; switch (odataPath.PathTemplate) { case "~/entityset/key/dynamicproperty": case "~/entityset/key/cast/dynamicproperty": case "~/singleton/dynamicproperty": case "~/singleton/cast/dynamicproperty": dynamicPropertSegment = odataPath.Segments[odataPath.Segments.Count - 1] as DynamicPropertyPathSegment; if (dynamicPropertSegment == null) { return(null); } if (controllerContext.Request.Method == HttpMethod.Get) { 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[odataPath.Segments.Count - 1] as DynamicPropertyPathSegment; if (dynamicPropertSegment == null) { return(null); } PropertyAccessPathSegment propertyAccessSegment = odataPath.Segments[odataPath.Segments.Count - 2] as PropertyAccessPathSegment; if (propertyAccessSegment == null) { return(null); } EdmComplexType complexType = propertyAccessSegment.Property.Type.Definition as EdmComplexType; if (complexType == null) { return(null); } if (controllerContext.Request.Method == HttpMethod.Get) { 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)) { EntitySetPathSegment entitySetPathSegment = (EntitySetPathSegment)odataPath.Segments.First(); IEdmEntityType edmEntityType = entitySetPathSegment.EntitySetBase.EntityType(); KeyValuePathSegment keyValueSegment = (KeyValuePathSegment)odataPath.Segments[1]; controllerContext.AddKeyValueToRouteData(keyValueSegment, edmEntityType, ODataRouteConstants.Key); } controllerContext.RouteData.Values[ODataRouteConstants.DynamicProperty] = dynamicPropertSegment.PropertyName; var key = ODataParameterValue.ParameterValuePrefix + ODataRouteConstants.DynamicProperty; var value = new ODataParameterValue(dynamicPropertSegment.PropertyName, EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(typeof(string))); controllerContext.Request.ODataProperties().RoutingConventionsStore[key] = value; return(actionName); } return(null); }
/// <inheritdoc/> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } HttpMethod requestMethod = controllerContext.Request.Method; IHttpRouteData routeData = controllerContext.RouteData; if (!IsSupportedRequestMethod(requestMethod)) { return(null); } if (odataPath.PathTemplate == "~/entityset/key/navigation/$ref" || odataPath.PathTemplate == "~/entityset/key/cast/navigation/$ref" || odataPath.PathTemplate == "~/singleton/navigation/$ref" || odataPath.PathTemplate == "~/singleton/cast/navigation/$ref") { NavigationPathSegment navigationSegment = (NavigationPathSegment)odataPath.Segments[odataPath.Segments.Count - 2]; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringEntityType(); string refActionName = FindRefActionName(actionMap, navigationProperty, declaringType, requestMethod); if (refActionName != null) { if (odataPath.PathTemplate.StartsWith("~/entityset/key", StringComparison.Ordinal)) { EntitySetPathSegment entitySetPathSegment = (EntitySetPathSegment)odataPath.Segments.First(); IEdmEntityType edmEntityType = entitySetPathSegment.EntitySetBase.EntityType(); KeyValuePathSegment keyValueSegment = (KeyValuePathSegment)odataPath.Segments[1]; controllerContext.AddKeyValueToRouteData(keyValueSegment, edmEntityType, ODataRouteConstants.Key); } routeData.Values[ODataRouteConstants.NavigationProperty] = navigationSegment.NavigationProperty.Name; return(refActionName); } } else if ((requestMethod == HttpMethod.Delete) && ( odataPath.PathTemplate == "~/entityset/key/navigation/key/$ref" || odataPath.PathTemplate == "~/entityset/key/cast/navigation/key/$ref" || odataPath.PathTemplate == "~/singleton/navigation/key/$ref" || odataPath.PathTemplate == "~/singleton/cast/navigation/key/$ref")) { NavigationPathSegment navigationSegment = (NavigationPathSegment)odataPath.Segments[odataPath.Segments.Count - 3]; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringEntityType(); string refActionName = FindRefActionName(actionMap, navigationProperty, declaringType, requestMethod); if (refActionName != null) { if (odataPath.PathTemplate.StartsWith("~/entityset/key", StringComparison.Ordinal)) { EntitySetPathSegment entitySetPathSegment = (EntitySetPathSegment)odataPath.Segments.First(); IEdmEntityType edmEntityType = entitySetPathSegment.EntitySetBase.EntityType(); KeyValuePathSegment keyValueSegment = (KeyValuePathSegment)odataPath.Segments[1]; controllerContext.AddKeyValueToRouteData(keyValueSegment, edmEntityType, ODataRouteConstants.Key); } routeData.Values[ODataRouteConstants.NavigationProperty] = navigationSegment.NavigationProperty.Name; KeyValuePathSegment relatedKeySegment = odataPath.Segments.Last(e => e is KeyValuePathSegment) as KeyValuePathSegment; IEdmEntityType navEntityType = navigationProperty.Type.AsCollection().ElementType().AsEntity().EntityDefinition(); controllerContext.AddKeyValueToRouteData(relatedKeySegment, navEntityType, ODataRouteConstants.RelatedKey); return(refActionName); } } return(null); }